diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..267a6aa
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,222 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Android-specific code.                        ==
+   =========================================================================
+
+Android Code
+Copyright 2005-2008 The Android Open Source Project
+
+This product includes software developed as part of
+The Android Open Source Project (http://source.android.com).
+
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for Apache Commons code.                              ==
+   =========================================================================
+
+Apache Commons
+Copyright 1999-2004 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for Jakarta Commons Logging.                          ==
+   =========================================================================
+
+Jakarta Commons Logging (JCL)
+Copyright 2005,2006 The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Nuance code.                                  ==
+   =========================================================================
+
+These files are Copyright 2007 Nuance Communications, but released under
+the Apache2 License.
+
+                               Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/awt/Android.mk b/awt/Android.mk
new file mode 100644
index 0000000..c7480f5
--- /dev/null
+++ b/awt/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_JAVA_LIBRARIES := core framework
+
+LOCAL_MODULE:= android.awt
+
+LOCAL_DX_FLAGS := --core-library
+
+include $(BUILD_JAVA_LIBRARY)
diff --git a/awt/com/android/internal/awt/AndroidGraphics2D.java b/awt/com/android/internal/awt/AndroidGraphics2D.java
new file mode 100644
index 0000000..9a8ae02
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidGraphics2D.java
@@ -0,0 +1,1354 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.awt;
+
+import com.android.internal.awt.AndroidGraphicsConfiguration;
+import com.android.internal.graphics.NativeUtils;
+
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.PathIterator;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.font.AndroidGlyphVector;
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.gl.image.OffscreenImage;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.graphics.Typeface;
+import android.graphics.PixelXorXfermode;
+import android.view.Display;
+import android.view.WindowManager;
+import android.content.Context;
+
+public class AndroidGraphics2D extends Graphics2D {
+    
+    private int displayWidth, displayHeight;
+
+    protected Surface dstSurf = null;
+    protected MultiRectArea clip = null;
+
+    protected Composite composite = AlphaComposite.SrcOver;
+    protected AffineTransform transform = new AffineTransform();
+
+    private static AndroidGraphics2D mAg;
+    private static Canvas mC;
+
+    // Android Paint
+    public static Paint mP;
+
+    private static java.awt.Font mFnt;
+
+    // Cached Matrix
+    public static Matrix mM;
+    private static FontMetrics mFm;
+    private static RenderingHints mRh;
+    private static Color mBc;
+
+    private Area mCurrClip;
+    
+    public final static double RAD_360 = Math.PI / 180 * 360;
+    
+    // Image drawing
+    private AndroidJavaBlitter blitter;
+    private DirectColorModel cm;
+    private SinglePixelPackedSampleModel sm;
+    private WritableRaster wr;
+
+
+    public static AndroidGraphics2D getInstance() {
+        if (mAg == null) {
+            throw new RuntimeException("AndroidGraphics2D not instantiated!");
+        }
+        return mAg;
+    }
+
+    public static AndroidGraphics2D getInstance(Context ctx, Canvas c, Paint p) {
+        if (c == null || ctx == null) {
+            throw new RuntimeException(
+                    "Illegal argument, Canvas cannot be null!");
+        }
+        mAg = new AndroidGraphics2D(ctx, c, p);
+        return mAg;
+    }
+
+    private AndroidGraphics2D(Context ctx, Canvas c, Paint p) {
+        super();
+        mC = c;
+        mP = p;
+        mM = new Matrix();
+        mM.reset();
+        mM = mC.getMatrix();
+        Rect r = mC.getClipBounds();
+        int cl[] = {-1, r.top, r.left, -2, r.top, r.right, -2, r.bottom, r.right, -2, r.bottom, r.left};
+        mCurrClip = new Area(createShape(cl));
+        if(ctx != null) {
+            WindowManager wm = (WindowManager)ctx.getSystemService(Context.WINDOW_SERVICE);
+            Display d = wm.getDefaultDisplay();
+            displayWidth = d.getWidth();
+            displayHeight = d.getHeight();
+        }
+        blitter = new AndroidJavaBlitter(c);
+        cm = new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
+        sm = new SinglePixelPackedSampleModel(
+                DataBuffer.TYPE_INT, displayWidth, displayHeight, cm.getMasks());
+        wr = Raster.createWritableRaster(sm, null);
+        dstSurf = new ImageSurface(cm, wr);       
+    }
+
+    @Override
+    public void addRenderingHints(Map<?, ?> hints) {
+        if (mRh == null) {
+            mRh = (RenderingHints) hints;
+        }
+        mRh.add((RenderingHints) hints);
+    }
+
+    public float[] getMatrix() {
+        float[] f = new float[9];
+        mC.getMatrix().getValues(f);
+        return f;
+    }
+
+    /**
+     * 
+     * @return a Matrix in Android format
+     */
+    public float[] getInverseMatrix() {
+        AffineTransform af = new AffineTransform(createAWTMatrix(getMatrix()));
+        try {
+            af = af.createInverse();
+        } catch (NoninvertibleTransformException e) {
+        }
+        return createMatrix(af);
+    }
+
+    private Path getPath(Shape s) {
+        Path path = new Path();
+        PathIterator pi = s.getPathIterator(null);
+        while (pi.isDone() == false) {
+            getCurrentSegment(pi, path);
+            pi.next();
+        }
+        return path;
+    }
+
+    private void getCurrentSegment(PathIterator pi, Path path) {
+        float[] coordinates = new float[6];
+        int type = pi.currentSegment(coordinates);
+        switch (type) {
+        case PathIterator.SEG_MOVETO:
+            path.moveTo(coordinates[0], coordinates[1]);
+            break;
+        case PathIterator.SEG_LINETO:
+            path.lineTo(coordinates[0], coordinates[1]);
+            break;
+        case PathIterator.SEG_QUADTO:
+            path.quadTo(coordinates[0], coordinates[1], coordinates[2],
+                    coordinates[3]);
+            break;
+        case PathIterator.SEG_CUBICTO:
+            path.cubicTo(coordinates[0], coordinates[1], coordinates[2],
+                    coordinates[3], coordinates[4], coordinates[5]);
+            break;
+        case PathIterator.SEG_CLOSE:
+            path.close();
+            break;
+        default:
+            break;
+        }
+    }
+    
+    private Shape createShape(int[] arr) {
+        Shape s = new GeneralPath();
+        for(int i = 0; i < arr.length; i++) {
+            int type = arr[i];    
+            switch (type) {
+            case -1:
+                //MOVETO
+                ((GeneralPath)s).moveTo(arr[++i], arr[++i]);
+                break;
+            case -2:
+                //LINETO
+                ((GeneralPath)s).lineTo(arr[++i], arr[++i]);
+                break;
+            case -3:
+                //QUADTO
+                ((GeneralPath)s).quadTo(arr[++i], arr[++i], arr[++i],
+                        arr[++i]);
+                break;
+            case -4:
+                //CUBICTO
+                ((GeneralPath)s).curveTo(arr[++i], arr[++i], arr[++i],
+                        arr[++i], arr[++i], arr[++i]);
+                break;
+            case -5:
+                //CLOSE
+                return s;
+            default:
+                break;
+            }
+        }
+        return s;
+    }
+    /*
+    public int[] getPixels() {
+        return mC.getPixels();
+    }*/
+
+    public static float getRadian(float degree) {
+        return (float) ((Math.PI / 180) * degree);
+    }
+    
+    private Shape getShape() {
+        return null;
+    }
+
+    public static float getDegree(float radian) {
+        return (float) ((180 / Math.PI) * radian);
+    }
+
+    /*
+     * Degree in radian
+     */
+    public static float getEllipsisX(float degree, float princAxis) {
+        return (float) Math.cos(degree) * princAxis;
+    }
+
+    public static float getEllipsisY(float degree, float conAxis) {
+        return (float) Math.sin(degree) * conAxis;
+    }
+
+    @Override
+    public void clip(Shape s) {
+        mC.clipPath(getPath(s));
+    }
+
+    public void setCanvas(Canvas c) {
+        mC = c;
+    }
+
+    @Override
+    public void draw(Shape s) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        Paint.Style tmp = mP.getStyle();
+        mP.setStyle(Paint.Style.STROKE);
+        mC.drawPath(getPath(s), mP);
+        mP.setStyle(tmp);
+    }
+/*
+    private ArrayList getSegments(Shape s) {
+        ArrayList arr = new ArrayList();
+        PathIterator pi = s.getPathIterator(null);
+        while (pi.isDone() == false) {
+            getCurrentSegment(pi, arr);
+            pi.next();
+        }
+        return arr;
+    }
+
+    private void getCurrentSegment(PathIterator pi, ArrayList arr) {
+        float[] coordinates = new float[6];
+        int type = pi.currentSegment(coordinates);
+        switch (type) {
+        case PathIterator.SEG_MOVETO:
+            arr.add(new Integer(-1));
+            break;
+        case PathIterator.SEG_LINETO:
+            arr.add(new Integer(-2));
+            break;
+        case PathIterator.SEG_QUADTO:
+            arr.add(new Integer(-3));
+            break;
+        case PathIterator.SEG_CUBICTO:
+            arr.add(new Integer(-4));
+            break;
+        case PathIterator.SEG_CLOSE:
+            arr.add(new Integer(-5));
+            break;
+        default:
+            break;
+        }
+    }
+*/
+    /*
+     * Convenience method, not standard AWT
+     */
+    public void draw(Path s) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        Paint.Style tmp = mP.getStyle();
+        mP.setStyle(Paint.Style.STROKE);
+        s.transform(mM);
+        mC.drawPath(s, mP);
+        mP.setStyle(tmp);
+    }
+
+    @Override
+    public void drawGlyphVector(GlyphVector g, float x, float y) {
+        // TODO draw at x, y
+        // draw(g.getOutline());
+        /*
+        Matrix matrix = new Matrix();
+        matrix.setTranslate(x, y);
+        Path pth = getPath(g.getOutline());
+        pth.transform(matrix);
+        draw(pth);
+        */
+        Path path = new Path();
+        char[] c = ((AndroidGlyphVector)g).getGlyphs();
+        mP.getTextPath(c, 0, c.length, x, y, path);
+        mC.drawPath(path, mP);
+    }
+
+    @Override
+    public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    @Override
+    public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    @Override
+    public void drawString(AttributedCharacterIterator iterator, float x,
+            float y) {
+        throw new RuntimeException("AttributedCharacterIterator not supported!");
+
+    }
+
+    @Override
+    public void drawString(AttributedCharacterIterator iterator, int x, int y) {
+        throw new RuntimeException("AttributedCharacterIterator not supported!");
+
+    }
+
+    @Override
+    public void drawString(String s, float x, float y) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+
+            mP.setStyle(Paint.Style.FILL);
+            Path pth = new Path();
+            mP.getTextPath(s, 0, s.length(), x, y, pth);
+            mC.drawPath(pth, mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void drawString(String str, int x, int y) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mP.setStrokeWidth(0);
+
+            mC.drawText(str.toCharArray(), 0, str.toCharArray().length, x, y,
+                    mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void fill(Shape s) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mP.setStyle(Paint.Style.FILL);
+            mC.drawPath(getPath(s), mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public Color getBackground() {
+        return mBc;
+    }
+
+    @Override
+    public Composite getComposite() {
+        throw new RuntimeException("Composite not implemented!");
+    }
+
+    @Override
+    public GraphicsConfiguration getDeviceConfiguration() {
+        return new AndroidGraphicsConfiguration();
+    }
+
+    @Override
+    public FontRenderContext getFontRenderContext() {
+        return new FontRenderContext(getTransform(), mP.isAntiAlias(), true);
+    }
+
+    @Override
+    public java.awt.Paint getPaint() {
+        throw new RuntimeException("AWT Paint not implemented in Android!");
+    }
+
+    public static Canvas getAndroidCanvas() {
+        return mC;
+    }
+    
+    public static Paint getAndroidPaint() {
+        return mP;
+    }
+
+    @Override
+    public RenderingHints getRenderingHints() {
+        return mRh;
+    }
+
+    @Override
+    public Stroke getStroke() {
+        if (mP != null) {
+            return new BasicStroke(mP.getStrokeWidth(), mP.getStrokeCap()
+                    .ordinal(), mP.getStrokeJoin().ordinal());
+        }
+        return null;
+    }
+
+    @Override
+    public AffineTransform getTransform() {
+        return new AffineTransform(createAWTMatrix(getMatrix()));
+    }
+
+    @Override
+    public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
+        // ???AWT TODO check if on stroke
+        return s.intersects(rect.getX(), rect.getY(), rect.getWidth(), rect
+                .getHeight());
+    }
+
+    @Override
+    public void rotate(double theta) {
+        mM.preRotate((float) AndroidGraphics2D
+                .getDegree((float) (RAD_360 - theta)));
+        mC.concat(mM);
+    }
+
+    @Override
+    public void rotate(double theta, double x, double y) {
+        mM.preRotate((float) AndroidGraphics2D.getDegree((float) theta),
+                (float) x, (float) y);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void scale(double sx, double sy) {
+        mM.setScale((float) sx, (float) sy);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void setBackground(Color color) {
+        mBc = color;
+        mC.clipRect(new Rect(0, 0, mC.getWidth(), mC.getHeight()));
+        // TODO don't limit to current clip
+        mC.drawARGB(color.getAlpha(), color.getRed(), color.getGreen(), color
+                .getBlue());
+    }
+
+    @Override
+    public void setComposite(Composite comp) {
+        throw new RuntimeException("Composite not implemented!");
+    }
+
+    public void setSpaint(Paint paint) {
+        mP = paint;
+    }
+
+    @Override
+    public void setPaint(java.awt.Paint paint) {
+        setColor((Color)paint);
+    }
+
+    @Override
+    public Object getRenderingHint(RenderingHints.Key key) {
+        if (mRh == null) {
+            return null;
+        }
+        return mRh.get(key);
+    }
+
+    @Override
+    public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) {
+        if (mRh == null) {
+            mRh = new RenderingHints(hintKey, hintValue);
+        } else {
+            mRh.put(hintKey, hintValue);
+        }
+        applyHints();
+    }
+
+    @Override
+    public void setRenderingHints(Map<?, ?> hints) {
+        mRh = (RenderingHints) hints;
+        applyHints();
+    }
+
+    private void applyHints() {
+        Object o;
+
+        // TODO do something like this:
+        /*
+         * Set s = mRh.keySet(); Iterator it = s.iterator(); while(it.hasNext()) {
+         * o = it.next(); }
+         */
+
+        // /////////////////////////////////////////////////////////////////////
+        // not supported in skia
+        /*
+         * o = mRh.get(RenderingHints.KEY_ALPHA_INTERPOLATION); if
+         * (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) { } else
+         * if (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) { }
+         * else if (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_COLOR_RENDERING); if
+         * (o.equals(RenderingHints.VALUE_COLOR_RENDER_DEFAULT)) { } else if
+         * (o.equals(RenderingHints.VALUE_COLOR_RENDER_QUALITY)) { } else if
+         * (o.equals(RenderingHints.VALUE_COLOR_RENDER_SPEED)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_DITHERING); if
+         * (o.equals(RenderingHints.VALUE_DITHER_DEFAULT)) { } else if
+         * (o.equals(RenderingHints.VALUE_DITHER_DISABLE)) { } else if
+         * (o.equals(RenderingHints.VALUE_DITHER_ENABLE)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_FRACTIONALMETRICS); if
+         * (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT)) { } else
+         * if (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_OFF)) { } else if
+         * (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_ON)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_INTERPOLATION); if
+         * (o.equals(RenderingHints.VALUE_INTERPOLATION_BICUBIC)) { } else if
+         * (o.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) { } else if
+         * (o .equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_RENDERING); if
+         * (o.equals(RenderingHints.VALUE_RENDER_DEFAULT)) { } else if
+         * (o.equals(RenderingHints.VALUE_RENDER_QUALITY)) { } else if
+         * (o.equals(RenderingHints.VALUE_RENDER_SPEED)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_STROKE_CONTROL); if
+         * (o.equals(RenderingHints.VALUE_STROKE_DEFAULT)) { } else if
+         * (o.equals(RenderingHints.VALUE_STROKE_NORMALIZE)) { } else if
+         * (o.equals(RenderingHints.VALUE_STROKE_PURE)) { }
+         */
+
+        o = mRh.get(RenderingHints.KEY_ANTIALIASING);
+        if (o != null) {
+            if (o.equals(RenderingHints.VALUE_ANTIALIAS_DEFAULT)) {
+                mP.setAntiAlias(false);
+            } else if (o.equals(RenderingHints.VALUE_ANTIALIAS_OFF)) {
+                mP.setAntiAlias(false);
+            } else if (o.equals(RenderingHints.VALUE_ANTIALIAS_ON)) {
+                mP.setAntiAlias(true);
+            }
+        }
+
+        o = mRh.get(RenderingHints.KEY_TEXT_ANTIALIASING);
+        if (o != null) {
+            if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT)) {
+                mP.setAntiAlias(false);
+            } else if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)) {
+                mP.setAntiAlias(false);
+            } else if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_ON)) {
+                mP.setAntiAlias(true);
+            }
+        }
+    }
+
+    @Override
+    public void setStroke(Stroke s) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        BasicStroke bs = (BasicStroke) s;
+        mP.setStyle(Paint.Style.STROKE);
+        mP.setStrokeWidth(bs.getLineWidth());
+
+        int cap = bs.getEndCap();
+        if (cap == 0) {
+            mP.setStrokeCap(Paint.Cap.BUTT);
+        } else if (cap == 1) {
+            mP.setStrokeCap(Paint.Cap.ROUND);
+        } else if (cap == 2) {
+            mP.setStrokeCap(Paint.Cap.SQUARE);
+        }
+
+        int join = bs.getLineJoin();
+        if (join == 0) {
+            mP.setStrokeJoin(Paint.Join.MITER);
+        } else if (join == 1) {
+            mP.setStrokeJoin(Paint.Join.ROUND);
+        } else if (join == 2) {
+            mP.setStrokeJoin(Paint.Join.BEVEL);
+        }
+    }
+
+    public static float[] createMatrix(AffineTransform Tx) {
+        double[] at = new double[9];
+        Tx.getMatrix(at);
+        float[] f = new float[at.length];
+        f[0] = (float) at[0];
+        f[1] = (float) at[2];
+        f[2] = (float) at[4];
+        f[3] = (float) at[1];
+        f[4] = (float) at[3];
+        f[5] = (float) at[5];
+        f[6] = 0;
+        f[7] = 0;
+        f[8] = 1;
+        return f;
+    }
+
+    private float[] createAWTMatrix(float[] matrix) {
+        float[] at = new float[9];
+        at[0] = matrix[0];
+        at[1] = matrix[3];
+        at[2] = matrix[1];
+        at[3] = matrix[4];
+        at[4] = matrix[2];
+        at[5] = matrix[5];
+        at[6] = 0;
+        at[7] = 0;
+        at[8] = 1;
+        return at;
+    }
+
+    public static Matrix createMatrixObj(AffineTransform Tx) {
+        Matrix m = new Matrix();
+        m.reset();
+        m.setValues(createMatrix(Tx));
+        return m;
+    }
+
+    @Override
+    public void setTransform(AffineTransform Tx) {
+        mM.reset();
+        /*
+         * if(Tx.isIdentity()) { mM = new Matrix(); }
+         */
+        mM.setValues(createMatrix(Tx));
+        Matrix m = new Matrix();
+        m.setValues(getInverseMatrix());
+        mC.concat(m);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void shear(double shx, double shy) {
+        mM.setSkew((float) shx, (float) shy);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void transform(AffineTransform Tx) {
+        Matrix m = new Matrix();
+        m.setValues(createMatrix(Tx));
+        mC.concat(m);
+    }
+
+    @Override
+    public void translate(double tx, double ty) {
+        mM.setTranslate((float) tx, (float) ty);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void translate(int x, int y) {
+        mM.setTranslate((float) x, (float) y);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void clearRect(int x, int y, int width, int height) {
+        mC.clipRect(x, y, x + width, y + height);
+        if (mBc != null) {
+            mC.drawARGB(mBc.getAlpha(), mBc.getBlue(), mBc.getGreen(), mBc
+                    .getRed());
+        } else {
+            mC.drawARGB(0xff, 0xff, 0xff, 0xff);
+        }
+    }
+
+    @Override
+    public void clipRect(int x, int y, int width, int height) {
+        int cl[] = {-1, x, y, -2, x, y + width, -2, x + height, y + width, -2, x + height, y};
+        Shape shp = createShape(cl);
+        mCurrClip.intersect(new Area(shp));
+        mC.clipRect(new Rect(x, y, x + width, y + height), Region.Op.INTERSECT);
+    }
+
+    @Override
+    public void copyArea(int sx, int sy, int width, int height, int dx, int dy) {
+        copyArea(mC, sx, sy, width + dx, height + dy, dx, dy);
+    }
+
+    @Override
+    public Graphics create() {
+        return this;
+    }
+
+    @Override
+    public void dispose() {
+            mC = null;
+            mP = null;
+    }
+
+    @Override
+    public void drawArc(int x, int y, int width, int height, int sa, int ea) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mP.setStrokeWidth(0);
+            mC.drawArc(new RectF(x, y, x + width, y + height), 360 - (ea + sa),
+                       ea, true, mP);
+    }
+
+    
+    // ???AWT: only used for debuging, delete in final version
+    public void drawBitmap(Bitmap bm, float x, float y, Paint p) {
+        mC.drawBitmap(bm, x, y, null);
+    }
+    
+    @Override
+    public boolean drawImage(Image image, int x, int y, Color bgcolor,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, (AffineTransform) transform.clone(),
+                    composite, bgcolor, clip);
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, ImageObserver imageObserver) {
+        return drawImage(image, x, y, null, imageObserver);
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, int width, int height,
+            Color bgcolor, ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(width == 0 || height == 0) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            if(w == width && h == height){
+                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                        (AffineTransform) transform.clone(),
+                        composite, bgcolor, clip);
+            }else{
+                AffineTransform xform = new AffineTransform();
+                xform.setToScale((float)width / w, (float)height / h);
+                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                        (AffineTransform) transform.clone(),
+                        xform, composite, bgcolor, clip);
+            }
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, int width, int height,
+            ImageObserver imageObserver) {
+        return drawImage(image, x, y, width, height, null, imageObserver);
+    }
+
+    @Override
+    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+            int sx1, int sy1, int sx2, int sy2, Color bgcolor,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(dx1 == dx2 || dy1 == dy2 || sx1 == sx2 || sy1 == sy2) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+
+            int dstX = dx1;
+            int dstY = dy1;
+            int srcX = sx1;
+            int srcY = sy1;
+
+            int dstW = dx2 - dx1;
+            int dstH = dy2 - dy1;
+            int srcW = sx2 - sx1;
+            int srcH = sy2 - sy1;
+
+            if(srcW == dstW && srcH == dstH){
+                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
+                        (AffineTransform) transform.clone(),
+                        composite, bgcolor, clip);
+            }else{
+                AffineTransform xform = new AffineTransform();
+                xform.setToScale((float)dstW / srcW, (float)dstH / srcH);
+                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
+                        (AffineTransform) transform.clone(),
+                        xform, composite, bgcolor, clip);
+            }
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+            int sx1, int sy1, int sx2, int sy2, ImageObserver imageObserver) {
+
+        return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
+                imageObserver);
+     }
+
+    @Override
+    public void drawImage(BufferedImage bufImage, BufferedImageOp op,
+            int x, int y) {
+
+        if(bufImage == null) {
+            return;
+        }
+
+        if(op == null) {
+            drawImage(bufImage, x, y, null);
+        } else if(op instanceof AffineTransformOp){
+            AffineTransformOp atop = (AffineTransformOp) op;
+            AffineTransform xform = atop.getTransform();
+            Surface srcSurf = Surface.getImageSurface(bufImage);
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                    (AffineTransform) transform.clone(), xform,
+                    composite, null, clip);
+        } else {
+            bufImage = op.filter(bufImage, null);
+            Surface srcSurf = Surface.getImageSurface(bufImage);
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                    (AffineTransform) transform.clone(),
+                    composite, null, clip);
+        }
+    }
+
+    @Override
+    public boolean drawImage(Image image, AffineTransform trans,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(trans == null || trans.isIdentity()) {
+            return drawImage(image, 0, 0, imageObserver);
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            AffineTransform xform = (AffineTransform) transform.clone();
+            xform.concatenate(trans);
+            blitter.blit(0, 0, srcSurf, 0, 0, dstSurf, w, h, xform, composite,
+                    null, clip);
+        }
+        return done;
+    }
+        
+    @Override
+    public void drawLine(int x1, int y1, int x2, int y2) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+            mC.drawLine(x1, y1, x2, y2, mP);
+    }
+
+    @Override
+    public void drawOval(int x, int y, int width, int height) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mP.setStyle(Paint.Style.STROKE);
+            mC.drawOval(new RectF(x, y, x + width, y + height), mP);
+    }
+
+    @Override
+    public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mC.drawLine(xpoints[npoints - 1], ypoints[npoints - 1], xpoints[0],
+                    ypoints[0], mP);
+            for (int i = 0; i < npoints - 1; i++) {
+                mC.drawLine(xpoints[i], ypoints[i], xpoints[i + 1],
+                        ypoints[i + 1], mP);
+            }
+    }
+
+    @Override
+    public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) {
+        for (int i = 0; i < npoints - 1; i++) {
+            drawLine(xpoints[i], ypoints[i], xpoints[i + 1], ypoints[i + 1]);
+        }
+
+    }
+
+    @Override
+    public void drawRoundRect(int x, int y, int width, int height,
+            int arcWidth, int arcHeight) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mC.drawRoundRect(new RectF(x, y, width, height), arcWidth,
+                    arcHeight, mP);
+    }
+
+    @Override
+    public void fillArc(int x, int y, int width, int height, int sa, int ea) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            
+            Paint.Style tmp = mP.getStyle();
+            mP.setStyle(Paint.Style.FILL_AND_STROKE);
+            mC.drawArc(new RectF(x, y, x + width, y + height), 360 - (sa + ea),
+                    ea, true, mP);
+            
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void fillOval(int x, int y, int width, int height) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mP.setStyle(Paint.Style.FILL);
+            mC.drawOval(new RectF(x, y, x + width, y + height), mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void fillPolygon(int[] xpoints, int[] ypoints, int npoints) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mC.save(Canvas.CLIP_SAVE_FLAG);
+
+            mP.setStyle(Paint.Style.FILL);
+
+            GeneralPath filledPolygon = new GeneralPath(
+                    GeneralPath.WIND_EVEN_ODD, npoints);
+            filledPolygon.moveTo(xpoints[0], ypoints[0]);
+            for (int index = 1; index < xpoints.length; index++) {
+                filledPolygon.lineTo(xpoints[index], ypoints[index]);
+            }
+            filledPolygon.closePath();
+            Path path = getPath(filledPolygon);
+            mC.clipPath(path);
+            mC.drawPath(path, mP);
+
+            mP.setStyle(tmp);
+            mC.restore();
+    }
+
+    @Override
+    public void fillRect(int x, int y, int width, int height) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mP.setStyle(Paint.Style.FILL);
+            mC.drawRect(new Rect(x, y, x + width, y + height), mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void drawRect(int x, int y, int width, int height) {
+        int[] xpoints = { x, x, x + width, x + width };
+        int[] ypoints = { y, y + height, y + height, y };
+        drawPolygon(xpoints, ypoints, 4);
+    }
+
+    @Override
+    public void fillRoundRect(int x, int y, int width, int height,
+            int arcWidth, int arcHeight) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mP.setStyle(Paint.Style.FILL);
+            mC.drawRoundRect(new RectF(x, y, x + width, y + height), arcWidth,
+                    arcHeight, mP);
+    }
+
+    @Override
+    public Shape getClip() {
+        return mCurrClip;
+    }
+
+    @Override
+    public Rectangle getClipBounds() {
+            Rect r = mC.getClipBounds();
+            return new Rectangle(r.left, r.top, r.width(), r.height());
+    }
+
+    @Override
+    public Color getColor() {
+        if (mP != null) {
+            return new Color(mP.getColor());
+        }
+        return null;
+    }
+
+    @Override
+    public Font getFont() {
+        return mFnt;
+    }
+
+    @Override
+    public FontMetrics getFontMetrics(Font font) {
+        mFm = new FontMetricsImpl(font);
+        return mFm;
+    }
+
+    @Override
+    public void setClip(int x, int y, int width, int height) {
+        int cl[] = {-1, x, y, -2, x, y + width, -2, x + height, y + width, -2, x + height, y};
+        mCurrClip = new Area(createShape(cl));
+        mC.clipRect(x, y, x + width, y + height, Region.Op.REPLACE);
+
+    }
+
+    @Override
+    public void setClip(Shape clip) {
+        mCurrClip = new Area(clip);
+        mC.clipPath(getPath(clip), Region.Op.REPLACE);
+    }
+
+    @Override
+    public void setColor(Color c) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        mP.setColor(c.getRGB());
+    }
+
+    /**
+     * Font mapping:
+     * 
+     * Family:
+     * 
+     * Android         AWT
+     * -------------------------------------
+     * serif           Serif / TimesRoman
+     * sans-serif      SansSerif / Helvetica
+     * monospace       Monospaced / Courier
+     * 
+     * Style:
+     * 
+     * Android            AWT
+     * -------------------------------------
+     * normal          Plain
+     * bold            bold
+     * italic          italic
+     * 
+     */
+    @Override
+    public void setFont(Font font) {
+        if (font == null) {
+            return;
+        }
+        if (mP == null) {
+            mP = new Paint();
+        }
+
+        mFnt = font;
+        Typeface tf = null;
+        int sty = font.getStyle();
+        String nam = font.getName();
+        String aF = "";
+        if (nam != null) {
+            if (nam.equalsIgnoreCase("Serif")
+                    || nam.equalsIgnoreCase("TimesRoman")) {
+                aF = "serif";
+            } else if (nam.equalsIgnoreCase("SansSerif")
+                    || nam.equalsIgnoreCase("Helvetica")) {
+                aF = "sans-serif";
+            } else if (nam.equalsIgnoreCase("Monospaced")
+                    || nam.equalsIgnoreCase("Courier")) {
+                aF = "monospace";
+            }
+        }
+
+        switch (sty) {
+        case Font.PLAIN:
+            tf = Typeface.create(aF, Typeface.NORMAL);
+            break;
+        case Font.BOLD:
+            tf = Typeface.create(aF, Typeface.BOLD);
+            break;
+        case Font.ITALIC:
+            tf = Typeface.create(aF, Typeface.ITALIC);
+            break;
+        case Font.BOLD | Font.ITALIC:
+            tf = Typeface.create(aF, Typeface.BOLD_ITALIC);
+            break;
+        default:
+            tf = Typeface.DEFAULT;
+        }
+
+        mP.setTextSize(font.getSize());
+        mP.setTypeface(tf);
+    }
+
+    @Override
+    public void drawBytes(byte[] data, int offset, int length, int x, int y) {
+        drawString(new String(data, offset, length), x, y);
+    }
+    
+    @Override
+    public void drawPolygon(Polygon p) {
+        drawPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    @Override
+    public void fillPolygon(Polygon p) {
+        fillPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+    
+    @Override
+    public Rectangle getClipBounds(Rectangle r) {
+        Shape clip = getClip();
+        if (clip != null) {
+            Rectangle b = clip.getBounds();
+            r.x = b.x;
+            r.y = b.y;
+            r.width = b.width;
+            r.height = b.height;
+        }
+        return r;
+    }
+    
+    @Override
+    public boolean hitClip(int x, int y, int width, int height) {
+        return getClipBounds().intersects(new Rectangle(x, y, width, height));
+    }
+    
+    @Override
+    public void drawChars(char[] data, int offset, int length, int x, int y) {
+        mC.drawText(data, offset, length, x, y, mP);
+    }
+    
+    @Override
+    public void setPaintMode() {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        mP.setXfermode(null);
+    }
+
+    @Override
+    public void setXORMode(Color color) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        mP.setXfermode(new PixelXorXfermode(color.getRGB()));
+    }
+    
+    @Override
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+            setColor(color);
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+            setColor(colorUp);
+        }
+
+        width--;
+        height--;
+        fillRect(x+1, y+1, width-1, height-1);
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+    
+    @Override
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+        }
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+
+    public void copyArea(Canvas canvas, int sx, int sy, int width, int height, int dx, int dy) {
+        sx += getTransform().getTranslateX();
+        sy += getTransform().getTranslateY();
+
+        NativeUtils.nativeScrollRect(canvas,
+                new Rect(sx, sy, sx + width, sy + height),
+                dx, dy);
+    }
+}
diff --git a/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java b/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java
new file mode 100644
index 0000000..0c888cd
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.awt;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.VolatileImage;
+
+import android.graphics.Canvas;
+
+public class AndroidGraphicsConfiguration extends GraphicsConfiguration {
+
+    @Override
+    public BufferedImage createCompatibleImage(int width, int height) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BufferedImage createCompatibleImage(int width, int height,
+            int transparency) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public VolatileImage createCompatibleVolatileImage(int width, int height) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public VolatileImage createCompatibleVolatileImage(int width, int height,
+            int transparency) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Rectangle getBounds() {
+        Canvas c = AndroidGraphics2D.getAndroidCanvas();
+        if(c != null)
+            return new Rectangle(0, 0, c.getWidth(), c.getHeight());
+        return null;
+    }
+
+    @Override
+    public ColorModel getColorModel() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ColorModel getColorModel(int transparency) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public AffineTransform getDefaultTransform() {
+        return new AffineTransform();
+    }
+
+    @Override
+    public GraphicsDevice getDevice() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public AffineTransform getNormalizingTransform() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
diff --git a/awt/com/android/internal/awt/AndroidGraphicsFactory.java b/awt/com/android/internal/awt/AndroidGraphicsFactory.java
new file mode 100644
index 0000000..ca255b5
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidGraphicsFactory.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.awt;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.peer.FontPeer;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.font.AndroidFont;
+import org.apache.harmony.awt.gl.font.FontManager;
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.gl.font.AndroidFontManager;
+import org.apache.harmony.awt.wtk.NativeWindow;
+import org.apache.harmony.awt.wtk.WindowFactory;
+import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.content.Context;
+
+public class AndroidGraphicsFactory extends CommonGraphics2DFactory {
+    
+    public GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Font embedFont(String fontFilePath) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public FontManager getFontManager() {
+        return AndroidFontManager.inst;
+    }
+
+    public FontMetrics getFontMetrics(Font font) {
+        return new FontMetricsImpl(font);
+    }
+
+    public FontPeer getFontPeer(Font font) {
+        //return getFontManager().getFontPeer(font.getName(), font.getStyle(), font.getSize());
+        return new AndroidFont(font.getName(), font.getStyle(), font.getSize());
+    }
+
+    public Graphics2D getGraphics2D(NativeWindow win, int translateX,
+            int translateY, MultiRectArea clip) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Graphics2D getGraphics2D(NativeWindow win, int translateX,
+            int translateY, int width, int height) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Graphics2D getGraphics2D(Context ctx, Canvas c, Paint p) {
+        return AndroidGraphics2D.getInstance(ctx, c, p);
+    }
+
+    public Graphics2D getGraphics2D(Canvas c, Paint p) {
+        throw new RuntimeException("Not supported!");
+    }
+
+    public Graphics2D getGraphics2D() {
+        return AndroidGraphics2D.getInstance();
+    }
+
+}
diff --git a/awt/com/android/internal/awt/AndroidImageDecoder.java b/awt/com/android/internal/awt/AndroidImageDecoder.java
new file mode 100644
index 0000000..81b2e1a
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidImageDecoder.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+package com.android.internal.awt;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+//import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.IndexColorModel;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.gl.image.DecodingImageSource;
+import org.apache.harmony.awt.gl.image.ImageDecoder;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class AndroidImageDecoder extends ImageDecoder {
+    
+    private static final int hintflags =
+        ImageConsumer.SINGLEFRAME | // PNG is a static image
+        ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
+        ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
+    
+    // Each pixel is a grayscale sample.
+    private static final int PNG_COLOR_TYPE_GRAY = 0;
+    // Each pixel is an R,G,B triple.
+    private static final int PNG_COLOR_TYPE_RGB = 2;
+    // Each pixel is a palette index, a PLTE chunk must appear.
+    private static final int PNG_COLOR_TYPE_PLTE = 3;
+    // Each pixel is a grayscale sample, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
+    // Each pixel is an R,G,B triple, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_RGBA = 6;
+    
+    private static final int NB_OF_LINES_PER_CHUNK = 1;  // 0 = full image
+    
+    Bitmap bm;  // The image as decoded by Android
+    
+    // Header information
+    int imageWidth; // Image size
+    int imageHeight;  
+    int colorType;  // One of the PNG_ constants from above
+    int bitDepth;   // Number of bits per color
+    byte cmap[];    // The color palette for index color models
+    ColorModel model;  // The corresponding AWT color model
+    
+    boolean transferInts; // Is transfer of type int or byte?
+    int dataElementsPerPixel;
+
+    // Buffers for decoded image data
+    byte byteOut[];
+    int intOut[];
+
+    
+    public AndroidImageDecoder(DecodingImageSource src, InputStream is) {
+        super(src, is);
+        dataElementsPerPixel = 1;
+    }
+
+    @Override
+    /**
+     * All the decoding is done in Android
+     * 
+     * AWT???: Method returns only once the image is completly 
+     * decoded; decoding is not done asynchronously
+     */
+    public void decodeImage() throws IOException {
+        try {
+            bm = BitmapFactory.decodeStream(inputStream);
+            if (bm == null) {
+                throw new IOException("Input stream empty and no image cached");
+            }
+
+            // Check size
+            imageWidth = bm.getWidth();
+            imageHeight = bm.getHeight();
+            if (imageWidth < 0 || imageHeight < 0 ) {
+                throw new RuntimeException("Illegal image size: " 
+                        + imageWidth + ", " + imageHeight);
+            }
+            
+            // We got the image fully decoded; now send all image data to AWT
+            setDimensions(imageWidth, imageHeight);
+            model = createColorModel();
+            setColorModel(model);
+            setHints(hintflags);
+            setProperties(new Hashtable<Object, Object>()); // Empty
+            sendPixels(NB_OF_LINES_PER_CHUNK != 0 ? NB_OF_LINES_PER_CHUNK : imageHeight);
+            imageComplete(ImageConsumer.STATICIMAGEDONE);        
+        } catch (IOException e) {
+            throw e;
+        } catch (RuntimeException e) {
+            imageComplete(ImageConsumer.IMAGEERROR);
+            throw e;
+        } finally {
+            closeStream();
+        }
+    }
+    
+    /**
+     * Create the AWT color model
+     *
+     * ???AWT: Android Bitmaps are always of type: ARGB-8888-Direct color model
+     * 
+     * However, we leave the code here for a more powerfull decoder 
+     * that returns a native model, and the conversion is then handled
+     * in AWT. With such a decoder, we would need to get the colorType, 
+     * the bitDepth, (and the color palette for an index color model)
+     * from the image and construct the correct color model here.
+     */
+    private ColorModel createColorModel() {
+        ColorModel cm = null;
+        int bmModel = 5; // TODO This doesn't exist: bm.getColorModel();
+        cmap = null;
+           
+        switch (bmModel) {
+        // A1_MODEL
+        case 1: 
+            colorType = PNG_COLOR_TYPE_GRAY;
+            bitDepth = 1;
+            break;
+            
+        // A8_MODEL
+        case 2:
+            colorType = PNG_COLOR_TYPE_GRAY_ALPHA;
+            bitDepth = 8;
+            break;
+            
+        // INDEX8_MODEL
+        // RGB_565_MODEL
+        // ARGB_8888_MODEL
+        case 3:
+        case 4: 
+        case 5: 
+            colorType = bm.hasAlpha() ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB;
+            bitDepth = 8;
+            break;
+
+        default:
+            // awt.3C=Unknown PNG color type
+            throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+        }
+        
+        switch (colorType) {
+        
+            case PNG_COLOR_TYPE_GRAY: {
+                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 &&  bitDepth != 1) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                // Create gray color model
+                int numEntries = 1 << bitDepth;
+                int scaleFactor = 255 / (numEntries-1);
+                byte comps[] = new byte[numEntries];
+                for (int i = 0; i < numEntries; i++) {
+                    comps[i] = (byte) (i * scaleFactor);
+                }
+                cm = new IndexColorModel(bitDepth, numEntries, comps, comps, comps);
+
+                transferInts = false;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_RGB: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+                
+                cm = new DirectColorModel(24, 0xff0000, 0xFF00, 0xFF);
+                
+                transferInts = true;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_PLTE: {
+                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                if (cmap == null) {
+                    throw new IllegalStateException("Palette color type is not supported");
+                }
+
+                cm = new IndexColorModel(bitDepth, cmap.length / 3, cmap, 0, false);
+
+                transferInts = false;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_GRAY_ALPHA: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                        true, false,
+                        Transparency.TRANSLUCENT,
+                        DataBuffer.TYPE_BYTE);
+
+                transferInts = false;
+                dataElementsPerPixel = 2;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_RGBA: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = ColorModel.getRGBdefault();
+
+                transferInts = true;
+                break;
+            }
+            default:
+                // awt.3C=Unknown PNG color type
+                throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+        }
+        
+        return cm;
+    }
+    
+    private void sendPixels(int nbOfLinesPerChunk) {
+        int w = imageWidth;
+        int h = imageHeight;
+        int n = 1;
+        if (nbOfLinesPerChunk > 0 && nbOfLinesPerChunk <= h) {
+            n = nbOfLinesPerChunk;
+        }
+        
+        if (transferInts) {
+            // Create output buffer
+            intOut = new int[w * n];
+            for (int yi = 0; yi < h; yi += n) {
+                // Last chunk might contain less liness
+                if (n > 1 && h - yi < n ) {
+                    n = h - yi;
+                }
+                bm.getPixels(intOut, 0, w, 0, yi, w, n);
+                setPixels(0, yi, w, n, model, intOut, 0, w);
+            }
+        } else {
+            // Android bitmaps always store ints (ARGB-8888 direct model)
+            throw new RuntimeException("Byte transfer not supported");
+        }
+    }
+    
+}
diff --git a/awt/com/android/internal/awt/AndroidJavaBlitter.java b/awt/com/android/internal/awt/AndroidJavaBlitter.java
new file mode 100644
index 0000000..423b534
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidJavaBlitter.java
@@ -0,0 +1,536 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.awt;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.XORComposite;
+import org.apache.harmony.awt.gl.render.Blitter;
+
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+public class AndroidJavaBlitter implements Blitter {
+
+    private Canvas canvas;
+    private Paint paint;
+    private int colorCache;
+        
+    public AndroidJavaBlitter(Canvas c) {
+        this.canvas = c;
+        this.paint = new Paint();
+        this.paint.setStrokeWidth(1);
+    }
+    
+    /**
+     * Instead of multiplication and division we are using values from
+     * Lookup tables.
+     */
+    static byte mulLUT[][]; // Lookup table for multiplication
+    static byte divLUT[][]; // Lookup table for division
+
+    static{
+        mulLUT = new byte[256][256];
+        for(int i = 0; i < 256; i++){
+            for(int j = 0; j < 256; j++){
+                mulLUT[i][j] = (byte)((float)(i * j)/255 + 0.5f);
+            }
+        }
+        divLUT = new byte[256][256];
+        for(int i = 1; i < 256; i++){
+            for(int j = 0; j < i; j++){
+                divLUT[i][j] = (byte)(((float)j / 255) / ((float)i/ 255) * 255 + 0.5f);
+            }
+            for(int j = i; j < 256; j++){
+                divLUT[i][j] = (byte)255;
+            }
+        }
+    }
+
+    final static int AlphaCompositeMode = 1;
+    final static int XORMode = 2;
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            AffineTransform xform, Composite comp, Color bgcolor,
+            MultiRectArea clip) {
+        
+        if(xform == null){
+            blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }else{
+            double scaleX = xform.getScaleX();
+            double scaleY = xform.getScaleY();
+            double scaledX = dstX / scaleX;
+            double scaledY = dstY / scaleY;
+            AffineTransform at = new AffineTransform();
+            at.setToTranslation(scaledX, scaledY);
+            xform.concatenate(at);
+            sysxform.concatenate(xform);
+            blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }
+
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            Composite comp, Color bgcolor, MultiRectArea clip) {
+        
+        if(sysxform == null) {
+            sysxform = new AffineTransform();
+        }
+        int type = sysxform.getType();
+        switch(type){
+            case AffineTransform.TYPE_TRANSLATION:
+                dstX += sysxform.getTranslateX();
+                dstY += sysxform.getTranslateY();
+            case AffineTransform.TYPE_IDENTITY:
+                simpleBlit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
+                        width, height, comp, bgcolor, clip);
+                break;
+            default:
+                int srcW = srcSurf.getWidth();
+                int srcH = srcSurf.getHeight();
+
+                int w = srcX + width < srcW ? width : srcW - srcX;
+                int h = srcY + height < srcH ? height : srcH - srcY;
+
+                ColorModel srcCM = srcSurf.getColorModel();
+                Raster srcR = srcSurf.getRaster().createChild(srcX, srcY,
+                        w, h, 0, 0, null);
+
+                ColorModel dstCM = dstSurf.getColorModel();
+                WritableRaster dstR = dstSurf.getRaster();
+
+                transformedBlit(srcCM, srcR, 0, 0, dstCM, dstR, dstX, dstY, w, h,
+                        sysxform, comp, bgcolor, clip);
+
+        }
+    }
+
+    public void simpleBlit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+
+        // TODO It's possible, though unlikely that we might encounter non-int[]
+        // data buffers. In this case the following code needs to have several
+        // branches that take this into account.
+        data = (DataBufferInt)srcSurf.getRaster().getDataBuffer();
+        int[] pixels = data.getData();
+        if (!srcSurf.getColorModel().hasAlpha()) {
+            // This wouldn't be necessary if Android supported RGB_888.
+            for (int i = 0; i < pixels.length; i++) {
+                pixels[i] = pixels[i] | 0xff000000;
+            }
+        }
+        bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
+        canvas.drawBitmap(bmap, dstX, dstY, paint);
+    }
+    
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+
+        javaBlt(srcX, srcY, srcSurf.getWidth(), srcSurf.getHeight(),
+                srcSurf.getColorModel(), srcSurf.getRaster(), dstX, dstY,
+                dstSurf.getWidth(), dstSurf.getHeight(),
+                dstSurf.getColorModel(), dstSurf.getRaster(),
+                width, height, comp, bgcolor, clip);
+
+    }
+    
+    public void javaBlt(int srcX, int srcY, int srcW, int srcH,
+            ColorModel srcCM, Raster srcRast, int dstX, int dstY,
+            int dstW, int dstH, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, Composite comp, Color bgcolor,
+            MultiRectArea clip){
+        
+        int srcX2 = srcW - 1;
+        int srcY2 = srcH - 1;
+        int dstX2 = dstW - 1;
+        int dstY2 = dstH - 1;
+
+        if(srcX < 0){
+            width += srcX;
+            srcX = 0;
+        }
+        if(srcY < 0){
+            height += srcY;
+            srcY = 0;
+        }
+
+        if(dstX < 0){
+            width += dstX;
+            srcX -= dstX;
+            dstX = 0;
+        }
+        if(dstY < 0){
+            height += dstY;
+            srcY -= dstY;
+            dstY = 0;
+        }
+
+        if(srcX > srcX2 || srcY > srcY2) {
+            return;
+        }
+        if(dstX > dstX2 || dstY > dstY2) {
+            return;
+        }
+
+        if(srcX + width > srcX2) {
+            width = srcX2 - srcX + 1;
+        }
+        if(srcY + height > srcY2) {
+            height = srcY2 - srcY + 1;
+        }
+        if(dstX + width > dstX2) {
+            width = dstX2 - dstX + 1;
+        }
+        if(dstY + height > dstY2) {
+            height = dstY2 - dstY + 1;
+        }
+
+        if(width <= 0 || height <= 0) {
+            return;
+        }
+
+        int clipRects[];
+        if(clip != null) {
+            clipRects = clip.rect;
+        } else {
+            clipRects = new int[]{5, 0, 0, dstW - 1, dstH - 1};
+        }
+
+        boolean isAlphaComp = false;
+        int rule = 0;
+        float alpha = 0;
+        boolean isXORComp = false;
+        Color xorcolor = null;
+        CompositeContext cont = null;
+
+        if(comp instanceof AlphaComposite){
+            isAlphaComp = true;
+            AlphaComposite ac = (AlphaComposite) comp;
+            rule = ac.getRule();
+            alpha = ac.getAlpha();
+        }else if(comp instanceof XORComposite){
+            isXORComp = true;
+            XORComposite xcomp = (XORComposite) comp;
+            xorcolor = xcomp.getXORColor();
+        }else{
+            cont = comp.createContext(srcCM, dstCM, null);
+        }
+
+        for(int i = 1; i < clipRects[0]; i += 4){
+            int _sx = srcX;
+            int _sy = srcY;
+
+            int _dx = dstX;
+            int _dy = dstY;
+
+            int _w = width;
+            int _h = height;
+
+            int cx = clipRects[i];          // Clipping left top X
+            int cy = clipRects[i + 1];      // Clipping left top Y
+            int cx2 = clipRects[i + 2];     // Clipping right bottom X
+            int cy2 = clipRects[i + 3];     // Clipping right bottom Y
+
+            if(_dx > cx2 || _dy > cy2 || dstX2 < cx || dstY2 < cy) {
+                continue;
+            }
+
+            if(cx > _dx){
+                int shx = cx - _dx;
+                _w -= shx;
+                _dx = cx;
+                _sx += shx;
+            }
+
+            if(cy > _dy){
+                int shy = cy - _dy;
+                _h -= shy;
+                _dy = cy;
+                _sy += shy;
+            }
+
+            if(_dx + _w > cx2 + 1){
+                _w = cx2 - _dx + 1;
+            }
+
+            if(_dy + _h > cy2 + 1){
+                _h = cy2 - _dy + 1;
+            }
+
+            if(_sx > srcX2 || _sy > srcY2) {
+                continue;
+            }
+
+            if(isAlphaComp){
+                alphaCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
+                        dstCM, dstRast, _w, _h, rule, alpha, bgcolor);
+            }else if(isXORComp){
+                xorCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
+                        dstCM, dstRast, _w, _h, xorcolor);
+            }else{
+                Raster sr = srcRast.createChild(_sx, _sy, _w, _h, 0, 0, null);
+                WritableRaster dr = dstRast.createWritableChild(_dx, _dy,
+                        _w, _h, 0, 0, null);
+                cont.compose(sr, dr, dr);
+            }
+        }
+        
+    }
+
+    DataBufferInt data;
+    Bitmap bmap, bmp;
+    
+    void alphaCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
+            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, int rule, float alpha, Color bgcolor){
+        
+        Object srcPixel = getTransferArray(srcRast, 1);
+        data = (DataBufferInt)srcRast.getDataBuffer();
+        int pix[] = data.getData();
+        bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565);
+        canvas.drawBitmap(bmap, dstX, dstY, paint);
+    }
+    
+    void render(int[] img, int x, int y, int width, int height) {
+        canvas.drawBitmap(Bitmap.createBitmap(img, width, height, Bitmap.Config.ARGB_8888), x, y, paint);
+    }
+
+    void xorCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
+            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, Color xorcolor){
+
+        data = (DataBufferInt)srcRast.getDataBuffer();
+        int pix[] = data.getData();
+        bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565);
+        canvas.drawBitmap(bmap, dstX, dstY, paint);
+    }
+    
+    private void transformedBlit(ColorModel srcCM, Raster srcR, int srcX, int srcY,
+            ColorModel dstCM, WritableRaster dstR, int dstX, int dstY,
+            int width, int height, AffineTransform at, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+        
+        data = (DataBufferInt)srcR.getDataBuffer();
+        int[] pixels = data.getData();
+        if (!srcCM.hasAlpha()) {
+            // This wouldn't be necessary if Android supported RGB_888.
+            for (int i = 0; i < pixels.length; i++) {
+                pixels[i] = pixels[i] | 0xff000000;
+            }
+        }
+        bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
+        
+        Matrix tm = new Matrix();
+        tm.setConcat(canvas.getMatrix(), AndroidGraphics2D.createMatrixObj(at));
+        if(at.getType() > 1) {
+            bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, true);
+        } else {
+            bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, false);
+        }
+        canvas.drawBitmap(bmp, dstX + (float)at.getTranslateX(), dstY + (float)at.getTranslateY(), paint);
+    }
+
+    private Rectangle2D getBounds2D(AffineTransform at, Rectangle r) {
+        int x = r.x;
+        int y = r.y;
+        int width = r.width;
+        int height = r.height;
+
+        float[] corners = {
+            x, y,
+            x + width, y,
+            x + width, y + height,
+            x, y + height
+        };
+
+        at.transform(corners, 0, corners, 0, 4);
+
+        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
+        bounds.add(corners[2], corners[3]);
+        bounds.add(corners[4], corners[5]);
+        bounds.add(corners[6], corners[7]);
+
+        return bounds;
+    }
+
+    private int compose(int srcRGB, boolean isSrcAlphaPre,
+            int dstRGB, boolean dstHasAlpha, boolean isDstAlphaPre,
+            int rule, int srcConstAlpha){
+
+        int sa, sr, sg, sb, da, dr, dg, db;
+
+        sa = (srcRGB >> 24) & 0xff;
+        sr = (srcRGB >> 16) & 0xff;
+        sg = (srcRGB >> 8) & 0xff;
+        sb = srcRGB & 0xff;
+
+        if(isSrcAlphaPre){
+            sa = mulLUT[srcConstAlpha][sa] & 0xff;
+            sr = mulLUT[srcConstAlpha][sr] & 0xff;
+            sg = mulLUT[srcConstAlpha][sg] & 0xff;
+            sb = mulLUT[srcConstAlpha][sb] & 0xff;
+        }else{
+            sa = mulLUT[srcConstAlpha][sa] & 0xff;
+            sr = mulLUT[sa][sr] & 0xff;
+            sg = mulLUT[sa][sg] & 0xff;
+            sb = mulLUT[sa][sb] & 0xff;
+        }
+
+        da = (dstRGB >> 24) & 0xff;
+        dr = (dstRGB >> 16) & 0xff;
+        dg = (dstRGB >> 8) & 0xff;
+        db = dstRGB & 0xff;
+
+        if(!isDstAlphaPre){
+            dr = mulLUT[da][dr] & 0xff;
+            dg = mulLUT[da][dg] & 0xff;
+            db = mulLUT[da][db] & 0xff;
+        }
+
+        int Fs = 0;
+        int Fd = 0;
+        switch(rule){
+        case AlphaComposite.CLEAR:
+            break;
+
+        case AlphaComposite.DST:
+            Fd = 255;
+            break;
+
+        case AlphaComposite.DST_ATOP:
+            Fs = 255 - da;
+            Fd = sa;
+            break;
+
+        case AlphaComposite.DST_IN:
+            Fd = sa;
+            break;
+
+        case AlphaComposite.DST_OUT:
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.DST_OVER:
+            Fs = 255 - da;
+            Fd = 255;
+            break;
+
+        case AlphaComposite.SRC:
+            Fs = 255;
+            break;
+
+        case AlphaComposite.SRC_ATOP:
+            Fs = da;
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.SRC_IN:
+            Fs = da;
+            break;
+
+        case AlphaComposite.SRC_OUT:
+            Fs = 255 - da;
+            break;
+
+        case AlphaComposite.SRC_OVER:
+            Fs = 255;
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.XOR:
+            Fs = 255 - da;
+            Fd = 255 - sa;
+            break;
+        }
+        dr = (mulLUT[sr][Fs] & 0xff) + (mulLUT[dr][Fd] & 0xff);
+        dg = (mulLUT[sg][Fs] & 0xff) + (mulLUT[dg][Fd] & 0xff);
+        db = (mulLUT[sb][Fs] & 0xff) + (mulLUT[db][Fd] & 0xff);
+
+        da = (mulLUT[sa][Fs] & 0xff) + (mulLUT[da][Fd] & 0xff);
+
+        if(!isDstAlphaPre){
+            if(da != 255){
+                dr = divLUT[da][dr] & 0xff;
+                dg = divLUT[da][dg] & 0xff;
+                db = divLUT[da][db] & 0xff;
+            }
+        }
+        if(!dstHasAlpha) {
+            da = 0xff;
+        }
+        dstRGB = (da << 24) | (dr << 16) | (dg << 8) | db;
+
+        return dstRGB;
+
+    }
+    
+    /**
+     * Allocate an array that can be use to store the result for a 
+     * Raster.getDataElements call.
+     * @param raster  Raster (type) where the getDataElements call will be made. 
+     * @param nbPixels  How many pixels to store in the array at most
+     * @return the result array or null
+     */
+    private Object getTransferArray(Raster raster, int nbPixels) {
+        int transferType = raster.getTransferType();
+        int nbDataElements = raster.getSampleModel().getNumDataElements();
+        int n = nbDataElements * nbPixels;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            return new byte[n];
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            return new short[n];
+        case DataBuffer.TYPE_INT:
+            return new int[n];
+        case DataBuffer.TYPE_FLOAT:
+            return new float[n];
+        case DataBuffer.TYPE_DOUBLE:
+            return new double[n];
+        case DataBuffer.TYPE_UNDEFINED:
+        default:
+            return null;
+        }
+    }
+    
+    /**
+     * Draw a pixel
+     */
+    private void dot(int x, int y, int clr) {
+        if (colorCache != clr) {
+            paint.setColor(clr);  
+            colorCache = clr;
+        }
+        canvas.drawLine(x, y, x + 1, y + 1, paint);
+    }
+}
diff --git a/awt/com/android/internal/awt/AndroidNativeEventQueue.java b/awt/com/android/internal/awt/AndroidNativeEventQueue.java
new file mode 100644
index 0000000..fc30614
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidNativeEventQueue.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.awt;
+
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+
+public class AndroidNativeEventQueue extends NativeEventQueue {
+    
+    private Object eventMonitor;
+    
+    public AndroidNativeEventQueue() {
+        super();
+        eventMonitor = getEventMonitor();
+    }
+
+    @Override
+    public void awake() {
+        synchronized (eventMonitor) {
+            eventMonitor.notify();
+        }
+    }
+
+    @Override
+    public void dispatchEvent() {
+        //???AWT
+        System.out.println(getClass()+": empty method called");
+    }
+
+    @Override
+    public long getJavaWindow() {
+        //???AWT
+        System.out.println(getClass()+": empty method called");
+        return 0;
+    }
+
+    @Override
+    public void performLater(Task task) {
+        //???AWT
+        System.out.println(getClass()+": empty method called");
+    }
+
+    @Override
+    public void performTask(Task task) {
+        //???AWT
+        System.out.println(getClass()+": empty method called");
+    }
+
+    @Override
+    public boolean waitEvent() {
+        while (isEmpty() ) {
+            synchronized (eventMonitor) {
+                try {
+                    eventMonitor.wait(1000);
+                } catch (InterruptedException ignore) {
+                }
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/awt/com/android/internal/awt/AndroidWTK.java b/awt/com/android/internal/awt/AndroidWTK.java
new file mode 100644
index 0000000..1609d11
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidWTK.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.awt;
+
+import java.awt.GraphicsDevice;
+
+import org.apache.harmony.awt.wtk.CursorFactory;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.NativeIM;
+import org.apache.harmony.awt.wtk.NativeMouseInfo;
+import org.apache.harmony.awt.wtk.NativeRobot;
+import org.apache.harmony.awt.wtk.SystemProperties;
+import org.apache.harmony.awt.wtk.WTK;
+import org.apache.harmony.awt.wtk.WindowFactory;
+
+public class AndroidWTK extends WTK {
+
+    private AndroidGraphicsFactory mAgf;
+    private AndroidNativeEventQueue mAneq;
+    
+    @Override
+    public CursorFactory getCursorFactory() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public GraphicsFactory getGraphicsFactory() {
+        if(mAgf == null) {
+            mAgf = new AndroidGraphicsFactory();
+        }
+        return mAgf;
+    }
+
+    @Override
+    public NativeEventQueue getNativeEventQueue() {
+        if(mAneq == null) {
+            mAneq = new AndroidNativeEventQueue();
+        }
+        return mAneq;
+    }
+
+    @Override
+    public NativeIM getNativeIM() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NativeMouseInfo getNativeMouseInfo() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NativeRobot getNativeRobot(GraphicsDevice screen) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SystemProperties getSystemProperties() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public WindowFactory getWindowFactory() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
diff --git a/awt/com/android/internal/awt/AwtFactory.java b/awt/com/android/internal/awt/AwtFactory.java
new file mode 100644
index 0000000..6e667b2
--- /dev/null
+++ b/awt/com/android/internal/awt/AwtFactory.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.awt;
+
+import java.awt.Graphics2D;
+import java.awt.Toolkit;
+
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+
+public class AwtFactory {
+    
+    private static GraphicsFactory gf;
+    
+    /**
+     * Use this method to get acces to AWT drawing primitives and to
+     * render into the surface area of a Android widget. Origin and 
+     * clip of the returned graphics object are the same as in the
+     * corresponding Android widget. 
+     * 
+     * @param c Canvas of the android widget to draw into
+     * @param p The default drawing parameters such as font, 
+     * stroke, foreground and background colors, etc.
+     * @return The AWT Graphics object that makes all AWT 
+     * drawing primitives available in the androind world.
+     */
+    public static Graphics2D getAwtGraphics(Canvas c, Paint p) {
+        // AWT?? TODO: test it!
+        if (null == gf) {
+            Toolkit tk = Toolkit.getDefaultToolkit();
+            gf = tk.getGraphicsFactory();
+        }
+        return gf.getGraphics2D(c, p);
+    }
+
+}
diff --git a/awt/com/android/internal/awt/ImageOutputStreamWrapper.java b/awt/com/android/internal/awt/ImageOutputStreamWrapper.java
new file mode 100644
index 0000000..92185fd
--- /dev/null
+++ b/awt/com/android/internal/awt/ImageOutputStreamWrapper.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.awt;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.imageio.stream.ImageOutputStream;
+
+public class ImageOutputStreamWrapper extends OutputStream {
+	
+	protected ImageOutputStream mIos;
+	
+	private byte[] mBuff;
+	
+	public ImageOutputStreamWrapper(ImageOutputStream ios) {
+		if (null == ios) {
+			throw new IllegalArgumentException("ImageOutputStream must not be null");
+		}
+		this.mIos = ios;
+		this.mBuff = new byte[1];
+	}
+
+	public ImageOutputStream getImageOutputStream() {
+		return mIos;
+	}
+	
+	@Override
+	public void write(int oneByte) throws IOException {
+		mBuff[0] = (byte)oneByte;
+		mIos.write(mBuff, 0, 1);
+	}
+
+	public void write(byte[] b) throws IOException {
+		mIos.write(b, 0, b.length);
+	}
+	
+	public void write(byte[] b, int off, int len) throws IOException {
+		mIos.write(b, off, len);
+	}
+	
+	public void flush() throws IOException {
+		mIos.flush();
+	}
+	
+    public void close() throws IOException {
+    	if (mIos == null) {
+    		throw new IOException("Stream already closed");
+    	}
+        mIos = null;
+    }
+}
diff --git a/awt/java/awt/AWTEvent.java b/awt/java/awt/AWTEvent.java
new file mode 100644
index 0000000..1ed9a37
--- /dev/null
+++ b/awt/java/awt/AWTEvent.java
@@ -0,0 +1,618 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev, Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.util.EventObject;
+import java.util.Hashtable;
+import java.util.EventListener;
+
+import java.awt.event.*;
+
+/**
+ * The abstract AWT events is base class for all AWT events. 
+ * This class and its subclasses supercede the original java.awt.Event class.
+ */
+public abstract class AWTEvent extends EventObject {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1825314779160409405L;
+
+    /** The Constant COMPONENT_EVENT_MASK indicates the event relates to a component. */
+    public static final long COMPONENT_EVENT_MASK = 1;
+
+    /** The Constant CONTAINER_EVENT_MASK indicates the event relates to a container. */
+    public static final long CONTAINER_EVENT_MASK = 2;
+
+    /** The Constant FOCUS_EVENT_MASK indicates the event relates to the focus. */
+    public static final long FOCUS_EVENT_MASK = 4;
+
+    /** The Constant KEY_EVENT_MASK indicates the event relates to a key. */
+    public static final long KEY_EVENT_MASK = 8;
+
+    /** The Constant MOUSE_EVENT_MASK indicates the event relates to the mouse. */
+    public static final long MOUSE_EVENT_MASK = 16;
+
+    /** The Constant MOUSE_MOTION_EVENT_MASK indicates the event relates to a mouse motion. */
+    public static final long MOUSE_MOTION_EVENT_MASK = 32;
+
+    /** The Constant WINDOW_EVENT_MASK indicates the event relates to a window. */
+    public static final long WINDOW_EVENT_MASK = 64;
+
+    /** The Constant ACTION_EVENT_MASK indicates the event relates to an action. */
+    public static final long ACTION_EVENT_MASK = 128;
+
+    /** The Constant ADJUSTMENT_EVENT_MASK indicates the event relates to an adjustment. */
+    public static final long ADJUSTMENT_EVENT_MASK = 256;
+
+    /** The Constant ITEM_EVENT_MASK indicates the event relates to an item. */
+    public static final long ITEM_EVENT_MASK = 512;
+
+    /** The Constant TEXT_EVENT_MASK indicates the event relates to text. */
+    public static final long TEXT_EVENT_MASK = 1024;
+
+    /** The Constant INPUT_METHOD_EVENT_MASK indicates the event relates to an input method. */
+    public static final long INPUT_METHOD_EVENT_MASK = 2048;
+
+    /** The Constant PAINT_EVENT_MASK indicates the event relates to a paint method. */
+    public static final long PAINT_EVENT_MASK = 8192;
+
+    /** The Constant INVOCATION_EVENT_MASK indicates the event relates to a method invocation. */
+    public static final long INVOCATION_EVENT_MASK = 16384;
+
+    /** The Constant HIERARCHY_EVENT_MASK indicates the event relates to a hierarchy. */
+    public static final long HIERARCHY_EVENT_MASK = 32768;
+
+    /** 
+     * The Constant HIERARCHY_BOUNDS_EVENT_MASK indicates the event relates to hierarchy bounds.
+     */
+    public static final long HIERARCHY_BOUNDS_EVENT_MASK = 65536;
+
+    /** The Constant MOUSE_WHEEL_EVENT_MASK indicates the event relates to the mouse wheel. */
+    public static final long MOUSE_WHEEL_EVENT_MASK = 131072;
+
+    /** The Constant WINDOW_STATE_EVENT_MASK indicates the event relates to a window state. */
+    public static final long WINDOW_STATE_EVENT_MASK = 262144;
+
+    /** The Constant WINDOW_FOCUS_EVENT_MASK indicates the event relates to a window focus. */
+    public static final long WINDOW_FOCUS_EVENT_MASK = 524288;
+
+    /** The Constant RESERVED_ID_MAX indicates the maximum value for reserved 
+     * AWT event IDs.
+     */
+    public static final int RESERVED_ID_MAX = 1999;
+
+    /** The Constant eventsMap. */
+    private static final Hashtable<Integer, EventDescriptor> eventsMap = new Hashtable<Integer, EventDescriptor>();
+
+    /** The converter. */
+    private static EventConverter converter;
+
+    /** The ID of the event. */
+    protected int id;
+
+    /** 
+     * The consumed indicates whether or not the event is sent back down to 
+     * the peer once the source has processed it (false means it's sent to the peer,
+     * true means it's not).
+     */ 
+    protected boolean consumed;
+
+    /** The dispatched by kfm. */
+    boolean dispatchedByKFM;
+    
+    /** The is posted. */
+    transient boolean isPosted;
+
+    static {
+        eventsMap.put(new Integer(KeyEvent.KEY_TYPED),
+                new EventDescriptor(KEY_EVENT_MASK, KeyListener.class));
+        eventsMap.put(new Integer(KeyEvent.KEY_PRESSED),
+                new EventDescriptor(KEY_EVENT_MASK, KeyListener.class));
+        eventsMap.put(new Integer(KeyEvent.KEY_RELEASED),
+                new EventDescriptor(KEY_EVENT_MASK, KeyListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_CLICKED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_PRESSED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_RELEASED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_MOVED),
+                new EventDescriptor(MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_ENTERED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_EXITED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_DRAGGED),
+                new EventDescriptor(MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_WHEEL),
+                new EventDescriptor(MOUSE_WHEEL_EVENT_MASK, MouseWheelListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_MOVED),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_RESIZED),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_SHOWN),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_HIDDEN),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(FocusEvent.FOCUS_GAINED),
+                new EventDescriptor(FOCUS_EVENT_MASK, FocusListener.class));
+        eventsMap.put(new Integer(FocusEvent.FOCUS_LOST),
+                new EventDescriptor(FOCUS_EVENT_MASK, FocusListener.class));
+        eventsMap.put(new Integer(PaintEvent.PAINT),
+                new EventDescriptor(PAINT_EVENT_MASK, null));
+        eventsMap.put(new Integer(PaintEvent.UPDATE),
+                new EventDescriptor(PAINT_EVENT_MASK, null));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_OPENED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSING),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_DEICONIFIED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_ICONIFIED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_STATE_CHANGED),
+                new EventDescriptor(WINDOW_STATE_EVENT_MASK, WindowStateListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_LOST_FOCUS),
+                new EventDescriptor(WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_GAINED_FOCUS),
+                new EventDescriptor(WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_DEACTIVATED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_ACTIVATED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.HIERARCHY_CHANGED),
+                new EventDescriptor(HIERARCHY_EVENT_MASK, HierarchyListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_MOVED),
+                new EventDescriptor(HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_RESIZED),
+                new EventDescriptor(HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
+        eventsMap.put(new Integer(ContainerEvent.COMPONENT_ADDED),
+                new EventDescriptor(CONTAINER_EVENT_MASK, ContainerListener.class));
+        eventsMap.put(new Integer(ContainerEvent.COMPONENT_REMOVED),
+                new EventDescriptor(CONTAINER_EVENT_MASK, ContainerListener.class));
+        eventsMap.put(new Integer(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED),
+                new EventDescriptor(INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
+        eventsMap.put(new Integer(InputMethodEvent.CARET_POSITION_CHANGED),
+                new EventDescriptor(INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
+        eventsMap.put(new Integer(InvocationEvent.INVOCATION_DEFAULT),
+                new EventDescriptor(INVOCATION_EVENT_MASK, null));
+        eventsMap.put(new Integer(ItemEvent.ITEM_STATE_CHANGED),
+                new EventDescriptor(ITEM_EVENT_MASK, ItemListener.class));
+        eventsMap.put(new Integer(TextEvent.TEXT_VALUE_CHANGED),
+                new EventDescriptor(TEXT_EVENT_MASK, TextListener.class));
+        eventsMap.put(new Integer(ActionEvent.ACTION_PERFORMED),
+                new EventDescriptor(ACTION_EVENT_MASK, ActionListener.class));
+        eventsMap.put(new Integer(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED),
+                new EventDescriptor(ADJUSTMENT_EVENT_MASK, AdjustmentListener.class));
+        converter = new EventConverter();
+    }
+    
+    /**
+     * Instantiates a new AWT event from the specified Event object.
+     * 
+     * @param event the Event object.
+     */
+    public AWTEvent(Event event) {
+        this(event.target, event.id);
+    }
+
+    /**
+     * Instantiates a new AWT event with the specified object and type.
+     * 
+     * @param source the source Object.
+     * @param id the event's type.
+     */
+    public AWTEvent(Object source, int id) {
+        super(source);
+        this.id = id;
+        consumed = false;
+    }
+
+    /**
+     * Gets the event's type.
+     * 
+     * @return the event type ID.
+     */
+    public int getID() {
+        return id;
+    }
+
+    /**
+     * Sets a new source for the AWTEvent.
+     * 
+     * @param newSource the new source Object for the AWTEvent.
+     */
+    public void setSource(Object newSource) {
+        source = newSource;
+    }
+
+    /**
+     * Returns a String representation of the AWTEvent.
+     * 
+     * @return the String representation of the AWTEvent.
+     */
+    @Override
+    public String toString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * AWTEvent event = new AWTEvent(new Component(){}, 1){};
+         * System.out.println(event);
+         */
+        String name = ""; //$NON-NLS-1$
+        
+        if (source instanceof Component && (source != null)) {
+            Component comp = (Component) getSource();
+            name = comp.getName();
+            if (name == null) {
+                name = ""; //$NON-NLS-1$
+            }
+        }
+        
+        return (getClass().getName() + "[" + paramString() + "]" //$NON-NLS-1$ //$NON-NLS-2$
+                + " on " + (name.length() > 0 ? name : source)); //$NON-NLS-1$
+    }
+
+    /**
+     * Returns a string representation of the AWTEvent state. 
+     *  
+     * @return a string representation of the AWTEvent state.
+     */
+    public String paramString() {
+        //nothing to implement: all event types must override this method
+        return ""; //$NON-NLS-1$
+    }
+
+    /**
+     * Checks whether or not this AWTEvent has been consumed.
+     * 
+     * @return true, if this AWTEvent has been consumed, false otherwise.
+     */
+    protected boolean isConsumed() {
+        return consumed;
+    }
+
+    /**
+     * Consumes the AWTEvent.
+     */
+    protected void consume() {
+       consumed = true;
+    }
+
+    /**
+     * Convert AWTEvent object to a corresponding (deprecated) Event object.
+     * 
+     * @return new Event object which is a converted AWTEvent object or null
+     * if the conversion is not possible
+     */
+    Event getEvent() {
+        
+        if (id == ActionEvent.ACTION_PERFORMED) {
+            ActionEvent ae = (ActionEvent) this;
+            return converter.convertActionEvent(ae);
+
+        } else if (id == AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED) {
+            AdjustmentEvent ae = (AdjustmentEvent) this;
+            return converter.convertAdjustmentEvent(ae);
+
+//???AWT
+//        } else if (id == ComponentEvent.COMPONENT_MOVED
+//                && source instanceof Window) {
+//            //the only type of Component events is COMPONENT_MOVED on window
+//            ComponentEvent ce = (ComponentEvent) this;
+//            return converter.convertComponentEvent(ce);
+
+        } else if (id >= FocusEvent.FOCUS_FIRST && id <= FocusEvent.FOCUS_LAST) {
+            //nothing to convert
+
+//???AWT
+//        } else if (id == ItemEvent.ITEM_STATE_CHANGED) {
+//            ItemEvent ie = (ItemEvent) this;
+//            return converter.convertItemEvent(ie);
+
+        } else if (id == KeyEvent.KEY_PRESSED || id == KeyEvent.KEY_RELEASED) {
+            KeyEvent ke = (KeyEvent) this;
+            return converter.convertKeyEvent(ke);
+        } else if (id >= MouseEvent.MOUSE_FIRST && id <= MouseEvent.MOUSE_LAST) {
+            MouseEvent me = (MouseEvent) this;
+            return converter.convertMouseEvent(me);
+        } else if (id == WindowEvent.WINDOW_CLOSING
+                || id == WindowEvent.WINDOW_ICONIFIED
+                || id == WindowEvent.WINDOW_DEICONIFIED) {
+            //nothing to convert
+        } else {
+            return null;
+        }
+        return new Event(source, id, null);
+    }
+
+
+    /**
+     * The Class EventDescriptor.
+     */
+    static final class EventDescriptor {
+
+        /** The event mask. */
+        final long eventMask;
+
+        /** The listener type. */
+        final Class<? extends EventListener> listenerType;
+
+        /**
+         * Instantiates a new event descriptor.
+         * 
+         * @param eventMask the event mask
+         * @param listenerType the listener type
+         */
+        EventDescriptor(long eventMask, Class<? extends EventListener> listenerType) {
+            this.eventMask = eventMask;
+            this.listenerType = listenerType;
+        }
+
+    }
+    
+    /**
+     * The Class EventTypeLookup.
+     */
+    static final class EventTypeLookup {
+        
+        /** The last event. */
+        private AWTEvent lastEvent = null;
+        
+        /** The last event descriptor. */
+        private EventDescriptor lastEventDescriptor = null;
+
+        /**
+         * Gets the event descriptor.
+         * 
+         * @param event the event
+         * 
+         * @return the event descriptor
+         */
+        EventDescriptor getEventDescriptor(AWTEvent event) {
+            synchronized (this) {
+                if (event != lastEvent) {
+                    lastEvent = event;
+                    lastEventDescriptor = eventsMap.get(new Integer(event.id));
+                }
+
+                return lastEventDescriptor;
+            }
+        }
+
+        /**
+         * Gets the event mask.
+         * 
+         * @param event the event
+         * 
+         * @return the event mask
+         */
+        long getEventMask(AWTEvent event) {
+            final EventDescriptor ed = getEventDescriptor(event);
+            return ed == null ? -1 : ed.eventMask;
+        }
+    }
+
+    /**
+     * The Class EventConverter.
+     */
+    static final class EventConverter {
+        
+        /** The Constant OLD_MOD_MASK. */
+        static final int OLD_MOD_MASK = Event.ALT_MASK | Event.CTRL_MASK
+        | Event.META_MASK | Event.SHIFT_MASK;
+
+        /**
+         * Convert action event.
+         * 
+         * @param ae the ae
+         * 
+         * @return the event
+         */
+        Event convertActionEvent(ActionEvent ae) {
+            Event evt = new Event(ae.getSource(), ae.getID(), ae.getActionCommand());
+            evt.when = ae.getWhen();
+            evt.modifiers = ae.getModifiers() & OLD_MOD_MASK;
+
+           /* if (source instanceof Button) {
+                arg = ((Button) source).getLabel();
+            } else if (source instanceof Checkbox) {
+                arg = new Boolean(((Checkbox) source).getState());
+            } else if (source instanceof CheckboxMenuItem) {
+                arg = ((CheckboxMenuItem) source).getLabel();
+            } else if (source instanceof Choice) {
+                arg = ((Choice) source).getSelectedItem();
+            } else if (source instanceof List) {
+                arg = ((List) source).getSelectedItem();
+            } else if (source instanceof MenuItem) {
+                arg = ((MenuItem) source).getLabel();
+            } else if (source instanceof TextField) {
+                arg = ((TextField) source).getText();
+            }
+*/
+            return evt;
+        }
+
+
+        /**
+         * Convert adjustment event.
+         * 
+         * @param ae the ae
+         * 
+         * @return the event
+         */
+        Event convertAdjustmentEvent(AdjustmentEvent ae) {
+            //TODO: Event.SCROLL_BEGIN/SCROLL_END
+            return new Event(ae.source, ae.id + ae.getAdjustmentType() - 1,
+                    new Integer(ae.getValue()));
+        }
+
+        /**
+         * Convert component event.
+         * 
+         * @param ce the ce
+         * 
+         * @return the event
+         */
+        Event convertComponentEvent(ComponentEvent ce) {
+            Component comp = ce.getComponent();
+            Event evt = new Event(comp, Event.WINDOW_MOVED, null);
+            evt.x = comp.getX();
+            evt.y = comp.getY();
+            return evt;
+        }
+
+        //???AWT
+        /*
+        Event convertItemEvent(ItemEvent ie) {
+            int oldId = ie.id + ie.getStateChange() - 1;
+            Object source = ie.source;
+            int idx = -1;
+            if (source instanceof List) {
+                List list = (List) source;
+                idx = list.getSelectedIndex();
+            }
+            else if (source instanceof Choice) {
+                Choice choice = (Choice) source;
+                idx = choice.getSelectedIndex();
+            }
+            Object arg = idx >= 0 ? new Integer(idx) : null;
+            return new Event(source, oldId, arg);
+        }
+        */
+        
+        /**
+         * Convert key event.
+         * 
+         * @param ke the ke
+         * 
+         * @return the event
+         */
+        Event convertKeyEvent(KeyEvent ke) {
+            int oldId = ke.id;
+            //leave only old Event's modifiers
+
+            int mod = ke.getModifiers() & OLD_MOD_MASK;
+            Component comp = ke.getComponent();
+            char keyChar = ke.getKeyChar();
+            int keyCode = ke.getKeyCode();
+            int key = convertKey(keyChar, keyCode);
+            if (key >= Event.HOME && key <= Event.INSERT) {
+                oldId += 2; //non-ASCII key -> action key
+            }
+            return new Event(comp, ke.getWhen(), oldId, 0, 0, key, mod);
+        }
+
+        /**
+         * Convert mouse event.
+         * 
+         * @param me the me
+         * 
+         * @return the event
+         */
+        Event convertMouseEvent(MouseEvent me) {
+            int id = me.id;
+            if (id != MouseEvent.MOUSE_CLICKED) {
+                Event evt = new Event(me.source, id, null);
+                evt.x = me.getX();
+                evt.y = me.getY();
+                int mod = me.getModifiers();
+                //in Event modifiers mean button number for mouse events:
+                evt.modifiers = mod & (Event.ALT_MASK | Event.META_MASK);
+                if (id == MouseEvent.MOUSE_PRESSED) {
+                    evt.clickCount = me.getClickCount();
+                }
+                return evt;
+            }
+            return null;
+        }
+        
+        /**
+         * Convert key.
+         * 
+         * @param keyChar the key char
+         * @param keyCode the key code
+         * 
+         * @return the int
+         */
+        int convertKey(char keyChar, int keyCode) {
+            int key;
+            //F1 - F12
+            if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
+                key = Event.F1 + keyCode - KeyEvent.VK_F1;
+            } else {
+                switch (keyCode) {
+                default: //non-action key
+                    key = keyChar;
+                    break;
+                //action keys:
+                case KeyEvent.VK_HOME:
+                    key = Event.HOME;
+                    break;
+                case KeyEvent.VK_END:
+                    key = Event.END;
+                    break;
+                case KeyEvent.VK_PAGE_UP:
+                    key = Event.PGUP;
+                    break;
+                case KeyEvent.VK_PAGE_DOWN:
+                    key = Event.PGDN;
+                    break;
+                case KeyEvent.VK_UP:
+                    key = Event.UP;
+                    break;
+                case KeyEvent.VK_DOWN:
+                    key = Event.DOWN;
+                    break;
+                case KeyEvent.VK_LEFT:
+                    key = Event.LEFT;
+                    break;
+                case KeyEvent.VK_RIGHT:
+                    key = Event.RIGHT;
+                    break;
+                case KeyEvent.VK_PRINTSCREEN:
+                    key = Event.PRINT_SCREEN;
+                    break;
+                case KeyEvent.VK_SCROLL_LOCK:
+                    key = Event.SCROLL_LOCK;
+                    break;
+                case KeyEvent.VK_CAPS_LOCK:
+                    key = Event.CAPS_LOCK;
+                    break;
+                case KeyEvent.VK_NUM_LOCK:
+                    key = Event.NUM_LOCK;
+                    break;
+                case KeyEvent.VK_PAUSE:
+                    key = Event.PAUSE;
+                    break;
+                case KeyEvent.VK_INSERT:
+                    key = Event.INSERT;
+                    break;
+                }
+            }
+            return key;
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/AWTException.java b/awt/java/awt/AWTException.java
new file mode 100644
index 0000000..70ce6e1
--- /dev/null
+++ b/awt/java/awt/AWTException.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+
+/**
+ * The AWTException class is used to provide notification and information
+ * about AWT errors.
+ */
+public class AWTException extends Exception {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1900414231151323879L;
+
+    /**
+     * Instantiates a new AWT exception with the specified message.
+     * 
+     * @param msg the specific message for current exception.
+     */
+    public AWTException(String msg) {
+        super(msg);
+    }
+
+}
+
diff --git a/awt/java/awt/AWTKeyStroke.java b/awt/java/awt/AWTKeyStroke.java
new file mode 100644
index 0000000..5e7de4e
--- /dev/null
+++ b/awt/java/awt/AWTKeyStroke.java
@@ -0,0 +1,678 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The AWTKeyStroke holds all of the information for the complete act of 
+ * typing a character. This includes the events that are generated when 
+ * the key is pressed, released, or typed (pressed and released generating
+ * a unicode character result) which are associated with the event
+ * objects KeyEvent.KEY_PRESSED, KeyEvent.KEY_RELEASED, or KeyEvent.KEY_TYPED.
+ * It also holds information about which modifiers (such as control or 
+ * shift) were used in conjunction with the keystroke. The following masks 
+ * are available to identify the modifiers:
+ * <ul>
+ * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_MASK</li>
+ * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+ * <li>java.awt.event.InputEvent.META_MASK</li>  
+ * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+ * </ul>  
+ * <br>
+ *  The AWTKeyStroke is unique, and applications should not create their own 
+ *  instances of AWTKeyStroke. All applications should use getAWTKeyStroke 
+ *  methods for obtaining instances of AWTKeyStroke.
+ */
+public class AWTKeyStroke implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -6430539691155161871L;
+
+    /** The Constant cache. */
+    private static final Map<AWTKeyStroke, AWTKeyStroke> cache = new HashMap<AWTKeyStroke, AWTKeyStroke>(); //Map<AWTKeyStroke, ? extends AWTKeyStroke>
+    
+    /** The Constant keyEventTypesMap. */
+    private static final Map<Integer, String> keyEventTypesMap = new HashMap<Integer, String>(); //Map<int, String>
+
+    private static Constructor<?> subConstructor;   
+
+    static {
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_PRESSED), "pressed"); //$NON-NLS-1$
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_RELEASED), "released"); //$NON-NLS-1$
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_TYPED), "typed"); //$NON-NLS-1$
+    }
+
+    /** The key char. */
+    private char keyChar;
+    
+    /** The key code. */
+    private int keyCode;
+    
+    /** The modifiers. */
+    private int modifiers;
+    
+    /** The on key release. */
+    private boolean onKeyRelease;
+    
+    /**
+     * Instantiates a new AWTKeyStroke. 
+     * getAWTKeyStroke method should be used by applications code.  
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease true if AWTKeyStroke is for a key release, overwise false. 
+     */
+    protected AWTKeyStroke(char keyChar, int keyCode, int modifiers,
+            boolean onKeyRelease)
+    {
+       setAWTKeyStroke(keyChar, keyCode, modifiers, onKeyRelease);
+    }
+
+    /** Sets the awt key stroke.
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease the on key release
+     */
+    private void setAWTKeyStroke( char keyChar, int keyCode, int modifiers,
+            boolean onKeyRelease)
+    {
+        this.keyChar = keyChar;
+        this.keyCode = keyCode;
+        this.modifiers = modifiers;
+        this.onKeyRelease = onKeyRelease;
+    }
+    
+    /**
+     * Instantiates a new AWTKeyStroke with default parameters:
+     * KeyEvent.CHAR_UNDEFINED key char, KeyEvent.VK_UNDEFINED key code,
+     * without modifiers and false key realised value.
+     */
+    protected AWTKeyStroke() {
+        this(KeyEvent.CHAR_UNDEFINED, KeyEvent.VK_UNDEFINED, 0, false);
+    }
+
+    /**
+     * Returns the unique number value for AWTKeyStroke object.
+     * 
+     * @return the int unique value of the AWTKeyStroke object.
+     */
+    @Override
+    public int hashCode() {
+        return modifiers + ( keyCode != KeyEvent.VK_UNDEFINED ?
+                keyCode : keyChar) + (onKeyRelease ? -1 : 0);
+    }
+
+    /**
+     * Gets the set of modifiers for the AWTKeyStroke object.
+     * 
+     * @return the int value which contains modifiers.
+     */
+    public final int getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * Compares the AWTKeyStroke object to the specified object.
+     * 
+     * @return true, if objects are identical, overwise false.
+     */
+    @Override
+    public final boolean equals(Object anObject) {
+        if (anObject instanceof AWTKeyStroke) {
+            AWTKeyStroke key = (AWTKeyStroke)anObject;
+            return ((key.keyCode == keyCode) && (key.keyChar == keyChar) &&
+                    (key.modifiers == modifiers) &&
+                    (key.onKeyRelease == onKeyRelease));
+        }
+        return false;
+    }
+
+    /**
+     * Returns the string representation of the AWTKeyStroke.
+     * This string should contain key stroke properties.
+     * 
+     * @return the string representation of the AWTKeyStroke.
+     */
+    @Override
+    public String toString() {
+        int type = getKeyEventType();
+        return InputEvent.getModifiersExText(getModifiers()) + " " + //$NON-NLS-1$
+            keyEventTypesMap.get(new Integer(type)) +  " " + //$NON-NLS-1$
+            (type == KeyEvent.KEY_TYPED ? new String(new char[] {keyChar}) :
+                                          KeyEvent.getKeyText(keyCode));
+    }
+
+    /**
+     * Gets the key code for the AWTKeyStroke object.
+     * 
+     * @return the key code for the AWTKeyStroke object.
+     */
+    public final int getKeyCode() {
+        return keyCode;
+    }
+
+    /**
+     * Gets the key character for the AWTKeyStroke object.
+     * 
+     * @return the key character for the AWTKeyStroke object.
+     */
+    public final char getKeyChar() {
+        return keyChar;
+    }
+
+    /**
+     * Gets the AWT key stroke.
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease the on key release
+     * 
+     * @return the AWT key stroke
+     */
+    private static AWTKeyStroke getAWTKeyStroke(char keyChar, int keyCode,
+                                                int modifiers,
+                                                boolean onKeyRelease) {
+        AWTKeyStroke key = newInstance(keyChar, keyCode, modifiers, onKeyRelease);
+
+        AWTKeyStroke value = cache.get(key);
+        if (value == null) {
+            value = key;
+            cache.put(key, value);
+        }
+        return value;
+    }
+
+    /**
+     * New instance.
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease the on key release
+     * 
+     * @return the AWT key stroke
+     */
+    private static AWTKeyStroke newInstance(char keyChar, int keyCode,
+                                            int modifiers,
+                                            boolean onKeyRelease) {
+        AWTKeyStroke key;
+        //???AWT
+//        if (subConstructor == null) {
+            key = new AWTKeyStroke();
+        //???AWT
+//        } else {
+//            try {
+//                key = (AWTKeyStroke) subConstructor.newInstance();
+//            } catch (Exception e) {
+//                throw new RuntimeException(e);
+//            }
+//        }
+        int allModifiers = getAllModifiers(modifiers);
+        key.setAWTKeyStroke(keyChar, keyCode, allModifiers, onKeyRelease);
+        return key;
+    }
+
+    /**
+     * Adds the mask.
+     * 
+     * @param mod the mod
+     * @param mask the mask
+     * 
+     * @return the int
+     */
+    private static int addMask(int mod, int mask) {
+        return ((mod & mask) != 0) ? (mod | mask) : mod;
+    }
+
+    /**
+     * return all (old & new) modifiers corresponding to.
+     * 
+     * @param mod old or new modifiers
+     * 
+     * @return old and new modifiers together
+     */
+    static int getAllModifiers(int mod) {
+        int allMod = mod;
+        int shift = (InputEvent.SHIFT_MASK | InputEvent.SHIFT_DOWN_MASK);
+        int ctrl = (InputEvent.CTRL_MASK | InputEvent.CTRL_DOWN_MASK);
+        int meta = (InputEvent.META_MASK | InputEvent.META_DOWN_MASK);
+        int alt = (InputEvent.ALT_MASK | InputEvent.ALT_DOWN_MASK);
+        int altGr = (InputEvent.ALT_GRAPH_MASK | InputEvent.ALT_GRAPH_DOWN_MASK);
+        // button modifiers are not converted between old & new
+
+        allMod = addMask(allMod, shift);
+        allMod = addMask(allMod, ctrl);
+        allMod = addMask(allMod, meta);
+        allMod = addMask(allMod, alt);
+        allMod = addMask(allMod, altGr);
+
+        return allMod;
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for parsed string.
+     * 
+     * The string must have the following syntax:
+     *<p>
+     * &lt;modifiers&gt;* (&lt;typedID&gt; | &lt;pressedReleasedID&gt;)
+     *<p>
+     * modifiers := shift | control | ctrl | meta | alt | altGraph
+     * <br> 
+     * typedID := typed <typedKey>
+     * <br>
+     * typedKey := string of length 1 giving the Unicode character.
+     * <br>
+     * pressedReleasedID := (pressed | released) <key>
+     * <br>
+     * key := KeyEvent key code name, i.e. the name following "VK_".
+     * <p>
+     * @param s the String which contains key stroke parameters.
+     * 
+     * @return the AWTKeyStroke for string.
+     * 
+     * @throws IllegalArgumentException if string has incorrect format or null.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(String s) {
+        if (s == null) {
+            // awt.65=null argument
+            throw new IllegalArgumentException(Messages.getString("awt.65")); //$NON-NLS-1$
+        }
+
+        StringTokenizer tokenizer = new StringTokenizer(s);
+
+        Boolean release = null;
+        int modifiers = 0;
+        int keyCode = KeyEvent.VK_UNDEFINED;
+        char keyChar = KeyEvent.CHAR_UNDEFINED;
+        boolean typed = false;
+        long modifier = 0;
+        String token = null;
+        do {
+            token = getNextToken(tokenizer);
+            modifier = parseModifier(token);
+            modifiers |= modifier;
+        } while (modifier > 0);
+
+        typed = parseTypedID(token);
+
+        if (typed) {
+            token = getNextToken(tokenizer);
+            keyChar = parseTypedKey(token);
+
+        }
+        if (keyChar == KeyEvent.CHAR_UNDEFINED) {
+            release = parsePressedReleasedID(token);
+            if (release != null) {
+                token = getNextToken(tokenizer);
+            }
+            keyCode = parseKey(token);
+        }
+        if (tokenizer.hasMoreTokens()) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+
+        return getAWTKeyStroke(keyChar, keyCode, modifiers,
+                               release == Boolean.TRUE);
+    }
+
+    /**
+     * Gets the next token.
+     * 
+     * @param tokenizer the tokenizer
+     * 
+     * @return the next token
+     */
+    private static String getNextToken(StringTokenizer tokenizer) {
+        try {
+            return tokenizer.nextToken();
+        } catch (NoSuchElementException exception) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Gets the key code.
+     * 
+     * @param s the s
+     * 
+     * @return the key code
+     */
+    static int getKeyCode(String s) {
+        try {
+            Field vk = KeyEvent.class.getField("VK_" + s); //$NON-NLS-1$
+            return vk.getInt(null);
+        } catch (Exception e) {
+            if (s.length() != 1) {
+                // awt.66=Invalid format
+                throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+            }
+            return KeyEvent.VK_UNDEFINED;
+        }
+    }
+
+    /**
+     * Gets an instance of the AWTKeyStroke for specified character.
+     * 
+     * @param keyChar the keyboard character value.
+     * 
+     * @return a AWTKeyStroke for specified character.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(char keyChar) {
+        return getAWTKeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for a given key code, set 
+     * of modifiers, and specified key released flag value.
+     * The key codes are defined in java.awt.event.KeyEvent class. 
+     * The set of modifiers is given as a bitwise combination 
+     * of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+     * <li>java.awt.event.InputEvent.META_MASK</li>  
+     * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     *  <br>
+     *  
+     * @param keyCode the specified key code of keyboard.
+     * @param modifiers the bit set of modifiers.
+     * 
+     * @return the AWTKeyStroke.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers,
+                                               boolean onKeyRelease) {
+        return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers,
+                               onKeyRelease);
+    }
+
+    /**
+     * Returns AWTKeyStroke for a specified character and set of modifiers. 
+     * The set of modifiers is given as a bitwise combination 
+     * of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+     * <li>java.awt.event.InputEvent.META_MASK</li>  
+     * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     * 
+     * @param keyChar the Character object which represents keyboard character value.
+     * @param modifiers the bit set of modifiers.
+     * 
+     * @return the AWTKeyStroke object.
+     * 
+     * @throws IllegalArgumentException if keyChar value is null.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers) {
+        if (keyChar == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "keyChar")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        return getAWTKeyStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED,
+                               modifiers, false);
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for a specified key code and 
+     * set of modifiers.
+     * The key codes are defined in java.awt.event.KeyEvent class. 
+     * The set of modifiers is given as a bitwise combination 
+     * of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+     * <li>java.awt.event.InputEvent.META_MASK</li>  
+     * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     *  
+     * @param keyCode the specified key code of keyboard.
+     * @param modifiers the bit set of modifiers.
+     * 
+     * @return the AWTKeyStroke
+     */
+    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers) {
+        return getAWTKeyStroke(keyCode, modifiers, false);
+    }
+
+    /**
+     * Gets the AWTKeyStroke for a key event. This method obtains the key char 
+     * and key code from the specified key event.
+     * 
+     * @param anEvent the key event which identifies the desired AWTKeyStroke.
+     * 
+     * @return the AWTKeyStroke for the key event.
+     */
+    public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent anEvent) {
+        int id = anEvent.getID();
+        char undef = KeyEvent.CHAR_UNDEFINED;
+        char keyChar = (id == KeyEvent.KEY_TYPED ? anEvent.getKeyChar() :
+                                                   undef);
+        int keyCode = (keyChar == undef ? anEvent.getKeyCode() :
+                                          KeyEvent.VK_UNDEFINED);
+        return getAWTKeyStroke(keyChar, keyCode, anEvent.getModifiersEx(),
+                               id == KeyEvent.KEY_RELEASED);
+    }
+
+    /**
+     * Gets the key event type for the AWTKeyStroke object.
+     * 
+     * @return the key event type: KeyEvent.KEY_PRESSED, KeyEvent.KEY_TYPED, or KeyEvent.KEY_RELEASED
+     */
+    public final int getKeyEventType() {
+        if (keyCode == KeyEvent.VK_UNDEFINED) {
+            return KeyEvent.KEY_TYPED;
+        }
+        return (onKeyRelease ? KeyEvent.KEY_RELEASED : KeyEvent.KEY_PRESSED);
+    }
+
+    /**
+     * Retuns true if the key event is associated with the AWTKeyStroke is 
+     * KEY_RELEASED, overwise false.
+     * 
+     * @return true, if if the key event associated with the AWTKeyStroke is 
+     * KEY_RELEASED, overwise false.
+     */
+    public final boolean isOnKeyRelease() {
+        return onKeyRelease;
+    }
+
+    /**
+     * Read resolve.
+     * 
+     * @return the object
+     * 
+     * @throws ObjectStreamException the object stream exception
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        return getAWTKeyStroke(this.keyChar, this.keyCode,
+                               this.modifiers, this.onKeyRelease);
+    }
+
+    /**
+     * Register subclass.
+     * 
+     * @param subclass the subclass
+     */
+    protected static void registerSubclass(Class<?> subclass) {
+        //???AWT
+        /*
+        if (subclass == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "subclass")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if (! AWTKeyStroke.class.isAssignableFrom(subclass)) {
+            // awt.67=subclass is not derived from AWTKeyStroke
+            throw new ClassCastException(Messages.getString("awt.67")); //$NON-NLS-1$
+        }
+        try {
+            subConstructor = subclass.getDeclaredConstructor();
+            subConstructor.setAccessible(true);
+        } catch (SecurityException e) {
+            throw new RuntimeException(e);
+        } catch (NoSuchMethodException e) {
+            // awt.68=subclass could not be instantiated
+            throw new IllegalArgumentException(Messages.getString("awt.68")); //$NON-NLS-1$
+        }
+        cache.clear(); //flush the cache
+        */
+    }
+
+    /**
+     * Parses the modifier.
+     * 
+     * @param strMod the str mod
+     * 
+     * @return the long
+     */
+    private static long parseModifier(String strMod) {
+        long modifiers = 0l;
+        if (strMod.equals("shift")) { //$NON-NLS-1$
+            modifiers |= InputEvent.SHIFT_DOWN_MASK;
+        } else if (strMod.equals("control") || strMod.equals("ctrl")) { //$NON-NLS-1$ //$NON-NLS-2$
+            modifiers |= InputEvent.CTRL_DOWN_MASK;
+        } else if (strMod.equals("meta")) { //$NON-NLS-1$
+            modifiers |= InputEvent.META_DOWN_MASK;
+        } else if (strMod.equals("alt")) { //$NON-NLS-1$
+            modifiers |= InputEvent.ALT_DOWN_MASK;
+        } else if (strMod.equals("altGraph")) { //$NON-NLS-1$
+            modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
+        } else if (strMod.equals("button1")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON1_DOWN_MASK;
+        } else if (strMod.equals("button2")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON2_DOWN_MASK;
+        } else if (strMod.equals("button3")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON3_DOWN_MASK;
+        }
+        return modifiers;
+    }
+
+    /**
+     * Parses the typed id.
+     * 
+     * @param strTyped the str typed
+     * 
+     * @return true, if successful
+     */
+    private static boolean parseTypedID(String strTyped) {
+        if (strTyped.equals("typed")) { //$NON-NLS-1$
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parses the typed key.
+     * 
+     * @param strChar the str char
+     * 
+     * @return the char
+     */
+    private static char parseTypedKey(String strChar) {
+        char keyChar = KeyEvent.CHAR_UNDEFINED;
+
+        if (strChar.length() != 1) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+        keyChar = strChar.charAt(0);
+        return keyChar;
+    }
+
+    /**
+     * Parses the pressed released id.
+     * 
+     * @param str the str
+     * 
+     * @return the boolean
+     */
+    private static Boolean parsePressedReleasedID(String str) {
+
+        if (str.equals("pressed")) { //$NON-NLS-1$
+            return Boolean.FALSE;
+        } else if (str.equals("released")) { //$NON-NLS-1$
+            return Boolean.TRUE;
+        }
+        return null;
+    }
+
+    /**
+     * Parses the key.
+     * 
+     * @param strCode the str code
+     * 
+     * @return the int
+     */
+    private static int parseKey(String strCode) {
+        int keyCode = KeyEvent.VK_UNDEFINED;
+
+        keyCode = getKeyCode(strCode);
+
+        if (keyCode == KeyEvent.VK_UNDEFINED) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+        return keyCode;
+    }
+}
+
diff --git a/awt/java/awt/AWTListenerList.java b/awt/java/awt/AWTListenerList.java
new file mode 100644
index 0000000..3327d63
--- /dev/null
+++ b/awt/java/awt/AWTListenerList.java
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.util.EventListener;
+
+import org.apache.harmony.awt.ListenerList;
+
+final class AWTListenerList<T extends EventListener> extends ListenerList<T> {
+    private static final long serialVersionUID = -2622077171532840953L;
+
+    private final Component owner;
+    
+    AWTListenerList() {
+        super();
+        this.owner = null;
+    }
+
+    AWTListenerList(Component owner) {
+        super();
+        this.owner = owner;
+    }
+
+    @Override
+    public void addUserListener(T listener) {
+        super.addUserListener(listener);
+
+        if (owner != null) {
+            owner.deprecatedEventHandler = false;
+        }
+    }
+}
diff --git a/awt/java/awt/AWTPermission.java b/awt/java/awt/AWTPermission.java
new file mode 100644
index 0000000..25326ab
--- /dev/null
+++ b/awt/java/awt/AWTPermission.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.security.BasicPermission;
+
+/**
+ * The AWTPermission specifies the name of the permission and the 
+ * corresponding action list.
+ */
+public final class AWTPermission extends BasicPermission {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8890392402588814465L;
+
+    /**
+     * Instantiates a new AWTPermission with defined name and actions.
+     * 
+     * @param name the name of a new AWTPermission. 
+     * @param actions the actions of a new AWTPermission.
+     */
+    public AWTPermission(String name, String actions) {
+        super(name, actions);
+    }
+
+    /**
+     * Instantiates a new AWT permission with the defined name.
+     * 
+     * @param name the name of a new AWTPermission. 
+     */
+    public AWTPermission(String name) {
+        super(name);
+    }
+
+}
+
diff --git a/awt/java/awt/ActiveEvent.java b/awt/java/awt/ActiveEvent.java
new file mode 100644
index 0000000..4133752
--- /dev/null
+++ b/awt/java/awt/ActiveEvent.java
@@ -0,0 +1,36 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * This interface defines events that know how to dispatch themselves. 
+ * Such event can be placed upon the event queue and its dispatch method 
+ * will be called when the event is dispatched.
+ */
+public interface ActiveEvent {
+
+    /**
+     * Dispatches the event to the listeners of the event's source, 
+     * or does whatever it is this event is supposed to do.
+     */
+    public void dispatch();
+
+}
diff --git a/awt/java/awt/Adjustable.java b/awt/java/awt/Adjustable.java
new file mode 100644
index 0000000..3241cad
--- /dev/null
+++ b/awt/java/awt/Adjustable.java
@@ -0,0 +1,156 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.AdjustmentListener;
+
+/**
+ * The Adjustable interface represents an adjustable numeric value 
+ * contained within a bounded range of values, such as the current 
+ * location in scrollable region or the value of a gauge.
+ */
+public interface Adjustable {
+
+    /** 
+     * The Constant HORIZONTAL indicates that the Adjustable's orientation 
+     * is horizontal. 
+     */
+    public static final int HORIZONTAL = 0;
+
+    /** 
+     * The Constant VERTICAL indicates that the Adjustable's orientation 
+     * is vertical. 
+     */
+    public static final int VERTICAL = 1;
+
+    /** 
+     * The Constant NO_ORIENTATION indicates that the Adjustable 
+     * has no orientation.
+     */
+    public static final int NO_ORIENTATION = 2;
+
+    /**
+     * Gets the value of the Adjustable.
+     * 
+     * @return the current value of the Adjustable.
+     */
+    public int getValue();
+
+    /**
+     * Sets the value to the Adjustable object.
+     * 
+     * @param a0 the new value of the Adjustable object. 
+     */
+    public void setValue(int a0);
+
+    /**
+     * Adds the AdjustmentListener to current Adjustment.
+     * 
+     * @param a0 the AdjustmentListener object.
+     */
+    public void addAdjustmentListener(AdjustmentListener a0);
+
+    /**
+     * Gets the block increment of the Adjustable.
+     * 
+     * @return the block increment of the Adjustable.
+     */
+    public int getBlockIncrement();
+
+    /**
+     * Gets the maximum value of the Adjustable.
+     * 
+     * @return the maximum value of the Adjustable.
+     */
+    public int getMaximum();
+
+    /**
+     * Gets the minimum value of the Adjustable.
+     * 
+     * @return the minimum value of the Adjustable. 
+     */
+    public int getMinimum();
+
+    /**
+     * Gets the orientation of the Adjustable.
+     * 
+     * @return the orientation of the Adjustable.
+     */
+    public int getOrientation();
+
+    /**
+     * Gets the unit increment of the Adjustable.
+     * 
+     * @return the unit increment of the Adjustable.
+     */
+    public int getUnitIncrement();
+
+    /**
+     * Gets the visible amount of the Adjustable.
+     * 
+     * @return the visible amount of the Adjustable.
+     */
+    public int getVisibleAmount();
+
+    /**
+     * Removes the adjustment listener of the Adjustable.
+     * 
+     * @param a0 the specified AdjustmentListener to be removed.
+     */
+    public void removeAdjustmentListener(AdjustmentListener a0);
+
+    /**
+     * Sets the block increment for the Adjustable.
+     * 
+     * @param a0 the new block increment.
+     */
+    public void setBlockIncrement(int a0);
+
+    /**
+     * Sets the maximum value of the Adjustable.
+     * 
+     * @param a0 the new maximum of the Adjustable.
+     */
+    public void setMaximum(int a0);
+
+    /**
+     * Sets the minimum value of the Adjustable.
+     * 
+     * @param a0 the new minimum of the Adjustable.
+     */
+    public void setMinimum(int a0);
+
+    /**
+     * Sets the unit increment of the Adjustable.
+     * 
+     * @param a0 the new unit increment of the Adjustable.
+     */
+    public void setUnitIncrement(int a0);
+
+    /**
+     * Sets the visible amount of the Adjustable.
+     * 
+     * @param a0 the new visible amount of the Adjustable.
+     */
+    public void setVisibleAmount(int a0);
+
+}
+
diff --git a/awt/java/awt/AlphaComposite.java b/awt/java/awt/AlphaComposite.java
new file mode 100644
index 0000000..d26753c
--- /dev/null
+++ b/awt/java/awt/AlphaComposite.java
@@ -0,0 +1,315 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.RenderingHints;
+import java.awt.image.ColorModel;
+
+import org.apache.harmony.awt.gl.ICompositeContext;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * The AlphaComposite class defines a basic alpha compositing rules for 
+ * combining source and destination colors to achieve blending and 
+ * transparency effects with graphics and images.
+ */
+public final class AlphaComposite implements Composite {
+
+    /** 
+     * The Constant CLEAR indicates that both the color and the alpha of 
+     * the destination are cleared (Porter-Duff Clear rule).
+     */
+    public static final int CLEAR = 1;
+
+    /** 
+     * The Constant SRC indicates that the source is copied to the destination 
+     * (Porter-Duff Source rule).
+     */
+    public static final int SRC = 2;
+
+    /** The Constant DST indicates that the destination is left untouched 
+     * (Porter-Duff Destination rule).
+     */
+    public static final int DST = 9;
+
+    /** 
+     * The Constant SRC_OVER indicates that the source is composited over 
+     * the destination (Porter-Duff Source Over Destination rule).
+     */
+    public static final int SRC_OVER = 3;
+
+    /**
+     * The Constant DST_OVER indicates that The destination is composited over 
+     * the source and the result replaces the destination 
+     * (Porter-Duff Destination Over Source rule).
+     */
+    public static final int DST_OVER = 4;
+
+    /**
+     * The Constant SRC_IN indicates that the part of the source lying 
+     * inside of the destination replaces the destination (Porter-Duff 
+     * Source In Destination rule).
+     */
+    public static final int SRC_IN = 5;
+
+    /** 
+     * The Constant DST_IN indicates that the part of the destination 
+     * lying inside of the source replaces the destination 
+     * (Porter-Duff Destination In Source rule).
+     */
+    public static final int DST_IN = 6;
+
+    /**
+     * The Constant SRC_OUT indicates that the part of the source lying 
+     * outside of the destination replaces the destination (Porter-Duff 
+     * Source Held Out By Destination rule).
+     */
+    public static final int SRC_OUT = 7;
+
+    /** 
+     * The Constant DST_OUT indicates that the part of the destination 
+     * lying outside of the source replaces the destination (Porter-Duff 
+     * Destination Held Out By Source rule).
+     */
+    public static final int DST_OUT = 8;
+
+    /** 
+     * The Constant SRC_ATOP indicates that the part of the source lying 
+     * inside of the destination is composited onto the destination 
+     * (Porter-Duff Source Atop Destination rule).
+     */
+    public static final int SRC_ATOP = 10;
+
+    /** 
+     * The Constant DST_ATOP indicates that the part of the destination 
+     * lying inside of the source is composited over the source and replaces 
+     * the destination (Porter-Duff Destination Atop Source rule).
+     */
+    public static final int DST_ATOP = 11;
+
+    /**
+     * The Constant XOR indicates that the part of the source that lies 
+     * outside of the destination is combined with the part of the destination 
+     * that lies outside of the source (Porter-Duff Source Xor Destination rule).
+     */
+    public static final int XOR = 12;
+
+    /** AlphaComposite object with the opaque CLEAR rule and an alpha of 1.0f. */
+    public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
+
+    /** AlphaComposite object with the opaque SRC rule and an alpha of 1.0f. */
+    public static final AlphaComposite Src = new AlphaComposite(SRC);
+
+    /** AlphaComposite object with the opaque DST rule and an alpha of 1.0f. */
+    public static final AlphaComposite Dst = new AlphaComposite(DST);
+
+    /** AlphaComposite object with the opaque SRC_OVER rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcOver = new AlphaComposite(SRC_OVER);
+
+    /** AlphaComposite object with the opaque DST_OVER rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstOver = new AlphaComposite(DST_OVER);
+
+    /** AlphaComposite object with the opaque SRC_IN rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcIn = new AlphaComposite(SRC_IN);
+
+    /** AlphaComposite object with the opaque DST_IN rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstIn = new AlphaComposite(DST_IN);
+
+    /** AlphaComposite object with the opaque SRC_OUT rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcOut = new AlphaComposite(SRC_OUT);
+
+    /** AlphaComposite object with the opaque DST_OUT rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstOut = new AlphaComposite(DST_OUT);
+
+    /** AlphaComposite object with the opaque SRC_ATOP rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcAtop = new AlphaComposite(SRC_ATOP);
+
+    /** AlphaComposite object with the opaque DST_ATOP rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstAtop = new AlphaComposite(DST_ATOP);
+
+    /** AlphaComposite object with the opaque XOR rule and an alpha of 1.0f. */
+    public static final AlphaComposite Xor = new AlphaComposite(XOR);
+
+    /** The rule. */
+    private int rule;
+    
+    /** The alpha. */
+    private float alpha;
+
+    /**
+     * Instantiates a new alpha composite.
+     * Creates a context for the compositing operation. The context contains state that is used in performing the compositing operation.
+     * 
+     * @param rule the rule
+     * @param alpha the alpha
+     */
+    private AlphaComposite(int rule, float alpha){
+        if(rule < CLEAR || rule > XOR) {
+            // awt.11D=Unknown rule
+            throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
+        }
+        if(alpha < 0.0f || alpha > 1.0f) {
+            // awt.11E=Wrong alpha value
+            throw new IllegalArgumentException(Messages.getString("awt.11E")); //$NON-NLS-1$
+        }
+
+        this.rule = rule;
+        this.alpha = alpha;
+    }
+
+    /**
+     * Instantiates a new alpha composite.
+     * 
+     * @param rule the rule
+     */
+    private AlphaComposite(int rule){
+        this(rule, 1.0f);
+    }
+
+    /**
+     * Creates a CompositeContext object with the specified source ColorModel,
+     * destination ColorModel and RenderingHints parameters for a composing 
+     * operation.
+     * 
+     * @param srcColorModel the source's ColorModel.
+     * @param dstColorModel the destination's ColorModel.
+     * @param hints the RenderingHints object.
+     * 
+     * @return the CompositeContext object.    
+     * 
+     * @see java.awt.Composite#createContext(java.awt.image.ColorModel, java.awt.image.ColorModel, java.awt.RenderingHints)
+     */
+    public CompositeContext createContext(ColorModel srcColorModel,
+            ColorModel dstColorModel, RenderingHints hints) {
+        return new ICompositeContext(this, srcColorModel, dstColorModel);
+    }
+
+    /**
+     * Compares the AlphaComposite object with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the AlphaComposite object is equal to the specified
+     * object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if(!(obj instanceof AlphaComposite)) {
+            return false;
+        }
+        AlphaComposite other = (AlphaComposite)obj;
+        return (this.rule == other.getRule() && this.alpha == other.getAlpha());
+    }
+
+    /**
+     * Returns the hash code of the AlphaComposite object.
+     * 
+     * @return the hash code of the AlphaComposite object.
+     */
+    @Override
+    public int hashCode() {
+        int hash = Float.floatToIntBits(alpha);
+        int tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= rule;
+        return hash;
+    }
+
+    /**
+     * Gets the compositing rule of this AlphaComposite object.
+     * 
+     * @return the compositing rule of this AlphaComposite object.
+     */
+    public int getRule() {
+        return rule;
+    }
+
+    /**
+     * Gets the alpha value of this AlphaComposite object; returns 1.0 if 
+     * this AlphaComposite object doesn't have alpha value.
+     * 
+     * @return the alpha value of this AlphaComposite object or 1.0 if 
+     * this AlphaComposite object doesn't have alpha value.
+     */
+    public float getAlpha() {
+        return alpha;
+    }
+
+    /**
+     * Gets the AlphaComposite instance with the specified rule and alpha value.
+     * 
+     * @param rule the compositing rule.
+     * @param alpha the alpha value.
+     * 
+     * @return AlphaComposite instance.
+     */
+    public static AlphaComposite getInstance(int rule, float alpha) {
+        if(alpha == 1.0f) {
+            return getInstance(rule);
+        }
+        return new AlphaComposite(rule, alpha);
+    }
+
+    /**
+     * Gets the AlphaComposite instance with the specified rule.
+     * 
+     * @param rule the compositing rule.
+     * 
+     * @return AlphaComposite instance.
+     */
+    public static AlphaComposite getInstance(int rule) {
+        switch(rule){
+        case CLEAR:
+            return Clear;
+        case SRC:
+            return Src;
+        case DST:
+            return Dst;
+        case SRC_OVER:
+            return SrcOver;
+        case DST_OVER:
+            return DstOver;
+        case SRC_IN:
+            return SrcIn;
+        case DST_IN:
+            return DstIn;
+        case SRC_OUT:
+            return SrcOut;
+        case DST_OUT:
+            return DstOut;
+        case SRC_ATOP:
+            return SrcAtop;
+        case DST_ATOP:
+            return DstAtop;
+        case XOR:
+            return Xor;
+        default:
+            // awt.11D=Unknown rule
+            throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/BasicStroke.java b/awt/java/awt/BasicStroke.java
new file mode 100644
index 0000000..955dc6b
--- /dev/null
+++ b/awt/java/awt/BasicStroke.java
@@ -0,0 +1,2204 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The BasicStroke class specifies a set of rendering attributes for the outlines 
+ * of graphics primitives. The BasicStroke attributes describe the shape of the 
+ * pen which draws the outline of a Shape and the decorations applied at the ends
+ * and joins of path segments of the Shape. The BasicStroke has the following
+ * rendering attributes:
+ * <p>
+ * <ul>
+ * <li> line width -the pen width which draws the outlines.</li>
+ * <li> end caps - indicates the decoration applied to the ends of unclosed 
+ * subpaths and dash segments. The BasicStroke defines three different decorations:
+ * CAP_BUTT, CAP_ROUND, and CAP_SQUARE.</li>
+ * <li>line joins - indicates the decoration applied at the intersection of 
+ * two path segments and at the intersection of the endpoints of a subpath.
+ * The BasicStroke defines three decorations: JOIN_BEVEL, JOIN_MITER, 
+ * and JOIN_ROUND.</li>
+ * <li>miter limit - the limit to trim a line join that has a JOIN_MITER 
+ * decoration.</li>
+ * <li>dash attributes - the definition of how to make a dash pattern by 
+ * alternating between opaque and transparent sections </li>
+ * </ul>
+ */
+public class BasicStroke implements Stroke {
+
+    /** 
+     * The Constant CAP_BUTT indicates the ends of unclosed subpaths 
+     * and dash segments have no added decoration.
+     */
+    public static final int CAP_BUTT = 0;
+    
+    /** 
+     * The Constant CAP_ROUND indicates the ends of unclosed subpaths 
+     * and dash segments have a round decoration.
+     */
+    public static final int CAP_ROUND = 1;
+    
+    /** 
+     * The Constant CAP_SQUARE indicates the ends of unclosed subpaths 
+     * and dash segments have a square projection.
+     */
+    public static final int CAP_SQUARE = 2;
+
+    /** 
+     * The Constant JOIN_MITER indicates that path segments are joined by 
+     * extending their outside edges until they meet.
+     */
+    public static final int JOIN_MITER = 0;
+    
+    /** 
+     * The Constant JOIN_ROUND indicates that path segments are joined by 
+     * rounding off the corner at a radius of half the line width.
+     */
+    public static final int JOIN_ROUND = 1;
+    
+    /** 
+     * The Constant JOIN_BEVEL indicates that path segments are joined by 
+     * connecting the outer corners of their wide outlines with 
+     * a straight segment.
+     */
+    public static final int JOIN_BEVEL = 2;
+    
+    /** Constants for calculating. */
+    static final int MAX_LEVEL = 20;        // Maximal deepness of curve subdivision
+    
+    /** The Constant CURVE_DELTA. */
+    static final double CURVE_DELTA = 2.0;  // Width tolerance
+    
+    /** The Constant CORNER_ANGLE. */
+    static final double CORNER_ANGLE = 4.0; // Minimum corner angle
+    
+    /** The Constant CORNER_ZERO. */
+    static final double CORNER_ZERO = 0.01; // Zero angle
+    
+    /** The Constant CUBIC_ARC. */
+    static final double CUBIC_ARC = 4.0 / 3.0 * (Math.sqrt(2.0) - 1);
+
+    /** Stroke width. */
+    float width;
+    
+    /** Stroke cap type. */
+    int cap;
+    
+    /** Stroke join type. */
+    int join;
+    
+    /** Stroke miter limit. */
+    float miterLimit;
+    
+    /** Stroke dashes array. */
+    float dash[];
+    
+    /** Stroke dash phase. */
+    float dashPhase;
+
+    /** The temporary pre-calculated values. */
+    double curveDelta;
+    
+    /** The corner delta. */
+    double cornerDelta;
+    
+    /** The zero delta. */
+    double zeroDelta;
+
+    /** The w2. */
+    double w2;
+    
+    /** The fmy. */
+    double fmx, fmy;
+    
+    /** The smy. */
+    double scx, scy, smx, smy;
+    
+    /** The cy. */
+    double mx, my, cx, cy;
+
+    /** The temporary indicators. */
+    boolean isMove;
+    
+    /** The is first. */
+    boolean isFirst;
+    
+    /** The check move. */
+    boolean checkMove;
+    
+    /** The temporary and destination work paths. */
+    BufferedPath dst, lp, rp, sp;
+    
+    /** Stroke dasher class. */
+    Dasher dasher;
+
+    /**
+     * Instantiates a new BasicStroke with default width, cap, join, limit,
+     * dash attributes parameters. The default parameters are a solid line of 
+     * width 1.0, CAP_SQUARE, JOIN_MITER, a miter limit of 10.0, null dash attributes,
+     * and a dash phase of 0.0f.
+     */
+    public BasicStroke() {
+        this(1.0f, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with the specified width,  
+     * caps, joins, limit, dash attributes, dash phase parameters.
+     * 
+     * @param width the width of BasikStroke.
+     * @param cap the end decoration of BasikStroke.
+     * @param join the join segments decoration.
+     * @param miterLimit the limit to trim the miter join.
+     * @param dash the array with the dashing pattern.
+     * @param dashPhase the offset to start the dashing pattern.
+     */
+    public BasicStroke(float width, int cap, int join, float miterLimit, float[] dash, float dashPhase) {
+        if (width < 0.0f) {
+            // awt.133=Negative width
+            throw new IllegalArgumentException(Messages.getString("awt.133")); //$NON-NLS-1$
+        }
+        if (cap != CAP_BUTT && cap != CAP_ROUND && cap != CAP_SQUARE) {
+            // awt.134=Illegal cap
+            throw new IllegalArgumentException(Messages.getString("awt.134")); //$NON-NLS-1$
+        }
+        if (join != JOIN_MITER && join != JOIN_ROUND && join != JOIN_BEVEL) {
+            // awt.135=Illegal join
+            throw new IllegalArgumentException(Messages.getString("awt.135")); //$NON-NLS-1$
+        }
+        if (join == JOIN_MITER && miterLimit < 1.0f) {
+            // awt.136=miterLimit less than 1.0f
+            throw new IllegalArgumentException(Messages.getString("awt.136")); //$NON-NLS-1$
+        }
+        if (dash != null) {
+            if (dashPhase < 0.0f) {
+                // awt.137=Negative dashPhase
+                throw new IllegalArgumentException(Messages.getString("awt.137")); //$NON-NLS-1$
+            }
+            if (dash.length == 0) {
+                // awt.138=Zero dash length
+                throw new IllegalArgumentException(Messages.getString("awt.138")); //$NON-NLS-1$
+            }
+            ZERO: {
+                for(int i = 0; i < dash.length; i++) {
+                    if (dash[i] < 0.0) {
+                        // awt.139=Negative dash[{0}]
+                        throw new IllegalArgumentException(Messages.getString("awt.139", i)); //$NON-NLS-1$
+                    }
+                    if (dash[i] > 0.0) {
+                        break ZERO;
+                    }
+                }
+                // awt.13A=All dash lengths zero
+                throw new IllegalArgumentException(Messages.getString("awt.13A")); //$NON-NLS-1$
+            }
+        }
+        this.width = width;
+        this.cap = cap;
+        this.join = join;
+        this.miterLimit = miterLimit;
+        this.dash = dash;
+        this.dashPhase = dashPhase;
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width, cap, join, limit
+     * and default dash attributes parameters. 
+     * 
+     * @param width the width of BasikStroke.
+     * @param cap the end decoration of BasikStroke.
+     * @param join the join segments decoration.
+     * @param miterLimit the limit to trim the miter join.
+     */
+    public BasicStroke(float width, int cap, int join, float miterLimit) {
+        this(width, cap, join, miterLimit, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width, cap, join
+     * and default limit and dash attributes parameters. 
+     * 
+     * @param width the width of BasikStroke.
+     * @param cap the end decoration of BasikStroke.
+     * @param join the join segments decoration.
+     */
+    public BasicStroke(float width, int cap, int join) {
+        this(width, cap, join, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width and default cap, join,
+     * limit, dash attributes parameters.
+     * 
+     * @param width the width of BasicStroke.
+     */
+    public BasicStroke(float width) {
+        this(width, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Gets the line width of the BasicStroke.
+     * 
+     * @return the line width of the BasicStroke.
+     */
+    public float getLineWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the end cap style of the BasicStroke.
+     * 
+     * @return the end cap style of the BasicStroke.
+     */
+    public int getEndCap() {
+        return cap;
+    }
+
+    /**
+     * Gets the line join style of the BasicStroke.
+     * 
+     * @return the line join style of the BasicStroke.
+     */
+    public int getLineJoin() {
+        return join;
+    }
+
+    /**
+     * Gets the miter limit of the BasicStroke (the limit to trim the miter join).
+     * 
+     * @return the miter limit of the BasicStroke.
+     */
+    public float getMiterLimit() {
+        return miterLimit;
+    }
+
+    /**
+     * Gets the dash attributes array of the BasicStroke.
+     * 
+     * @return the dash attributes array of the BasicStroke.
+     */
+    public float[] getDashArray() {
+        return dash;
+    }
+
+    /**
+     * Gets the dash phase of the BasicStroke.
+     * 
+     * @return the dash phase of the BasicStroke.
+     */
+    public float getDashPhase() {
+        return dashPhase;
+    }
+
+    /**
+     * Returns hash code of this BasicStroke.
+     * 
+     * @return the hash code of this BasicStroke.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(width);
+        hash.append(cap);
+        hash.append(join);
+        hash.append(miterLimit);
+        if (dash != null) {
+            hash.append(dashPhase);
+            for (float element : dash) {
+                hash.append(element);
+            }
+        }
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this BasicStroke object with the specified Object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the Object is a BasicStroke with the same data
+     * values as this BasicStroke; false otherwise. 
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof BasicStroke) {
+            BasicStroke bs = (BasicStroke)obj;
+            return
+                bs.width == width &&
+                bs.cap == cap &&
+                bs.join == join &&
+                bs.miterLimit == miterLimit &&
+                bs.dashPhase == dashPhase &&
+                java.util.Arrays.equals(bs.dash, dash);
+        }
+        return false;
+    }
+
+    /**
+     * Calculates allowable curve derivation.
+     * 
+     * @param width the width
+     * 
+     * @return the curve delta
+     */
+    double getCurveDelta(double width) {
+        double a = width + CURVE_DELTA;
+        double cos = 1.0 - 2.0 * width * width / (a * a);
+        double sin = Math.sqrt(1.0 - cos * cos);
+        return Math.abs(sin / cos);
+    }
+
+    /**
+     * Calculates the value to detect a small angle.
+     * 
+     * @param width the width
+     * 
+     * @return the corner delta
+     */
+    double getCornerDelta(double width) {
+        return width * width * Math.sin(Math.PI * CORNER_ANGLE / 180.0);
+    }
+
+    /**
+     * Calculates value to detect a zero angle.
+     * 
+     * @param width the width
+     * 
+     * @return the zero delta
+     */
+    double getZeroDelta(double width) {
+        return width * width * Math.sin(Math.PI * CORNER_ZERO / 180.0);
+    }
+
+    /**
+     * Creates a Shape from the outline of the specified shape 
+     * drawn with this BasicStroke.
+     * 
+     * @param s the specified Shape to be stroked.
+     * 
+     * @return the Shape of the stroked outline.
+     * 
+     * @see java.awt.Stroke#createStrokedShape(java.awt.Shape)
+     */
+    public Shape createStrokedShape(Shape s) {
+        w2 = width / 2.0;
+        curveDelta = getCurveDelta(w2);
+        cornerDelta = getCornerDelta(w2);
+        zeroDelta = getZeroDelta(w2);
+
+        dst = new BufferedPath();
+        lp = new BufferedPath();
+        rp = new BufferedPath();
+
+        if (dash == null) {
+            createSolidShape(s.getPathIterator(null));
+        } else {
+            createDashedShape(s.getPathIterator(null));
+        }
+
+        return dst.createGeneralPath();
+    }
+
+    /**
+     * Generates a shape with a solid (not dashed) outline.
+     * 
+     * @param p - the PathIterator of source shape
+     */
+    void createSolidShape(PathIterator p) {
+        double coords[] = new double[6];
+        mx = my = cx = cy = 0.0;
+        isMove = false;
+        isFirst = false;
+        checkMove = true;
+        boolean isClosed = true;
+
+        while(!p.isDone()) {
+            switch(p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (!isClosed) {
+                    closeSolidShape();
+                }
+                rp.clean();
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                isMove = true;
+                isClosed = false;
+                break;
+            case PathIterator.SEG_LINETO:
+                addLine(cx, cy, cx = coords[0], cy = coords[1], true);
+                break;
+            case PathIterator.SEG_QUADTO:
+                addQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                addCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5]);
+                break;
+            case PathIterator.SEG_CLOSE:
+                addLine(cx, cy, mx, my, false);
+                addJoin(lp, mx, my, lp.xMove, lp.yMove, true);
+                addJoin(rp, mx, my, rp.xMove, rp.yMove, false);
+                lp.closePath();
+                rp.closePath();
+                lp.appendReverse(rp);
+                isClosed = true;
+                break;
+            }
+            p.next();
+        }
+        if (!isClosed) {
+            closeSolidShape();
+        }
+
+        dst = lp;
+    }
+
+    /**
+     * Closes solid shape path.
+     */
+    void closeSolidShape() {
+        addCap(lp, cx, cy, rp.xLast, rp.yLast);
+        lp.combine(rp);
+        addCap(lp, mx, my, lp.xMove, lp.yMove);
+        lp.closePath();
+    }
+
+    /**
+     * Generates dashed stroked shape.
+     * 
+     * @param p - the PathIterator of source shape
+     */
+    void createDashedShape(PathIterator p) {
+        double coords[] = new double[6];
+        mx = my = cx = cy = 0.0;
+        smx = smy = scx = scy = 0.0;
+        isMove = false;
+        checkMove = false;
+        boolean isClosed = true;
+
+        while(!p.isDone()) {
+            switch(p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+
+                if (!isClosed) {
+                    closeDashedShape();
+                }
+
+                dasher = new Dasher(dash, dashPhase);
+                lp.clean();
+                rp.clean();
+                sp = null;
+                isFirst = true;
+                isMove = true;
+                isClosed = false;
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                break;
+            case PathIterator.SEG_LINETO:
+                addDashLine(cx, cy, cx = coords[0], cy = coords[1]);
+                break;
+            case PathIterator.SEG_QUADTO:
+                addDashQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                addDashCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5]);
+                break;
+            case PathIterator.SEG_CLOSE:
+                addDashLine(cx, cy, cx = mx, cy = my);
+
+                if (dasher.isConnected()) {
+                    // Connect current and head segments
+                    addJoin(lp, fmx, fmy, sp.xMove, sp.yMove, true);
+                    lp.join(sp);
+                    addJoin(lp, fmx, fmy, rp.xLast, rp.yLast, true);
+                    lp.combine(rp);
+                    addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                    lp.closePath();
+                    dst.append(lp);
+                    sp = null;
+                } else {
+                    closeDashedShape();
+                }
+
+                isClosed = true;
+                break;
+            }
+            p.next();
+        }
+
+        if (!isClosed) {
+            closeDashedShape();
+        }
+
+    }
+
+    /**
+     * Closes dashed shape path.
+     */
+    void closeDashedShape() {
+        // Add head segment
+        if (sp != null) {
+            addCap(sp, fmx, fmy, sp.xMove, sp.yMove);
+            sp.closePath();
+            dst.append(sp);
+        }
+        if (lp.typeSize > 0) {
+            // Close current segment
+            if (!dasher.isClosed()) {
+                addCap(lp, scx, scy, rp.xLast, rp.yLast);
+                lp.combine(rp);
+                addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                lp.closePath();
+            }
+            dst.append(lp);
+        }
+    }
+
+    /**
+     * Adds cap to the work path.
+     * 
+     * @param p - the BufferedPath object of work path
+     * @param x0 - the x coordinate of the source path
+     * @param y0 - the y coordinate on the source path
+     * @param x2 - the x coordinate of the next point on the work path
+     * @param y2 - the y coordinate of the next point on the work path
+     */
+    void addCap(BufferedPath p, double x0, double y0, double x2, double y2) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+
+        switch(cap) {
+        case CAP_BUTT:
+            p.lineTo(x2, y2);
+            break;
+        case CAP_ROUND:
+            double mx = x10 * CUBIC_ARC;
+            double my = y10 * CUBIC_ARC;
+
+            double x3 = x0 + y10;
+            double y3 = y0 - x10;
+
+            x10 *= CUBIC_ARC;
+            y10 *= CUBIC_ARC;
+            x20 *= CUBIC_ARC;
+            y20 *= CUBIC_ARC;
+
+            p.cubicTo(x1 + y10, y1 - x10, x3 + mx, y3 + my, x3, y3);
+            p.cubicTo(x3 - mx, y3 - my, x2 - y20, y2 + x20, x2, y2);
+            break;
+        case CAP_SQUARE:
+            p.lineTo(x1 + y10, y1 - x10);
+            p.lineTo(x2 - y20, y2 + x20);
+            p.lineTo(x2, y2);
+            break;
+        }
+    }
+
+    /**
+     * Adds bevel and miter join to the work path.
+     * 
+     * @param p - the BufferedPath object of work path
+     * @param x0 - the x coordinate of the source path
+     * @param y0 - the y coordinate on the source path
+     * @param x2 - the x coordinate of the next point on the work path
+     * @param y2 - the y coordinate of the next point on the work path
+     * @param isLeft - the orientation of work path, true if work path lies to the left from source path, false otherwise
+     */
+    void addJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+        double sin0 = x10 * y20 - y10 * x20;
+
+        // Small corner
+        if (-cornerDelta < sin0 && sin0 < cornerDelta) {
+            double cos0 = x10 * x20 + y10 * y20;
+            if (cos0 > 0.0) {
+                // if zero corner do nothing
+                if (-zeroDelta > sin0 || sin0 > zeroDelta) {
+                    double x3 = x0 + w2 * w2 * (y20 - y10) / sin0;
+                    double y3 = y0 + w2 * w2 * (x10 - x20) / sin0;
+                    p.setLast(x3, y3);
+                }
+                return;
+            }
+            // Zero corner
+            if (-zeroDelta < sin0 && sin0 < zeroDelta) {
+                p.lineTo(x2, y2);
+            }
+            return;
+        }
+
+        if (isLeft ^ (sin0 < 0.0)) {
+            // Twisted corner
+            p.lineTo(x0, y0);
+            p.lineTo(x2, y2);
+        } else {
+            switch(join) {
+            case JOIN_BEVEL:
+                p.lineTo(x2, y2);
+                break;
+            case JOIN_MITER:
+                double s1 = x1 * x10 + y1 * y10;
+                double s2 = x2 * x20 + y2 * y20;
+                double x3 = (s1 * y20 - s2 * y10) / sin0;
+                double y3 = (s2 * x10 - s1 * x20) / sin0;
+                double x30 = x3 - x0;
+                double y30 = y3 - y0;
+                double miterLength = Math.sqrt(x30 * x30 + y30 * y30);
+                if (miterLength < miterLimit * w2) {
+                    p.lineTo(x3, y3);
+                }
+                p.lineTo(x2, y2);
+                break;
+            case JOIN_ROUND:
+                addRoundJoin(p, x0, y0, x2, y2, isLeft);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Adds round join to the work path.
+     * 
+     * @param p - the BufferedPath object of work path
+     * @param x0 - the x coordinate of the source path
+     * @param y0 - the y coordinate on the source path
+     * @param x2 - the x coordinate of the next point on the work path
+     * @param y2 - the y coordinate of the next point on the work path
+     * @param isLeft - the orientation of work path, true if work path lies to the left from source path, false otherwise
+     */
+    void addRoundJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+
+        double x30 = x10 + x20;
+        double y30 = y10 + y20;
+
+        double l30 = Math.sqrt(x30 * x30 + y30 * y30);
+
+        if (l30 < 1E-5) {
+            p.lineTo(x2, y2);
+            return;
+        }
+
+        double w = w2 / l30;
+
+        x30 *= w;
+        y30 *= w;
+
+        double x3 = x0 + x30;
+        double y3 = y0 + y30;
+
+        double cos = x10 * x20 + y10 * y20;
+        double a = Math.acos(cos / (w2 * w2));
+        if (cos >= 0.0) {
+            double k = 4.0 / 3.0 * Math.tan(a / 4.0);
+            if (isLeft) {
+                k = -k;
+            }
+
+            x10 *= k;
+            y10 *= k;
+            x20 *= k;
+            y20 *= k;
+
+            p.cubicTo(x1 - y10, y1 + x10, x2 + y20, y2 - x20, x2, y2);
+        } else {
+            double k = 4.0 / 3.0 * Math.tan(a / 8.0);
+            if (isLeft) {
+                k = -k;
+            }
+
+            x10 *= k;
+            y10 *= k;
+            x20 *= k;
+            y20 *= k;
+            x30 *= k;
+            y30 *= k;
+
+            p.cubicTo(x1 - y10, y1 + x10, x3 + y30, y3 - x30, x3, y3);
+            p.cubicTo(x3 - y30, y3 + x30, x2 + y20, y2 - x20, x2, y2);
+        }
+
+    }
+
+    /**
+     * Adds solid line segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the start line point
+     * @param y1 - the y coordinate of the start line point
+     * @param x2 - the x coordinate of the end line point
+     * @param y2 - the y coordinate of the end line point
+     * @param zero - if true it's allowable to add zero length line segment
+     */
+    void addLine(double x1, double y1, double x2, double y2, boolean zero) {
+        double dx = x2 - x1;
+        double dy = y2 - y1;
+
+        if (dx == 0.0 && dy == 0.0) {
+            if (!zero) {
+                return;
+            }
+            dx = w2;
+            dy = 0;
+        } else {
+            double w = w2 / Math.sqrt(dx * dx + dy * dy);
+            dx *= w;
+            dy *= w;
+        }
+
+        double lx1 = x1 - dy;
+        double ly1 = y1 + dx;
+        double rx1 = x1 + dy;
+        double ry1 = y1 - dx;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        lp.lineTo(x2 - dy, y2 + dx);
+        rp.lineTo(x2 + dy, y2 - dx);
+    }
+
+    /**
+     * Adds solid quad segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     */
+    void addQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+
+        if (l21 == 0.0 && l23 == 0.0) {
+            addLine(x1, y1, x3, y3, false);
+            return;
+        }
+
+        if (l21 == 0.0) {
+            addLine(x2, y2, x3, y3, false);
+            return;
+        }
+
+        if (l23 == 0.0) {
+            addLine(x1, y1, x2, y2, false);
+            return;
+        }
+
+        double w;
+        w = w2 / l21;
+        double mx1 = - y21 * w;
+        double my1 =   x21 * w;
+        w = w2 / l23;
+        double mx3 =   y23 * w;
+        double my3 = - x23 * w;
+
+        double lx1 = x1 + mx1;
+        double ly1 = y1 + my1;
+        double rx1 = x1 - mx1;
+        double ry1 = y1 - my1;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        if (x21 * y23 - y21 * x23 == 0.0) {
+            // On line curve
+            if (x21 * x23 + y21 * y23 > 0.0) {
+                // Twisted curve
+                if (l21 == l23) {
+                    double px = x1 + (x21 + x23) / 4.0;
+                    double py = y1 + (y21 + y23) / 4.0;
+                    lp.lineTo(px + mx1, py + my1);
+                    rp.lineTo(px - mx1, py - my1);
+                    lp.lineTo(px - mx1, py - my1);
+                    rp.lineTo(px + mx1, py + my1);
+                    lp.lineTo(x3 - mx1, y3 - my1);
+                    rp.lineTo(x3 + mx1, y3 + my1);
+                } else {
+                    double px1, py1;
+                    double k = l21 / (l21 + l23);
+                    double px = x1 + (x21 + x23) * k * k;
+                    double py = y1 + (y21 + y23) * k * k;
+                    px1 = (x1 + px) / 2.0;
+                    py1 = (y1 + py) / 2.0;
+                    lp.quadTo(px1 + mx1, py1 + my1, px + mx1, py + my1);
+                    rp.quadTo(px1 - mx1, py1 - my1, px - mx1, py - my1);
+                    lp.lineTo(px - mx1, py - my1);
+                    rp.lineTo(px + mx1, py + my1);
+                    px1 = (x3 + px) / 2.0;
+                    py1 = (y3 + py) / 2.0;
+                    lp.quadTo(px1 - mx1, py1 - my1, x3 - mx1, y3 - my1);
+                    rp.quadTo(px1 + mx1, py1 + my1, x3 + mx1, y3 + my1);
+                }
+            } else {
+                // Simple curve
+                lp.quadTo(x2 + mx1, y2 + my1, x3 + mx3, y3 + my3);
+                rp.quadTo(x2 - mx1, y2 - my1, x3 - mx3, y3 - my3);
+            }
+        } else {
+            addSubQuad(x1, y1, x2, y2, x3, y3, 0);
+        }
+    }
+
+    /**
+     * Subdivides solid quad curve to make outline for source quad segment and adds it to work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param level - the maximum level of subdivision deepness
+     */
+    void addSubQuad(double x1, double y1, double x2, double y2, double x3, double y3, int level) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double cos = x21 * x23 + y21 * y23;
+        double sin = x21 * y23 - y21 * x23;
+
+        if (level < MAX_LEVEL && (cos >= 0.0 || (Math.abs(sin / cos) > curveDelta))) {
+            double c1x = (x2 + x1) / 2.0;
+            double c1y = (y2 + y1) / 2.0;
+            double c2x = (x2 + x3) / 2.0;
+            double c2y = (y2 + y3) / 2.0;
+            double c3x = (c1x + c2x) / 2.0;
+            double c3y = (c1y + c2y) / 2.0;
+            addSubQuad(x1, y1, c1x, c1y, c3x, c3y, level + 1);
+            addSubQuad(c3x, c3y, c2x, c2y, x3, y3, level + 1);
+        } else {
+            double w;
+            double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+            w = w2 / sin;
+            double mx2 = (x21 * l23 + x23 * l21) * w;
+            double my2 = (y21 * l23 + y23 * l21) * w;
+            w = w2 / l23;
+            double mx3 =   y23 * w;
+            double my3 = - x23 * w;
+            lp.quadTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3);
+            rp.quadTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3);
+        }
+    }
+
+    /**
+     * Adds solid cubic segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param x4 - the x coordinate of the fours control point
+     * @param y4 - the y coordinate of the fours control point
+     */
+    void addCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+        // All edges are zero
+        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
+            addLine(x1, y1, x4, y4, false);
+            return;
+        }
+
+        // One zero edge
+        if (l12 == 0.0 && l23 == 0.0) {
+            addLine(x3, y3, x4, y4, false);
+            return;
+        }
+
+        if (l23 == 0.0 && l34 == 0.0) {
+            addLine(x1, y1, x2, y2, false);
+            return;
+        }
+
+        if (l12 == 0.0 && l34 == 0.0) {
+            addLine(x2, y2, x3, y3, false);
+            return;
+        }
+
+        double w, mx1, my1, mx4, my4;
+        boolean onLine;
+
+        if (l12 == 0.0) {
+            w = w2 / l23;
+            mx1 =   y23 * w;
+            my1 = - x23 * w;
+            w = w2 / l34;
+            mx4 =   y34 * w;
+            my4 = - x34 * w;
+            onLine = - x23 * y34 + y23 * x34 == 0.0; // sin3
+        } else
+        if (l34 == 0.0) {
+            w = w2 / l12;
+            mx1 =   y12 * w;
+            my1 = - x12 * w;
+            w = w2 / l23;
+            mx4 =   y23 * w;
+            my4 = - x23 * w;
+            onLine = - x12 * y23 + y12 * x23 == 0.0; // sin2
+        } else {
+            w = w2 / l12;
+            mx1 =   y12 * w;
+            my1 = - x12 * w;
+            w = w2 / l34;
+            mx4 =   y34 * w;
+            my4 = - x34 * w;
+            if (l23 == 0.0) {
+                onLine = - x12 * y34 + y12 * x34 == 0.0;
+            } else {
+                onLine =
+                    - x12 * y34 + y12 * x34 == 0.0 &&
+                    - x12 * y23 + y12 * x23 == 0.0 && // sin2
+                    - x23 * y34 + y23 * x34 == 0.0;   // sin3
+            }
+        }
+
+        double lx1 = x1 + mx1;
+        double ly1 = y1 + my1;
+        double rx1 = x1 - mx1;
+        double ry1 = y1 - my1;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        if (onLine) {
+            if ((x1 == x2 && y1 < y2) || x1 < x2) {
+                l12 = -l12;
+            }
+            if ((x2 == x3 && y2 < y3) || x2 < x3) {
+                l23 = -l23;
+            }
+            if ((x3 == x4 && y3 < y4) || x3 < x4) {
+                l34 = -l34;
+            }
+            double d = l23 * l23 - l12 * l34;
+            double roots[] = new double[3];
+            int rc = 0;
+            if (d == 0.0) {
+                double t = (l12 - l23) / (l12 + l34 - l23 - l23);
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+            } else
+            if (d > 0.0) {
+                d = Math.sqrt(d);
+                double z = l12 + l34 - l23 - l23;
+                double t;
+                t = (l12 - l23 + d) / z;
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+                t = (l12 - l23 - d) / z;
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+            }
+
+            if (rc > 0) {
+                // Sort roots
+                if (rc == 2 && roots[0] > roots[1]) {
+                    double tmp = roots[0];
+                    roots[0] = roots[1];
+                    roots[1] = tmp;
+                }
+                roots[rc++] = 1.0;
+
+                double ax = - x34 - x12 + x23 + x23;
+                double ay = - y34 - y12 + y23 + y23;
+                double bx = 3.0 * (- x23 + x12);
+                double by = 3.0 * (- y23 + y12);
+                double cx = 3.0 * (- x12);
+                double cy = 3.0 * (- y12);
+                double xPrev = x1;
+                double yPrev = y1;
+                for(int i = 0; i < rc; i++) {
+                    double t = roots[i];
+                    double px = t * (t * (t * ax + bx) + cx) + x1;
+                    double py = t * (t * (t * ay + by) + cy) + y1;
+                    double px1 = (xPrev + px) / 2.0;
+                    double py1 = (yPrev + py) / 2.0;
+                    lp.cubicTo(px1 + mx1, py1 + my1, px1 + mx1, py1 + my1, px + mx1, py + my1);
+                    rp.cubicTo(px1 - mx1, py1 - my1, px1 - mx1, py1 - my1, px - mx1, py - my1);
+                    if (i < rc - 1) {
+                        lp.lineTo(px - mx1, py - my1);
+                        rp.lineTo(px + mx1, py + my1);
+                    }
+                    xPrev = px;
+                    yPrev = py;
+                    mx1 = - mx1;
+                    my1 = - my1;
+                }
+            } else {
+                lp.cubicTo(x2 + mx1, y2 + my1, x3 + mx4, y3 + my4, x4 + mx4, y4 + my4);
+                rp.cubicTo(x2 - mx1, y2 - my1, x3 - mx4, y3 - my4, x4 - mx4, y4 - my4);
+            }
+        } else {
+            addSubCubic(x1, y1, x2, y2, x3, y3, x4, y4, 0);
+        }
+    }
+
+    /**
+     * Subdivides solid cubic curve to make outline for source quad segment and adds it to work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param x4 - the x coordinate of the fours control point
+     * @param y4 - the y coordinate of the fours control point
+     * @param level - the maximum level of subdivision deepness
+     */
+    void addSubCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, int level) {
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double cos2 = - x12 * x23 - y12 * y23;
+        double cos3 = - x23 * x34 - y23 * y34;
+        double sin2 = - x12 * y23 + y12 * x23;
+        double sin3 = - x23 * y34 + y23 * x34;
+        double sin0 = - x12 * y34 + y12 * x34;
+        double cos0 = - x12 * x34 - y12 * y34;
+
+        if (level < MAX_LEVEL && (sin2 != 0.0 || sin3 != 0.0 || sin0 != 0.0) &&
+            (cos2 >= 0.0 || cos3 >= 0.0 || cos0 >= 0.0 ||
+            (Math.abs(sin2 / cos2) > curveDelta) ||
+            (Math.abs(sin3 / cos3) > curveDelta) ||
+            (Math.abs(sin0 / cos0) > curveDelta)))
+        {
+            double cx = (x2 + x3) / 2.0;
+            double cy = (y2 + y3) / 2.0;
+            double lx2 = (x2 + x1) / 2.0;
+            double ly2 = (y2 + y1) / 2.0;
+            double rx3 = (x3 + x4) / 2.0;
+            double ry3 = (y3 + y4) / 2.0;
+            double lx3 = (cx + lx2) / 2.0;
+            double ly3 = (cy + ly2) / 2.0;
+            double rx2 = (cx + rx3) / 2.0;
+            double ry2 = (cy + ry3) / 2.0;
+            cx = (lx3 + rx2) / 2.0;
+            cy = (ly3 + ry2) / 2.0;
+            addSubCubic(x1, y1, lx2, ly2, lx3, ly3, cx, cy, level + 1);
+            addSubCubic(cx, cy, rx2, ry2, rx3, ry3, x4, y4, level + 1);
+        } else {
+            double w, mx1, my1, mx2, my2, mx3, my3, mx4, my4;
+            double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+            double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+            if (l12 == 0.0) {
+                w = w2 / l23;
+                mx1 =   y23 * w;
+                my1 = - x23 * w;
+                w = w2 / l34;
+                mx4 =   y34 * w;
+                my4 = - x34 * w;
+            } else
+            if (l34 == 0.0) {
+                w = w2 / l12;
+                mx1 =   y12 * w;
+                my1 = - x12 * w;
+                w = w2 / l23;
+                mx4 =   y23 * w;
+                my4 = - x23 * w;
+            } else {
+                // Common case
+                w = w2 / l12;
+                mx1 =   y12 * w;
+                my1 = - x12 * w;
+                w = w2 / l34;
+                mx4 =   y34 * w;
+                my4 = - x34 * w;
+            }
+
+            if (sin2 == 0.0) {
+                mx2 = mx1;
+                my2 = my1;
+            } else {
+                w = w2 / sin2;
+                mx2 = -(x12 * l23 - x23 * l12) * w;
+                my2 = -(y12 * l23 - y23 * l12) * w;
+            }
+            if (sin3 == 0.0) {
+                mx3 = mx4;
+                my3 = my4;
+            } else {
+                w = w2 / sin3;
+                mx3 = -(x23 * l34 - x34 * l23) * w;
+                my3 = -(y23 * l34 - y34 * l23) * w;
+            }
+
+            lp.cubicTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3, x4 + mx4, y4 + my4);
+            rp.cubicTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3, x4 - mx4, y4 - my4);
+        }
+    }
+
+    /**
+     * Adds dashed line segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the start line point
+     * @param y1 - the y coordinate of the start line point
+     * @param x2 - the x coordinate of the end line point
+     * @param y2 - the y coordinate of the end line point
+     */
+    void addDashLine(double x1, double y1, double x2, double y2) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+
+        if (l21 == 0.0) {
+            return;
+        }
+
+        double px1, py1;
+        px1 = py1 = 0.0;
+        double w = w2 / l21;
+        double mx = - y21 * w;
+        double my =   x21 * w;
+
+        dasher.init(new DashIterator.Line(l21));
+
+        while(!dasher.eof()) {
+            double t = dasher.getValue();
+            scx = x1 + t * x21;
+            scy = y1 + t * y21;
+
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                double lx1 = px1 + mx;
+                double ly1 = py1 + my;
+                double rx1 = px1 - mx;
+                double ry1 = py1 - my;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else
+                if (dasher.isContinue()) {
+                    double px2 = scx;
+                    double py2 = scy;
+                    lp.lineTo(px2 + mx, py2 + my);
+                    rp.lineTo(px2 - mx, py2 - my);
+                    if (dasher.close) {
+                        addCap(lp, px2, py2, rp.xLast, rp.yLast);
+                        lp.combine(rp);
+                        if (isFirst) {
+                            isFirst = false;
+                            fmx = smx;
+                            fmy = smy;
+                            sp = lp;
+                            lp = new BufferedPath();
+                        } else {
+                            addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                            lp.closePath();
+                        }
+                        isMove = true;
+                    }
+                }
+
+            dasher.next();
+        }
+    }
+
+    /**
+     * Adds dashed quad segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     */
+    void addDashQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
+
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+
+        if (l21 == 0.0 && l23 == 0.0) {
+            return;
+        }
+
+        if (l21 == 0.0) {
+            addDashLine(x2, y2, x3, y3);
+            return;
+        }
+
+        if (l23 == 0.0) {
+            addDashLine(x1, y1, x2, y2);
+            return;
+        }
+
+        double ax = x1 + x3 - x2 - x2;
+        double ay = y1 + y3 - y2 - y2;
+        double bx = x2 - x1;
+        double by = y2 - y1;
+        double cx = x1;
+        double cy = y1;
+
+        double px1, py1, dx1, dy1;
+        px1 = py1 = dx1 = dy1 = 0.0;
+        double prev = 0.0;
+
+        dasher.init(new DashIterator.Quad(x1, y1, x2, y2, x3, y3));
+
+        while(!dasher.eof()) {
+            double t = dasher.getValue();
+            double dx = t * ax + bx;
+            double dy = t * ay + by;
+            scx = t * (dx + bx) + cx; // t^2 * ax + 2.0 * t * bx + cx
+            scy = t * (dy + by) + cy; // t^2 * ay + 2.0 * t * by + cy
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                dx1 = dx;
+                dy1 = dy;
+                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
+                double mx1 = - dy1 * w;
+                double my1 =   dx1 * w;
+                double lx1 = px1 + mx1;
+                double ly1 = py1 + my1;
+                double rx1 = px1 - mx1;
+                double ry1 = py1 - my1;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else 
+                if (dasher.isContinue()) {
+                    double px3 = scx;
+                    double py3 = scy;
+                    double sx = x2 - x23 * prev;
+                    double sy = y2 - y23 * prev;
+                    double t2 = (t - prev) / (1 - prev);
+                    double px2 = px1 + (sx - px1) * t2;
+                    double py2 = py1 + (sy - py1) * t2;
+
+                    addQuad(px1, py1, px2, py2, px3, py3);
+                    if (dasher.isClosed()) {
+                        addCap(lp, px3, py3, rp.xLast, rp.yLast);
+                        lp.combine(rp);
+                        if (isFirst) {
+                            isFirst = false;
+                            fmx = smx;
+                            fmy = smy;
+                            sp = lp;
+                            lp = new BufferedPath();
+                        } else {
+                            addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                            lp.closePath();
+                        }
+                        isMove = true;
+                    }
+                }
+
+            prev = t;
+            dasher.next();
+        }
+    }
+
+    /**
+     * Adds dashed cubic segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param x4 - the x coordinate of the fours control point
+     * @param y4 - the y coordinate of the fours control point
+     */
+    void addDashCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
+
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+        // All edges are zero
+        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
+            // NOTHING
+            return;
+        }
+
+        // One zero edge
+        if (l12 == 0.0 && l23 == 0.0) {
+            addDashLine(x3, y3, x4, y4);
+            return;
+        }
+
+        if (l23 == 0.0 && l34 == 0.0) {
+            addDashLine(x1, y1, x2, y2);
+            return;
+        }
+
+        if (l12 == 0.0 && l34 == 0.0) {
+            addDashLine(x2, y2, x3, y3);
+            return;
+        }
+
+        double ax = x4 - x1 + 3.0 * (x2 - x3);
+        double ay = y4 - y1 + 3.0 * (y2 - y3);
+        double bx = 3.0 * (x1 + x3 - x2 - x2);
+        double by = 3.0 * (y1 + y3 - y2 - y2);
+        double cx = 3.0 * (x2 - x1);
+        double cy = 3.0 * (y2 - y1);
+        double dx = x1;
+        double dy = y1;
+
+        double px1 = 0.0;
+        double py1 = 0.0;
+        double prev = 0.0;
+
+        dasher.init(new DashIterator.Cubic(x1, y1, x2, y2, x3, y3, x4, y4));
+
+        while(!dasher.eof()) {
+
+            double t = dasher.getValue();
+            scx = t * (t * (t * ax + bx) + cx) + dx;
+            scy = t * (t * (t * ay + by) + cy) + dy;
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                double dx1 = t * (t * (ax + ax + ax) + bx + bx) + cx;
+                double dy1 = t * (t * (ay + ay + ay) + by + by) + cy;
+                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
+                double mx1 = - dy1 * w;
+                double my1 =   dx1 * w;
+                double lx1 = px1 + mx1;
+                double ly1 = py1 + my1;
+                double rx1 = px1 - mx1;
+                double ry1 = py1 - my1;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else 
+                if (dasher.isContinue()) {
+                    double sx1 = x2 - x23 * prev;
+                    double sy1 = y2 - y23 * prev;
+                    double sx2 = x3 - x34 * prev;
+                    double sy2 = y3 - y34 * prev;
+                    double sx3 = sx1 + (sx2 - sx1) * prev;
+                    double sy3 = sy1 + (sy2 - sy1) * prev;
+                    double t2 = (t - prev) / (1 - prev);
+                    double sx4 = sx3 + (sx2 - sx3) * t2;
+                    double sy4 = sy3 + (sy2 - sy3) * t2;
+
+                    double px4 = scx;
+                    double py4 = scy;
+                    double px2 = px1 + (sx3 - px1) * t2;
+                    double py2 = py1 + (sy3 - py1) * t2;
+                    double px3 = px2 + (sx4 - px2) * t2;
+                    double py3 = py2 + (sy4 - py2) * t2;
+
+                    addCubic(px1, py1, px2, py2, px3, py3, px4, py4);
+                    if (dasher.isClosed()) {
+                        addCap(lp, px4, py4, rp.xLast, rp.yLast);
+                        lp.combine(rp);
+                        if (isFirst) {
+                            isFirst = false;
+                            fmx = smx;
+                            fmy = smy;
+                            sp = lp;
+                            lp = new BufferedPath();
+                        } else {
+                            addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                            lp.closePath();
+                        }
+                        isMove = true;
+                    }
+                }
+
+            prev = t;
+            dasher.next();
+        }
+    }
+
+    /**
+     * Dasher class provides dashing for particular dash style.
+     */
+    class Dasher {
+        
+        /** The pos. */
+        double pos;
+        
+        /** The first. */
+        boolean close, visible, first;
+        
+        /** The dash. */
+        float dash[];
+        
+        /** The phase. */
+        float phase;
+        
+        /** The index. */
+        int index;
+        
+        /** The iter. */
+        DashIterator iter;
+        
+        /**
+         * Instantiates a new dasher.
+         * 
+         * @param dash the dash
+         * @param phase the phase
+         */
+        Dasher(float dash[], float phase) {
+            this.dash = dash;
+            this.phase = phase;
+            index = 0;
+            pos = phase;
+            visible = true;
+            while (pos >= dash[index]) {
+                visible = !visible;
+                pos -= dash[index];
+                index = (index + 1) % dash.length;
+            }            
+            pos = -pos;
+            first = visible;
+        }
+        
+        /**
+         * Inits the.
+         * 
+         * @param iter the iter
+         */
+        void init(DashIterator iter) {
+            this.iter = iter;
+            close = true;
+        }
+        
+        /**
+         * Checks if is open.
+         * 
+         * @return true, if is open
+         */
+        boolean isOpen() {
+            return visible && pos < iter.length;
+        }
+        
+        /**
+         * Checks if is continue.
+         * 
+         * @return true, if is continue
+         */
+        boolean isContinue() {
+            return !visible && pos > 0;
+        }
+        
+        /**
+         * Checks if is closed.
+         * 
+         * @return true, if is closed
+         */
+        boolean isClosed() {
+            return close;
+        }
+        
+        /**
+         * Checks if is connected.
+         * 
+         * @return true, if is connected
+         */
+        boolean isConnected() {
+            return first && !close;
+        }
+
+        /**
+         * Eof.
+         * 
+         * @return true, if successful
+         */
+        boolean eof() {
+            if (!close) {
+                pos -= iter.length;
+                return true;
+            }
+            if (pos >= iter.length) {
+                if (visible) {
+                    pos -= iter.length;
+                    return true;
+                }
+                close = pos == iter.length;
+            }
+            return false;
+        }
+        
+        /**
+         * Next.
+         */
+        void next() {
+            if (close) {
+                pos += dash[index];
+                index = (index + 1) % dash.length;
+            } else {
+                // Go back
+                index = (index + dash.length - 1) % dash.length;
+                pos -= dash[index];
+            }
+            visible = !visible;
+        }
+        
+        /**
+         * Gets the value.
+         * 
+         * @return the value
+         */
+        double getValue() {
+            double t = iter.getNext(pos);
+            return t < 0 ? 0 : (t > 1 ? 1 : t);
+        }
+        
+    }
+
+    /**
+     * DashIterator class provides dashing for particular segment type.
+     */
+    static abstract class DashIterator {
+
+        /** The Constant FLATNESS. */
+        static final double FLATNESS = 1.0;
+
+        /**
+         * The Class Line.
+         */
+        static class Line extends DashIterator {
+
+            /**
+             * Instantiates a new line.
+             * 
+             * @param len the len
+             */
+            Line(double len) {
+                length = len;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                return dashPos / length;
+            }
+
+        }
+
+        /**
+         * The Class Quad.
+         */
+        static class Quad extends DashIterator {
+
+            /** The val size. */
+            int valSize;
+            
+            /** The val pos. */
+            int valPos;
+            
+            /** The cur len. */
+            double curLen;
+            
+            /** The prev len. */
+            double prevLen;
+            
+            /** The last len. */
+            double lastLen;
+            
+            /** The values. */
+            double[] values;
+            
+            /** The step. */
+            double step;
+
+            /**
+             * Instantiates a new quad.
+             * 
+             * @param x1 the x1
+             * @param y1 the y1
+             * @param x2 the x2
+             * @param y2 the y2
+             * @param x3 the x3
+             * @param y3 the y3
+             */
+            Quad(double x1, double y1, double x2, double y2, double x3, double y3) {
+
+                double nx = x1 + x3 - x2 - x2;
+                double ny = y1 + y3 - y2 - y2;
+
+                int n = (int)(1 + Math.sqrt(0.75 * (Math.abs(nx) + Math.abs(ny)) * FLATNESS));
+                step = 1.0 / n;
+
+                double ax = x1 + x3 - x2 - x2;
+                double ay = y1 + y3 - y2 - y2;
+                double bx = 2.0 * (x2 - x1);
+                double by = 2.0 * (y2 - y1);
+
+                double dx1 = step * (step * ax + bx);
+                double dy1 = step * (step * ay + by);
+                double dx2 = step * (step * ax * 2.0);
+                double dy2 = step * (step * ay * 2.0);
+                double vx = x1;
+                double vy = y1;
+
+                valSize = n;
+                values = new double[valSize];
+                double pvx = vx;
+                double pvy = vy;
+                length = 0.0;
+                for(int i = 0; i < n; i++) {
+                    vx += dx1;
+                    vy += dy1;
+                    dx1 += dx2;
+                    dy1 += dy2;
+                    double lx = vx - pvx;
+                    double ly = vy - pvy;
+                    values[i] = Math.sqrt(lx * lx + ly * ly);
+                    length += values[i];
+                    pvx = vx;
+                    pvy = vy;
+                }
+
+                valPos = 0;
+                curLen = 0.0;
+                prevLen = 0.0;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                double t = 2.0;
+                while (curLen <= dashPos && valPos < valSize) {
+                    prevLen = curLen;
+                    curLen += lastLen = values[valPos++];
+                }
+                if (curLen > dashPos) {
+                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
+                }
+                return t;
+            }
+
+        }
+
+        /**
+         * The Class Cubic.
+         */
+        static class Cubic extends DashIterator {
+
+            /** The val size. */
+            int valSize;
+            
+            /** The val pos. */
+            int valPos;
+            
+            /** The cur len. */
+            double curLen;
+            
+            /** The prev len. */
+            double prevLen;
+            
+            /** The last len. */
+            double lastLen;
+            
+            /** The values. */
+            double[] values;
+            
+            /** The step. */
+            double step;
+
+            /**
+             * Instantiates a new cubic.
+             * 
+             * @param x1 the x1
+             * @param y1 the y1
+             * @param x2 the x2
+             * @param y2 the y2
+             * @param x3 the x3
+             * @param y3 the y3
+             * @param x4 the x4
+             * @param y4 the y4
+             */
+            Cubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
+
+                double nx1 = x1 + x3 - x2 - x2;
+                double ny1 = y1 + y3 - y2 - y2;
+                double nx2 = x2 + x4 - x3 - x3;
+                double ny2 = y2 + y4 - y3 - y3;
+
+                double max = Math.max(Math.abs(nx1) + Math.abs(ny1), Math.abs(nx2) + Math.abs(ny2));
+                int n = (int)(1 + Math.sqrt(0.75 * max) * FLATNESS);
+                step = 1.0 / n;
+
+                double ax = x4 - x1 + 3.0 * (x2 - x3);
+                double ay = y4 - y1 + 3.0 * (y2 - y3);
+                double bx = 3.0 * (x1 + x3 - x2 - x2);
+                double by = 3.0 * (y1 + y3 - y2 - y2);
+                double cx = 3.0 * (x2 - x1);
+                double cy = 3.0 * (y2 - y1);
+
+                double dx1 = step * (step * (step * ax + bx) + cx);
+                double dy1 = step * (step * (step * ay + by) + cy);
+                double dx2 = step * (step * (step * ax * 6.0 + bx * 2.0));
+                double dy2 = step * (step * (step * ay * 6.0 + by * 2.0));
+                double dx3 = step * (step * (step * ax * 6.0));
+                double dy3 = step * (step * (step * ay * 6.0));
+                double vx = x1;
+                double vy = y1;
+
+                valSize = n;
+                values = new double[valSize];
+                double pvx = vx;
+                double pvy = vy;
+                length = 0.0;
+                for(int i = 0; i < n; i++) {
+                    vx += dx1;
+                    vy += dy1;
+                    dx1 += dx2;
+                    dy1 += dy2;
+                    dx2 += dx3;
+                    dy2 += dy3;
+                    double lx = vx - pvx;
+                    double ly = vy - pvy;
+                    values[i] = Math.sqrt(lx * lx + ly * ly);
+                    length += values[i];
+                    pvx = vx;
+                    pvy = vy;
+                }
+
+                valPos = 0;
+                curLen = 0.0;
+                prevLen = 0.0;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                double t = 2.0;
+                while (curLen <= dashPos && valPos < valSize) {
+                    prevLen = curLen;
+                    curLen += lastLen = values[valPos++];
+                }
+                if (curLen > dashPos) {
+                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
+                }
+                return t;
+            }
+
+        }
+
+        /** The length. */
+        double length;
+
+        /**
+         * Gets the next.
+         * 
+         * @param dashPos the dash pos
+         * 
+         * @return the next
+         */
+        abstract double getNext(double dashPos);
+
+    }
+
+    /**
+     * BufferedPath class provides work path storing and processing.
+     */
+    static class BufferedPath {
+
+        /** The Constant bufCapacity. */
+        private static final int bufCapacity = 10;
+
+        /** The point shift. */
+        static int pointShift[] = {
+                2,  // MOVETO
+                2,  // LINETO
+                4,  // QUADTO
+                6,  // CUBICTO
+                0}; // CLOSE
+
+        /** The types. */
+        byte[] types;
+        
+        /** The points. */
+        float[] points;
+        
+        /** The type size. */
+        int typeSize;
+        
+        /** The point size. */
+        int pointSize;
+
+        /** The x last. */
+        float xLast;
+        
+        /** The y last. */
+        float yLast;
+        
+        /** The x move. */
+        float xMove;
+        
+        /** The y move. */
+        float yMove;
+
+        /**
+         * Instantiates a new buffered path.
+         */
+        public BufferedPath() {
+            types = new byte[bufCapacity];
+            points = new float[bufCapacity * 2];
+        }
+
+        /**
+         * Check buf.
+         * 
+         * @param typeCount the type count
+         * @param pointCount the point count
+         */
+        void checkBuf(int typeCount, int pointCount) {
+            if (typeSize + typeCount > types.length) {
+                byte tmp[] = new byte[typeSize + Math.max(bufCapacity, typeCount)];
+                System.arraycopy(types, 0, tmp, 0, typeSize);
+                types = tmp;
+            }
+            if (pointSize + pointCount > points.length) {
+                float tmp[] = new float[pointSize + Math.max(bufCapacity * 2, pointCount)];
+                System.arraycopy(points, 0, tmp, 0, pointSize);
+                points = tmp;
+            }
+        }
+
+        /**
+         * Checks if is empty.
+         * 
+         * @return true, if is empty
+         */
+        boolean isEmpty() {
+            return typeSize == 0;
+        }
+
+        /**
+         * Clean.
+         */
+        void clean() {
+            typeSize = 0;
+            pointSize = 0;
+        }
+
+        /**
+         * Move to.
+         * 
+         * @param x the x
+         * @param y the y
+         */
+        void moveTo(double x, double y) {
+            checkBuf(1, 2);
+            types[typeSize++] = PathIterator.SEG_MOVETO;
+            points[pointSize++] = xMove = (float)x;
+            points[pointSize++] = yMove = (float)y;
+        }
+
+        /**
+         * Line to.
+         * 
+         * @param x the x
+         * @param y the y
+         */
+        void lineTo(double x, double y) {
+            checkBuf(1, 2);
+            types[typeSize++] = PathIterator.SEG_LINETO;
+            points[pointSize++] = xLast = (float)x;
+            points[pointSize++] = yLast = (float)y;
+        }
+
+        /**
+         * Quad to.
+         * 
+         * @param x1 the x1
+         * @param y1 the y1
+         * @param x2 the x2
+         * @param y2 the y2
+         */
+        void quadTo(double x1, double y1, double x2, double y2) {
+            checkBuf(1, 4);
+            types[typeSize++] = PathIterator.SEG_QUADTO;
+            points[pointSize++] = (float)x1;
+            points[pointSize++] = (float)y1;
+            points[pointSize++] = xLast = (float)x2;
+            points[pointSize++] = yLast = (float)y2;
+        }
+
+        /**
+         * Cubic to.
+         * 
+         * @param x1 the x1
+         * @param y1 the y1
+         * @param x2 the x2
+         * @param y2 the y2
+         * @param x3 the x3
+         * @param y3 the y3
+         */
+        void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3) {
+            checkBuf(1, 6);
+            types[typeSize++] = PathIterator.SEG_CUBICTO;
+            points[pointSize++] = (float)x1;
+            points[pointSize++] = (float)y1;
+            points[pointSize++] = (float)x2;
+            points[pointSize++] = (float)y2;
+            points[pointSize++] = xLast = (float)x3;
+            points[pointSize++] = yLast = (float)y3;
+        }
+
+        /**
+         * Close path.
+         */
+        void closePath() {
+            checkBuf(1, 0);
+            types[typeSize++] = PathIterator.SEG_CLOSE;
+        }
+
+        /**
+         * Sets the last.
+         * 
+         * @param x the x
+         * @param y the y
+         */
+        void setLast(double x, double y) {
+            points[pointSize - 2] = xLast = (float)x;
+            points[pointSize - 1] = yLast = (float)y;
+        }
+
+        /**
+         * Append.
+         * 
+         * @param p the p
+         */
+        void append(BufferedPath p) {
+            checkBuf(p.typeSize, p.pointSize);
+            System.arraycopy(p.points, 0, points, pointSize, p.pointSize);
+            System.arraycopy(p.types, 0, types, typeSize, p.typeSize);
+            pointSize += p.pointSize;
+            typeSize += p.typeSize;
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Append reverse.
+         * 
+         * @param p the p
+         */
+        void appendReverse(BufferedPath p) {
+            checkBuf(p.typeSize, p.pointSize);
+            // Skip last point, beacause it's the first point of the second path
+            for(int i = p.pointSize - 2; i >= 0; i -= 2) {
+                points[pointSize++] = p.points[i + 0];
+                points[pointSize++] = p.points[i + 1];
+            }
+            // Skip first type, beacuse it's always MOVETO
+            int closeIndex = 0;
+            for(int i = p.typeSize - 1; i >= 0; i--) {
+                byte type = p.types[i];
+                if (type == PathIterator.SEG_MOVETO) {
+                    types[closeIndex] = PathIterator.SEG_MOVETO;
+                    types[typeSize++] = PathIterator.SEG_CLOSE;
+                } else {
+                    if (type == PathIterator.SEG_CLOSE) {
+                        closeIndex = typeSize;
+                    }
+                    types[typeSize++] = type;
+                }
+            }
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Join.
+         * 
+         * @param p the p
+         */
+        void join(BufferedPath p) {
+            // Skip MOVETO
+            checkBuf(p.typeSize - 1, p.pointSize - 2);
+            System.arraycopy(p.points, 2, points, pointSize, p.pointSize - 2);
+            System.arraycopy(p.types, 1, types, typeSize, p.typeSize - 1);
+            pointSize += p.pointSize - 2;
+            typeSize += p.typeSize - 1;
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Combine.
+         * 
+         * @param p the p
+         */
+        void combine(BufferedPath p) {
+            checkBuf(p.typeSize - 1, p.pointSize - 2);
+            // Skip last point, beacause it's the first point of the second path
+            for(int i = p.pointSize - 4; i >= 0; i -= 2) {
+                points[pointSize++] = p.points[i + 0];
+                points[pointSize++] = p.points[i + 1];
+            }
+            // Skip first type, beacuse it's always MOVETO
+            for(int i = p.typeSize - 1; i >= 1; i--) {
+                types[typeSize++] = p.types[i];
+            }
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Creates the general path.
+         * 
+         * @return the general path
+         */
+        GeneralPath createGeneralPath() {
+            GeneralPath p = new GeneralPath();
+            int j = 0;
+            for(int i = 0; i < typeSize; i++) {
+                int type = types[i];
+                switch(type){
+                case PathIterator.SEG_MOVETO:
+                    p.moveTo(points[j], points[j + 1]);
+                    break;
+                case PathIterator.SEG_LINETO:
+                    p.lineTo(points[j], points[j + 1]);
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    p.quadTo(points[j], points[j + 1], points[j + 2], points[j + 3]);
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    p.curveTo(points[j], points[j + 1], points[j + 2], points[j + 3], points[j + 4], points[j + 5]);
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    p.closePath();
+                    break;
+                }
+                j += pointShift[type];
+            }
+            return p;
+        }
+
+    }
+
+}
+
diff --git a/awt/java/awt/BufferCapabilities.java b/awt/java/awt/BufferCapabilities.java
new file mode 100644
index 0000000..80e8add
--- /dev/null
+++ b/awt/java/awt/BufferCapabilities.java
@@ -0,0 +1,185 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+
+/**
+ * The BufferCapabilities class represents the capabilities 
+ * and other properties of the image buffers.
+ */
+public class BufferCapabilities implements Cloneable {
+    
+    /** The front buffer capabilities. */
+    private final ImageCapabilities frontBufferCapabilities;
+    
+    /** The back buffer capabilities. */
+    private final ImageCapabilities backBufferCapabilities;
+    
+    /** The flip contents. */
+    private final FlipContents flipContents;
+
+    /**
+     * Instantiates a new BufferCapabilities object.
+     * 
+     * @param frontBufferCapabilities the front buffer capabilities, 
+     * can not be null.
+     * @param backBufferCapabilities the the back and intermediate 
+     * buffers capabilities, can not be null.
+     * @param flipContents the back buffer contents after page flipping, 
+     * null if page flipping is not used.
+     */
+    public BufferCapabilities(ImageCapabilities frontBufferCapabilities, 
+            ImageCapabilities backBufferCapabilities, FlipContents flipContents) {
+        if (frontBufferCapabilities == null || backBufferCapabilities == null) {
+            throw new IllegalArgumentException();
+        }
+
+        this.frontBufferCapabilities = frontBufferCapabilities;
+        this.backBufferCapabilities = backBufferCapabilities;
+        this.flipContents = flipContents;
+    }
+
+    /**
+     * Returns a copy of the BufferCapabilities object.
+     * 
+     * @return a copy of the BufferCapabilities object.
+     */
+    @Override
+    public Object clone() {
+        return new BufferCapabilities(frontBufferCapabilities, backBufferCapabilities, flipContents);
+    }
+
+    /**
+     * Gets the image capabilities of the front buffer.
+     * 
+     * @return the ImageCapabilities object represented capabilities 
+     * of the front buffer. 
+     */
+    public ImageCapabilities getFrontBufferCapabilities() {
+        return frontBufferCapabilities;
+    }
+
+    /**
+     * Gets the image capabilities of the back buffer.
+     * 
+     * @return the ImageCapabilities object represented capabilities 
+     * of the back buffer. 
+     */
+    public ImageCapabilities getBackBufferCapabilities() {
+        return backBufferCapabilities;
+    }
+
+    /**
+     * Gets the flip contents of the back buffer after page-flipping. 
+     * 
+     * @return the FlipContents of the back buffer after page-flipping.
+     */
+    public FlipContents getFlipContents() {
+        return flipContents;
+    }
+
+    /**
+     * Checks if the buffer strategy uses page flipping.
+     * 
+     * @return true, if the buffer strategy uses page flipping,
+     * false otherwise.
+     */
+    public boolean isPageFlipping() {
+        return flipContents != null;
+    }
+
+    /**
+     * Checks if page flipping is only available in full-screen mode.
+     * 
+     * @return true, if page flipping is only available in full-screen mode,
+     * false otherwise.
+     */
+    public boolean isFullScreenRequired() {
+        return false;
+    }
+
+    /**
+     * Checks if page flipping can be performed using more than two buffers.
+     * 
+     * @return true, if page flipping can be performed using more than two buffers,
+     * false otherwise.
+     */
+    public boolean isMultiBufferAvailable() {
+        return false;
+    }
+
+    /**
+     * The FlipContents class represents a set of possible back buffer contents 
+     * after page-flipping.
+     */
+    public static final class FlipContents {
+        
+        /**
+         * The back buffered contents are cleared with the background color 
+         * after flipping.
+         */
+        public static final FlipContents BACKGROUND = new FlipContents();
+        
+        /** 
+         * The back buffered contents are copied to the front buffer before 
+         * flipping.
+         */
+        public static final FlipContents COPIED = new FlipContents();
+        
+        /** 
+         * The back buffer contents are the prior contents of the 
+         * front buffer.
+         */
+        public static final FlipContents PRIOR = new FlipContents();
+        
+        /** 
+         * The back buffer contents are undefined after flipping 
+         */
+        public static final FlipContents UNDEFINED = new FlipContents();
+
+        /**
+         * Instantiates a new flip contents.
+         */
+        private FlipContents() {
+
+        }
+
+        /**
+         * Returns the hash code of the FlipContents object.
+         * 
+         * @return the hash code of the FlipContents object.
+         */
+        @Override
+        public int hashCode() {
+            return super.hashCode();
+        }
+
+        /**
+         * Returns the String representation of the FlipContents object.
+         * 
+         * @return the string
+         */
+        @Override
+        public String toString() {
+            return super.toString();
+        }
+    }
+}
diff --git a/awt/java/awt/Color.java b/awt/java/awt/Color.java
new file mode 100644
index 0000000..e1e4178
--- /dev/null
+++ b/awt/java/awt/Color.java
@@ -0,0 +1,881 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Color class defines colors in the default sRGB color 
+ * space or in the specified ColorSpace. Every Color contains alpha value.
+ * The alpha value defines the transparency of a color and can be represented
+ * by a float value in the range 0.0 - 1.0 or 0 - 255. 
+  */
+public class Color implements Paint, Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 118526816881161077L;
+
+    /*
+     * The values of the following colors are based on 1.5 release behavior which
+     * can be revealed using the following or similar code:
+     *   Color c = Color.white;
+     *   System.out.println(c);
+     */
+
+    /** The color white. */
+    public static final Color white = new Color(255, 255, 255);
+
+    /** The color white. */
+    public static final Color WHITE = white;
+
+    /** The color light gray. */
+    public static final Color lightGray = new Color(192, 192, 192);
+
+    /** The color light gray. */
+    public static final Color LIGHT_GRAY = lightGray;
+
+    /** The color gray. */
+    public static final Color gray = new Color(128, 128, 128);
+
+    /** The color gray. */
+    public static final Color GRAY = gray;
+
+    /** The color dark gray. */
+    public static final Color darkGray = new Color(64, 64, 64);
+
+    /** The color dark gray. */
+    public static final Color DARK_GRAY = darkGray;
+
+    /** The color black. */
+    public static final Color black = new Color(0, 0, 0);
+
+    /** The color black. */
+    public static final Color BLACK = black;
+
+    /** The color red. */
+    public static final Color red = new Color(255, 0, 0);
+
+    /** The color red. */
+    public static final Color RED = red;
+
+    /** The color pink. */
+    public static final Color pink = new Color(255, 175, 175);
+
+    /** The color pink. */
+    public static final Color PINK = pink;
+
+    /** The color orange. */
+    public static final Color orange = new Color(255, 200, 0);
+
+    /** The color orange. */
+    public static final Color ORANGE = orange;
+
+    /** The color yellow. */
+    public static final Color yellow = new Color(255, 255, 0);
+
+    /** The color yellow. */
+    public static final Color YELLOW = yellow;
+
+    /** The color green. */
+    public static final Color green = new Color(0, 255, 0);
+
+    /** The color green. */
+    public static final Color GREEN = green;
+
+    /** The color magenta. */
+    public static final Color magenta = new Color(255, 0, 255);
+
+    /** The color magenta. */
+    public static final Color MAGENTA = magenta;
+
+    /** The color cyan. */
+    public static final Color cyan = new Color(0, 255, 255);
+
+    /** The color cyan. */
+    public static final Color CYAN = cyan;
+
+    /** The color blue. */
+    public static final Color blue = new Color(0, 0, 255);
+
+    /** The color blue. */
+    public static final Color BLUE = blue;
+
+    /** integer RGB value. */
+    int value;
+
+    /** Float sRGB value. */
+    private float[] frgbvalue;
+
+    /** Color in an arbitrary color space with <code>float</code> components. If null, other value should be used. */
+    private float fvalue[];
+
+    /** Float alpha value. If frgbvalue is null, this is not valid data. */
+    private float falpha;
+
+    /** The color's color space if applicable. */
+    private ColorSpace cs;
+
+    /*
+     * The value of the SCALE_FACTOR is based on 1.5 release behavior which
+     * can be revealed using the following code:
+     *   Color c = new Color(100, 100, 100);
+     *   Color bc = c.brighter();
+     *   System.out.println("Brighter factor: " + ((float)c.getRed())/((float)bc.getRed()));
+     *   Color dc = c.darker();
+     *   System.out.println("Darker factor: " + ((float)dc.getRed())/((float)c.getRed()));
+     * The result is the same for brighter and darker methods, so we need only
+     * one scale factor for both.
+     */
+    /** The Constant SCALE_FACTOR. */
+    private static final double SCALE_FACTOR = 0.7;
+
+    /** The Constant MIN_SCALABLE. */
+    private static final int MIN_SCALABLE = 3; // should increase when multiplied by SCALE_FACTOR
+
+    /** The current paint context. */
+    transient private PaintContext currentPaintContext;
+
+    /**
+     * Creates a color in the specified ColorSpace, the specified color 
+     * components and the specified alpha. 
+     * 
+     * @param cspace the ColorSpace to be used to define the components.
+     * @param components the components.
+     * @param alpha the alpha.
+     */
+    public Color(ColorSpace cspace, float[] components, float alpha) {
+        int nComps = cspace.getNumComponents();
+        float comp;
+        fvalue = new float[nComps];
+
+        for(int i=0 ; i<nComps; i++) {
+            comp = components[i];
+            if(comp < 0.0f || comp > 1.0f) {
+                // awt.107=Color parameter outside of expected range: component {0}.
+                throw new IllegalArgumentException(
+                        Messages.getString("awt.107", i)); //$NON-NLS-1$
+            }
+            fvalue[i] = components[i];
+        }
+
+        if (alpha < 0.0f || alpha > 1.0f) {
+            // awt.108=Alpha value outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.108")); //$NON-NLS-1$
+        }
+        falpha = alpha;
+
+        cs = cspace;
+
+        frgbvalue = cs.toRGB(fvalue);
+
+        value =  ((int)(frgbvalue[2]*255 + 0.5))    |
+                (((int)(frgbvalue[1]*255 + 0.5)) << 8 )  |
+                (((int)(frgbvalue[0]*255 + 0.5)) << 16 ) |
+                (((int)(falpha*255 + 0.5)) << 24 );
+    }
+
+    /**
+     * Instantiates a new sRGB color with the specified combined 
+     * RGBA value consisting of the alpha component in bits 24-31, 
+     * the red component in bits 16-23, the green component in bits 8-15, 
+     * and the blue component in bits 0-7. If the hasalpha argument is 
+     * false, the alpha has default value - 255.
+     * 
+     * @param rgba the RGBA components.
+     * @param hasAlpha alpha parameter is true if alpha bits are valid,
+     * false otherwise.
+     */
+    public Color(int rgba, boolean hasAlpha) {
+        if (!hasAlpha) {
+            value = rgba | 0xFF000000;
+        } else {
+            value = rgba;
+        }
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, blue and alpha 
+     * components.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     * @param a the alpha component.
+     */
+    public Color(int r, int g, int b, int a) {
+        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b || (a & 0xFF) != a) {
+            // awt.109=Color parameter outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
+        }
+        value = b | (g << 8) | (r << 16) | (a << 24);
+    }
+
+    /**
+     * Instantiates a new opaque sRGB color with the specified red, green, 
+     * and blue values. The Alpha component is set to the default - 1.0.
+     * 
+     * @param r the red component. 
+     * @param g the green component.
+     * @param b the blue component.
+     */
+    public Color(int r, int g, int b) {
+        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b) {
+            // awt.109=Color parameter outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
+        }
+        // 0xFF for alpha channel
+        value = b | (g << 8) | (r << 16) | 0xFF000000;
+    }
+
+    /**
+     * Instantiates a new sRGB color with the specified 
+     * RGB value consisting of the red component in bits 16-23, 
+     * the green component in bits 8-15, and the blue component 
+     * in bits 0-7. Alpha has default value - 255.
+     * 
+     * @param rgb the RGB components.
+     */
+    public Color(int rgb) {
+        value = rgb | 0xFF000000;
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, blue and alpha 
+     * components.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     * @param a the alpha component.
+     */
+    public Color(float r, float g, float b, float a) {
+        this((int)(r*255+0.5),
+                (int)(g*255+0.5),
+                (int)(b*255+0.5),
+                (int)(a*255+0.5));
+        falpha = a;
+        fvalue = new float[3];
+        fvalue[0] = r;
+        fvalue[1] = g;
+        fvalue[2] = b;
+        frgbvalue = fvalue;
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, and blue 
+     * components and default alfa value - 1.0.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     */
+    public Color(float r, float g, float b) {
+        this(r, g, b, 1.0f);
+    }
+
+    public PaintContext createContext(
+            ColorModel cm,
+            Rectangle r,
+            Rectangle2D r2d,
+            AffineTransform xform,
+            RenderingHints rhs
+    ) {
+        if(currentPaintContext != null) {
+            return currentPaintContext;
+        }
+        currentPaintContext = new Color.ColorPaintContext(value);
+        return currentPaintContext;
+    }
+
+    /**
+     * Returns a string representation of the Color object.
+     * 
+     * @return the string representation of the Color object.
+     */
+    @Override
+    public String toString() {
+        /*
+           The format of the string is based on 1.5 release behavior which
+           can be revealed using the following code:
+
+           Color c = new Color(1, 2, 3);
+           System.out.println(c);
+        */
+        
+        return getClass().getName() +
+                "[r=" + getRed() + //$NON-NLS-1$
+                ",g=" + getGreen() + //$NON-NLS-1$
+                ",b=" + getBlue() + //$NON-NLS-1$
+                "]"; //$NON-NLS-1$
+    }
+
+    /**
+     * Compares the specified Object to the Color.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is a Color whose 
+     * value is equal to this Color, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if(obj instanceof Color) {
+            return ((Color)obj).value == this.value;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a float array containing the color and alpha components of 
+     * the Color in the specified ColorSpace. 
+     * 
+     * @param colorSpace the specified ColorSpace.
+     * @param components the results of this method will be written to
+     * this float array. If null, a float array will be created.
+     * 
+     * @return the color and alpha components in a float array.
+     */
+    public float[] getComponents(ColorSpace colorSpace, float[] components) {
+        int nComps = colorSpace.getNumComponents();
+        if(components == null) {
+            components = new float[nComps+1];
+        }
+
+        getColorComponents(colorSpace, components);
+
+        if(frgbvalue != null) {
+            components[nComps] = falpha;
+        } else {
+            components[nComps] = getAlpha()/255f;
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a float array containing the color components of 
+     * the Color in the specified ColorSpace.
+     * 
+     * @param colorSpace the specified ColorSpace.
+     * @param components the results of this method will be written to
+     * this float array. If null, a float array will be created.
+     * 
+     * @return the color components in a float array.
+     */
+    public float[] getColorComponents(ColorSpace colorSpace, float[] components) {
+        float[] cieXYZComponents = getColorSpace().toCIEXYZ(getColorComponents(null));
+        float[] csComponents = colorSpace.fromCIEXYZ(cieXYZComponents);
+
+        if(components == null) {
+            return csComponents;
+        }
+
+        for(int i=0; i<csComponents.length; i++) {
+            components[i] = csComponents[i];
+        }
+
+        return components;
+    }
+
+    /**
+     * Gets the ColorSpace of this Color.
+     * 
+     * @return the ColorSpace object.
+     */
+    public ColorSpace getColorSpace() {
+        if (cs == null) {
+            cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        }
+
+        return cs;
+    }
+
+    /**
+     * Creates a new Color which is a darker than this Color
+     * according to a fixed scale factor.
+     * 
+     * @return the darker Color.
+     */
+    public Color darker() {
+        return new Color(
+                (int)(getRed()*SCALE_FACTOR),
+                (int)(getGreen()*SCALE_FACTOR),
+                (int)(getBlue()*SCALE_FACTOR));
+    }
+
+    /**
+     * Creates a new Color which is a brighter than this Color.
+     * 
+     * @return the brighter Color.
+     */
+    public Color brighter() {
+
+        int r = getRed();
+        int b = getBlue();
+        int g = getGreen();
+
+        if(r == 0 && b == 0 && g == 0) {
+            return new Color(MIN_SCALABLE, MIN_SCALABLE, MIN_SCALABLE);
+        }
+
+        if(r < MIN_SCALABLE && r != 0) {
+            r = MIN_SCALABLE;
+        } else {
+            r = (int) (r/SCALE_FACTOR);
+            r = (r > 255) ? 255 : r;
+        }
+
+        if(b < MIN_SCALABLE && b != 0) {
+            b = MIN_SCALABLE;
+        } else {
+            b = (int) (b/SCALE_FACTOR);
+            b = (b > 255) ? 255 : b;
+        }
+
+        if(g < MIN_SCALABLE && g != 0) {
+            g = MIN_SCALABLE;
+        } else {
+            g = (int) (g/SCALE_FACTOR);
+            g = (g > 255) ? 255 : g;
+        }
+
+        return new Color(r, g, b);
+    }
+
+    /**
+     * Returns a float array containing the color and alpha components of 
+     * the Color in the default sRGB color space. 
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the RGB color and alpha components in a float array.
+     */
+    public float[] getRGBComponents(float[] components) {
+        if(components == null) {
+            components = new float[4];
+        }
+
+        if(frgbvalue != null) {
+            components[3] = falpha;
+        } else {
+            components[3] = getAlpha()/255f;
+        }
+
+        getRGBColorComponents(components);
+
+        return components;
+    }
+
+    /**
+     * Returns a float array containing the color components of 
+     * the Color in the default sRGB color space. 
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the RGB color components in a float array.
+     */
+    public float[] getRGBColorComponents(float[] components) {
+        if(components == null) {
+            components = new float[3];
+        }
+
+        if(frgbvalue != null) {
+            components[2] = frgbvalue[2];
+            components[1] = frgbvalue[1];
+            components[0] = frgbvalue[0];
+        } else {
+            components[2] = getBlue()/255f;
+            components[1] = getGreen()/255f;
+            components[0] = getRed()/255f;
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a float array which contains the color and alpha components of 
+     * the Color in the ColorSpace of the Color.
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the color and alpha components in a float array.
+     */
+    public float[] getComponents(float[] components) {
+        if(fvalue == null) {
+            return getRGBComponents(components);
+        }
+
+        int nColorComps = fvalue.length;
+
+        if(components == null) {
+            components = new float[nColorComps+1];
+        }
+
+        getColorComponents(components);
+
+        components[nColorComps] = falpha;
+
+        return components;
+    }
+
+    /**
+     * Returns a float array which contains the color components of 
+     * the Color in the ColorSpace of the Color.
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the color components in a float array.
+     */
+    public float[] getColorComponents(float[] components) {
+        if(fvalue == null) {
+            return getRGBColorComponents(components);
+        }
+
+        if(components == null) {
+            components = new float[fvalue.length];
+        }
+
+        for(int i=0; i<fvalue.length; i++) {
+            components[i] = fvalue[i];
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a hash code of this Color object.
+     * 
+     * @return a hash code of this Color object.
+     */
+    @Override
+    public int hashCode() {
+        return value;
+    }
+
+    public int getTransparency() {
+        switch(getAlpha()) {
+            case 0xff:
+                return Transparency.OPAQUE;
+            case 0:
+                return Transparency.BITMASK;
+            default:
+                return Transparency.TRANSLUCENT;
+        }
+    }
+
+    /**
+     * Gets the red component of the Color in the range 0-255.
+     * 
+     * @return the red component of the Color.
+     */
+    public int getRed() {
+        return (value >> 16) & 0xFF;
+    }
+
+    /**
+     * Gets the RGB value that represents the color in the default sRGB ColorModel.
+     * 
+     * @return the RGB color value in the default sRGB ColorModel.
+     */
+    public int getRGB() {
+        return value;
+    }
+
+    /**
+     * Gets the green component of the Color in the range 0-255.
+     * 
+     * @return the green component of the Color.
+     */
+    public int getGreen() {
+        return (value >> 8) & 0xFF;
+    }
+
+    /**
+     * Gets the blue component of the Color in the range 0-255.
+     * 
+     * @return the blue component of the Color.
+     */
+    public int getBlue() {
+        return value & 0xFF;
+    }
+
+    /**
+     * Gets the alpha component of the Color in the range 0-255.
+     * 
+     * @return the alpha component of the Color.
+     */
+    public int getAlpha() {
+        return (value >> 24) & 0xFF;
+    }
+
+    /**
+     * Gets the Color from the specified string, or returns the Color
+     * specified by the second parameter.
+     * 
+     * @param nm the specified string.
+     * @param def the default Color.
+     * 
+     * @return the color from the specified string, or the Color
+     * specified by the second parameter.
+     */
+    public static Color getColor(String nm, Color def) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return def;
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets the Color from the specified string, or returns the Color converted
+     * from the second parameter.
+     * 
+     * @param nm the specified string.
+     * @param def the default Color.
+     * 
+     * @return the color from the specified string, or the Color
+     * converted from the second parameter.
+     */
+    public static Color getColor(String nm, int def) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return new Color(def);
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets the Color from the specified String.
+     * 
+     * @param nm the specified string.
+     * 
+     * @return the Color object, or null.
+     */
+    public static Color getColor(String nm) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return null;
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Decodes a String to an integer and returns the specified opaque Color.
+     * 
+     * @param nm a String which represents an opaque color as a 24-bit integer.
+     * 
+     * @throws NumberFormatException if the specified string can not be
+     * converted to an integer.
+     */
+    public static Color decode(String nm) throws NumberFormatException {
+        Integer integer = Integer.decode(nm);
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets a Color object using the specified values of the HSB color model.
+     * 
+     * @param h the hue component of the Color.
+     * @param s the saturation of the Color.
+     * @param b the brightness of the Color.
+     * 
+     * @return a color object with the specified hue, saturation and 
+     * brightness values.
+     */
+    public static Color getHSBColor(float h, float s, float b) {
+        return new Color(HSBtoRGB(h, s, b));
+    }
+
+    /**
+     * Converts the Color specified by the RGB model to an equivalent 
+     * color in the HSB model.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     * @param hsbvals the array of result hue, saturation, brightness
+     * values or null.
+     * 
+     * @return the float array of hue, saturation, brightness values.
+     */
+    public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
+        if(hsbvals == null) {
+            hsbvals = new float[3];
+        }
+
+        int V = Math.max(b, Math.max(r, g));
+        int temp = Math.min(b, Math.min(r, g));
+
+        float H, S, B;
+
+        B = V/255.f;
+
+        if(V == temp) {
+            H = S = 0;
+        } else {
+            S = (V - temp)/((float)V);
+
+            float Cr = (V - r) / (float)(V - temp);
+            float Cg = (V - g) / (float)(V - temp);
+            float Cb = (V - b) / (float)(V - temp);
+
+            if (r == V) {
+                H = Cb - Cg;
+            } else if (g == V) {
+                H = 2 + Cr - Cb;
+            } else {
+                H = 4 + Cg - Cr;
+            }
+
+            H /= 6.f;
+            if(H < 0) {
+                H++;
+            }
+        }
+
+        hsbvals[0] = H;
+        hsbvals[1] = S;
+        hsbvals[2] = B;
+
+        return hsbvals;
+    }
+
+    /**
+     * Converts the Color specified by the HSB model to an equivalent 
+     * color in the default RGB model.
+     * 
+     * @param hue the hue component of the Color.
+     * @param saturation the saturation of the Color.
+     * @param brightness the brightness of the Color.
+     * 
+     * @return the RGB value of the color with the specified hue, 
+     * saturation and brightness.
+     */
+    public static int HSBtoRGB(float hue, float saturation, float brightness) {
+        float fr, fg, fb;
+
+        if(saturation == 0) {
+            fr = fg = fb = brightness;
+        } else {
+            float H = (hue - (float)Math.floor(hue)) * 6;
+            int I = (int) Math.floor(H);
+            float F = H - I;
+            float M = brightness * (1 - saturation);
+            float N = brightness * (1 - saturation * F);
+            float K = brightness * (1 - saturation * (1 - F));
+
+            switch(I) {
+                case 0:
+                    fr = brightness; fg = K; fb = M; break;
+                case 1:
+                    fr = N; fg = brightness; fb = M; break;
+                case 2:
+                    fr = M; fg = brightness; fb = K; break;
+                case 3:
+                    fr = M; fg = N; fb = brightness; break;
+                case 4:
+                    fr = K; fg = M; fb = brightness; break;
+                case 5:
+                    fr = brightness; fg = M; fb = N; break;
+                default:
+                    fr = fb = fg = 0; // impossible, to supress compiler error
+            }
+        }
+
+        int r = (int) (fr * 255. + 0.5);
+        int g = (int) (fg * 255. + 0.5);
+        int b = (int) (fb * 255. + 0.5);
+
+        return (r << 16) | (g << 8) | b | 0xFF000000;
+    }
+
+    /**
+     * The Class ColorPaintContext.
+     */
+    class ColorPaintContext implements PaintContext {
+        
+        /** The rgb value. */
+        int rgbValue;
+        
+        /** The saved raster. */
+        WritableRaster savedRaster = null;
+
+        /**
+         * Instantiates a new color paint context.
+         * 
+         * @param rgb the rgb
+         */
+        protected ColorPaintContext(int rgb) {
+            rgbValue = rgb;
+        }
+
+        public void dispose() {
+            savedRaster = null;
+        }
+
+        public ColorModel getColorModel() {
+            return ColorModel.getRGBdefault();
+        }
+
+        public Raster getRaster(int x, int y, int w, int h) {
+            if (savedRaster == null ||
+                    w != savedRaster.getWidth() ||
+                    h != savedRaster.getHeight()) {
+                savedRaster =
+                        getColorModel().createCompatibleWritableRaster(w, h);
+
+                // Suppose we have here simple INT/RGB color/sample model
+                DataBufferInt intBuffer =
+                        (DataBufferInt) savedRaster.getDataBuffer();
+                int rgbValues[] = intBuffer.getData();
+                int rgbFillValue = rgbValue;
+                Arrays.fill(rgbValues, rgbFillValue);
+            }
+
+            return savedRaster;
+        }
+    }
+}
+
diff --git a/awt/java/awt/Component.java b/awt/java/awt/Component.java
new file mode 100644
index 0000000..f19d285
--- /dev/null
+++ b/awt/java/awt/Component.java
@@ -0,0 +1,6408 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+//import java.awt.dnd.DropTarget;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.HierarchyBoundsListener;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InputMethodListener;
+import java.awt.event.InvocationEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
+import java.awt.im.InputContext;
+import java.awt.im.InputMethodRequests;
+import java.awt.image.BufferStrategy;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.awt.peer.ComponentPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+//???AWT
+//import javax.accessibility.Accessible;
+//import javax.accessibility.AccessibleComponent;
+//import javax.accessibility.AccessibleContext;
+//import javax.accessibility.AccessibleRole;
+//import javax.accessibility.AccessibleState;
+//import javax.accessibility.AccessibleStateSet;
+
+import org.apache.harmony.awt.ClipRegion;
+//import org.apache.harmony.awt.FieldsAccessor;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.state.State;
+//import org.apache.harmony.awt.text.TextFieldKit;
+//import org.apache.harmony.awt.text.TextKit;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+/**
+ * The abstract Component class specifies an object with a graphical 
+ * representation that can be displayed on the screen and that can 
+ * interact with the user (for example: scrollbars, buttons, checkboxes).
+ */
+public abstract class Component implements ImageObserver, MenuContainer, Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -7644114512714619750L;
+
+    /** The Constant TOP_ALIGNMENT indicates the top alignment of the component. */
+    public static final float TOP_ALIGNMENT = 0.0f;
+
+    /** The Constant CENTER_ALIGNMENT indicates the center alignment of the component. */
+    public static final float CENTER_ALIGNMENT = 0.5f;
+
+    /** The Constant BOTTOM_ALIGNMENT indicates the bottom alignment of the component. */
+    public static final float BOTTOM_ALIGNMENT = 1.0f;
+
+    /** The Constant LEFT_ALIGNMENT indicates the left alignment of the component. */
+    public static final float LEFT_ALIGNMENT = 0.0f;
+
+    /** The Constant RIGHT_ALIGNMENT indicates the right alignment of the component. */
+    public static final float RIGHT_ALIGNMENT = 1.0f;
+
+    /** The Constant childClassesFlags. */
+    private static final Hashtable<Class<?>, Boolean> childClassesFlags = new Hashtable<Class<?>, Boolean>();
+
+    /** The Constant peer. */
+    private static final ComponentPeer peer = new ComponentPeer() {
+    };
+
+    /** The Constant incrementalImageUpdate. */
+    private static final boolean incrementalImageUpdate;
+
+    /** The toolkit. */
+    final transient Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+    //???AWT
+    /*
+    protected abstract class AccessibleAWTComponent extends AccessibleContext implements
+            Serializable, AccessibleComponent {
+        private static final long serialVersionUID = 642321655757800191L;
+
+        protected class AccessibleAWTComponentHandler implements ComponentListener {
+            protected AccessibleAWTComponentHandler() {
+            }
+
+            public void componentHidden(ComponentEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                        AccessibleState.VISIBLE, null);
+            }
+
+            public void componentMoved(ComponentEvent e) {
+            }
+
+            public void componentResized(ComponentEvent e) {
+            }
+
+            public void componentShown(ComponentEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
+                        AccessibleState.VISIBLE);
+            }
+        }
+
+        protected class AccessibleAWTFocusHandler implements FocusListener {
+            public void focusGained(FocusEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
+                        AccessibleState.FOCUSED);
+            }
+
+            public void focusLost(FocusEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                        AccessibleState.FOCUSED, null);
+            }
+        }
+    
+        protected ComponentListener accessibleAWTComponentHandler;
+    
+        protected FocusListener accessibleAWTFocusHandler;
+        */
+        /*
+         * Number of registered property change listeners.
+         */
+        /*
+        int listenersCount;
+
+        public void addFocusListener(FocusListener l) {
+            Component.this.addFocusListener(l);
+        }
+
+        @Override
+        public void addPropertyChangeListener(PropertyChangeListener listener) {
+            toolkit.lockAWT();
+            try {
+                super.addPropertyChangeListener(listener);
+                listenersCount++;
+                if (accessibleAWTComponentHandler == null) {
+                    accessibleAWTComponentHandler = new AccessibleAWTComponentHandler();
+                    Component.this.addComponentListener(accessibleAWTComponentHandler);
+                }
+                if (accessibleAWTFocusHandler == null) {
+                    accessibleAWTFocusHandler = new AccessibleAWTFocusHandler();
+                    Component.this.addFocusListener(accessibleAWTFocusHandler);
+                }
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+        
+        public boolean contains(Point p) {
+            toolkit.lockAWT();
+            try {
+                return Component.this.contains(p);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Accessible getAccessibleAt(Point arg0) {
+            toolkit.lockAWT();
+            try {
+                return null;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Color getBackground() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getBackground();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Rectangle getBounds() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getBounds();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Cursor getCursor() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getCursor();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Font getFont() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getFont();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public FontMetrics getFontMetrics(Font f) {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getFontMetrics(f);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Color getForeground() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getForeground();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Point getLocation() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getLocation();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Point getLocationOnScreen() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getLocationOnScreen();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Dimension getSize() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getSize();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isEnabled() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isEnabled();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isFocusTraversable() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isFocusTraversable();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isShowing() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isShowing();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isVisible() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isVisible();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void removeFocusListener(FocusListener l) {
+            Component.this.removeFocusListener(l);
+        }
+
+        @Override
+        public void removePropertyChangeListener(PropertyChangeListener listener) {
+            toolkit.lockAWT();
+            try {
+                super.removePropertyChangeListener(listener);
+                listenersCount--;
+                if (listenersCount > 0) {
+                    return;
+                }
+                // if there are no more listeners, remove handlers:
+                Component.this.removeFocusListener(accessibleAWTFocusHandler);
+                Component.this.removeComponentListener(accessibleAWTComponentHandler);
+                accessibleAWTComponentHandler = null;
+                accessibleAWTFocusHandler = null;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void requestFocus() {
+            toolkit.lockAWT();
+            try {
+                Component.this.requestFocus();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setBackground(Color color) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setBackground(color);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setBounds(Rectangle r) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setBounds(r);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setCursor(Cursor cursor) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setCursor(cursor);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setEnabled(boolean enabled) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setEnabled(enabled);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setFont(Font f) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setFont(f);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setForeground(Color color) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setForeground(color);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setLocation(Point p) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setLocation(p);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setSize(Dimension size) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setSize(size);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setVisible(boolean visible) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setVisible(visible);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+        
+        @Override
+        public Accessible getAccessibleParent() {
+            toolkit.lockAWT();
+            try {
+                Accessible aParent = super.getAccessibleParent();
+                if (aParent != null) {
+                    return aParent;
+                }
+                Container parent = getParent();
+                return (parent instanceof Accessible ? (Accessible) parent : null);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public Accessible getAccessibleChild(int i) {
+            toolkit.lockAWT();
+            try {
+                return null;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public int getAccessibleChildrenCount() {
+            toolkit.lockAWT();
+            try {
+                return 0;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleComponent getAccessibleComponent() {
+            return this;
+        }
+
+        @Override
+        public String getAccessibleDescription() {
+            return super.getAccessibleDescription(); // why override?
+        }
+
+        @Override
+        public int getAccessibleIndexInParent() {
+            toolkit.lockAWT();
+            try {
+                if (getAccessibleParent() == null) {
+                    return -1;
+                }
+                int count = 0;
+                Container parent = getParent();
+                for (int i = 0; i < parent.getComponentCount(); i++) {
+                    Component aComp = parent.getComponent(i);
+                    if (aComp instanceof Accessible) {
+                        if (aComp == Component.this) {
+                            return count;
+                        }
+                        ++count;
+                    }
+                }
+                return -1;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleRole getAccessibleRole() {
+            toolkit.lockAWT();
+            try {
+                return AccessibleRole.AWT_COMPONENT;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleStateSet getAccessibleStateSet() {
+            toolkit.lockAWT();
+            try {
+                AccessibleStateSet set = new AccessibleStateSet();
+                if (isEnabled()) {
+                    set.add(AccessibleState.ENABLED);
+                }
+                if (isFocusable()) {
+                    set.add(AccessibleState.FOCUSABLE);
+                }
+                if (hasFocus()) {
+                    set.add(AccessibleState.FOCUSED);
+                }
+                if (isOpaque()) {
+                    set.add(AccessibleState.OPAQUE);
+                }
+                if (isShowing()) {
+                    set.add(AccessibleState.SHOWING);
+                }
+                if (isVisible()) {
+                    set.add(AccessibleState.VISIBLE);
+                }
+                return set;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public Locale getLocale() throws IllegalComponentStateException {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getLocale();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+    }
+    */
+    /**
+     * The BltBufferStrategy class provides opportunity of blitting 
+     * offscreen surfaces to a component. For more information on 
+     * blitting, see <a href="http://en.wikipedia.org/wiki/Bit_blit">Bit blit</a>.
+     */
+    protected class BltBufferStrategy extends BufferStrategy {
+        
+        /** The back buffers. */
+        protected VolatileImage[] backBuffers;
+
+        /** The caps. */
+        protected BufferCapabilities caps;
+
+        /** The width. */
+        protected int width;
+
+        /** The height. */
+        protected int height;
+
+        /** The validated contents. */
+        protected boolean validatedContents;
+
+        /**
+         * Instantiates a new BltBufferStrategy buffer strategy.
+         * 
+         * @param numBuffers the number of buffers.
+         * @param caps the BufferCapabilities.
+         * 
+         * @throws NotImplementedException the not implemented exception.
+         */
+        protected BltBufferStrategy(int numBuffers, BufferCapabilities caps) throws org.apache.harmony.luni.util.NotImplementedException {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Returns true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics. 
+         * 
+         * @return true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics, false otherwise.
+         *  
+         * @see java.awt.image.BufferStrategy#contentsLost()
+         */
+        @Override
+        public boolean contentsLost() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color.
+         * 
+         * @return true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color,
+         * false otherwise.
+         *           
+         * @see java.awt.image.BufferStrategy#contentsRestored()
+         */
+        @Override
+        public boolean contentsRestored() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Creates the back buffers.
+         * 
+         * @param numBuffers the number of buffers.
+         */
+        protected void createBackBuffers(int numBuffers) {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Returns the BufferCapabilities of the buffer strategy.
+         * 
+         * @return the BufferCapabilities.
+         * 
+         * @see java.awt.image.BufferStrategy#getCapabilities()
+         */
+        @Override
+        public BufferCapabilities getCapabilities() {
+            return (BufferCapabilities) caps.clone();
+        }
+
+        /**
+         * Gets Graphics of current buffer strategy.
+         * 
+         * @return the Graphics of current buffer strategy.
+         * 
+         * @see java.awt.image.BufferStrategy#getDrawGraphics()
+         */
+        @Override
+        public Graphics getDrawGraphics() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Revalidates the lost drawing buffer.
+         */
+        protected void revalidate() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Shows the next available buffer.
+         * 
+         * @see java.awt.image.BufferStrategy#show()
+         */
+        @Override
+        public void show() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * The FlipBufferStrategy class is for flipping buffers on a component. 
+     */
+    protected class FlipBufferStrategy extends BufferStrategy {
+        
+        /** The Buffer Capabilities. */
+        protected BufferCapabilities caps;
+
+        /** The drawing buffer. */
+        protected Image drawBuffer;
+
+        /** The drawing VolatileImage buffer. */
+        protected VolatileImage drawVBuffer;
+
+        /** The number of buffers. */
+        protected int numBuffers;
+
+        /** The validated contents indicates if the drawing buffer is restored from
+         * lost state. */
+        protected boolean validatedContents;
+
+        /**
+         * Instantiates a new flip buffer strategy.
+         * 
+         * @param numBuffers the number of buffers.
+         * @param caps the BufferCapabilities.
+         * 
+         * @throws AWTException if the capabilities supplied could not 
+         * be supported or met.
+         */
+        protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
+                throws AWTException {
+            //???AWT
+            /*
+            if (!(Component.this instanceof Window) && !(Component.this instanceof Canvas)) {
+                // awt.14B=Only Canvas or Window is allowed
+                throw new ClassCastException(Messages.getString("awt.14B")); //$NON-NLS-1$
+            }
+            */
+            // TODO: throw new AWTException("Capabilities are not supported");
+            this.numBuffers = numBuffers;
+            this.caps = (BufferCapabilities) caps.clone();
+        }
+
+        /**
+         * Returns true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics. 
+         * 
+         * @return true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics, false otherwise.
+         * 
+         * @see java.awt.image.BufferStrategy#contentsLost()
+         */
+        @Override
+        public boolean contentsLost() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color.
+         * 
+         * @return true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color,
+         * false otherwise. 
+         * 
+         * @see java.awt.image.BufferStrategy#contentsRestored()
+         */
+        @Override
+        public boolean contentsRestored() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Creates flipping buffers with the specified buffer capabilities.
+         * 
+         * @param numBuffers the number of buffers.
+         * @param caps the BufferCapabilities.
+         * 
+         * @throws AWTException if the capabilities could not be 
+         * supported or met.
+         */
+        protected void createBuffers(int numBuffers, BufferCapabilities caps)
+                throws AWTException {
+            if (numBuffers < 2) {
+                // awt.14C=Number of buffers must be greater than one
+                throw new IllegalArgumentException(Messages.getString("awt.14C")); //$NON-NLS-1$
+            }
+            if (!caps.isPageFlipping()) {
+                // awt.14D=Buffer capabilities should support flipping
+                throw new IllegalArgumentException(Messages.getString("awt.14D")); //$NON-NLS-1$
+            }
+            if (!Component.this.behaviour.isDisplayable()) {
+                // awt.14E=Component should be displayable
+                throw new IllegalStateException(Messages.getString("awt.14E")); //$NON-NLS-1$
+            }
+            // TODO: throw new AWTException("Capabilities are not supported");
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Destroy buffers.
+         */
+        protected void destroyBuffers() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Flips the contents of the back buffer to the front buffer.
+         * 
+         * @param flipAction the flip action.
+         */
+        protected void flip(BufferCapabilities.FlipContents flipAction) {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Gets the back buffer as Image.
+         * 
+         * @return the back buffer as Image.
+         */
+        protected Image getBackBuffer() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Returns the BufferCapabilities of the buffer strategy.
+         * 
+         * @return the BufferCapabilities.
+         * 
+         * @see java.awt.image.BufferStrategy#getCapabilities()
+         */
+        @Override
+        public BufferCapabilities getCapabilities() {
+            return (BufferCapabilities) caps.clone();
+        }
+
+        /**
+         * Gets Graphics of current buffer strategy.
+         * 
+         * @return the Graphics of current buffer strategy.
+         * 
+         * @see java.awt.image.BufferStrategy#getDrawGraphics()
+         */
+        @Override
+        public Graphics getDrawGraphics() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Revalidates the lost drawing buffer.
+         */
+        protected void revalidate() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Shows the next available buffer.
+         * 
+         * @see java.awt.image.BufferStrategy#show()
+         */
+        @Override
+        public void show() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * The internal component's state utilized by the visual theme.
+     */
+    class ComponentState implements State {
+        
+        /** The default minimum size. */
+        private Dimension defaultMinimumSize = new Dimension();
+
+        /**
+         * Checks if the component is enabled.
+         * 
+         * @return true, if the component is enabled
+         */
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        /**
+         * Checks if the component is visible.
+         * 
+         * @return true, if the component is visible
+         */
+        public boolean isVisible() {
+            return visible;
+        }
+
+        /**
+         * Checks if is focused.
+         * 
+         * @return true, if is focused
+         */
+        public boolean isFocused() {
+            //???AWT: return isFocusOwner();
+            return false;
+        }
+
+        /**
+         * Gets the font.
+         * 
+         * @return the font
+         */
+        public Font getFont() {
+            return Component.this.getFont();
+        }
+
+        /**
+         * Checks if the font has been set.
+         * 
+         * @return true, if the font has been set
+         */
+        public boolean isFontSet() {
+            return font != null;
+        }
+
+        /**
+         * Gets the background color.
+         * 
+         * @return the background color
+         */
+        public Color getBackground() {
+            Color c = Component.this.getBackground();
+            return (c != null) ? c : getDefaultBackground();
+        }
+
+        /**
+         * Checks if the background is set.
+         * 
+         * @return true, if the background is set
+         */
+        public boolean isBackgroundSet() {
+            return backColor != null;
+        }
+
+        /**
+         * Gets the text color.
+         * 
+         * @return the text color
+         */
+        public Color getTextColor() {
+            Color c = getForeground();
+            return (c != null) ? c : getDefaultForeground();
+        }
+
+        /**
+         * Checks if the text color is set.
+         * 
+         * @return true, if the text color is set
+         */
+        public boolean isTextColorSet() {
+            return foreColor != null;
+        }
+
+        /**
+         * Gets the font metrics.
+         * 
+         * @return the font metrics
+         */
+        @SuppressWarnings("deprecation")
+        public FontMetrics getFontMetrics() {
+            return toolkit.getFontMetrics(Component.this.getFont());
+        }
+
+        /**
+         * Gets the bounding rectangle.
+         * 
+         * @return the bounding rectangle
+         */
+        public Rectangle getBounds() {
+            return new Rectangle(x, y, w, h);
+        }
+
+        /**
+         * Gets the size of the bounding rectangle.
+         * 
+         * @return the size of the bounding rectangle
+         */
+        public Dimension getSize() {
+            return new Dimension(w, h);
+        }
+
+        /**
+         * Gets the window id.
+         * 
+         * @return the window id
+         */
+        public long getWindowId() {
+            NativeWindow win = getNativeWindow();
+            return (win != null) ? win.getId() : 0;
+        }
+
+        /**
+         * Gets the default minimum size.
+         * 
+         * @return the default minimum size
+         */
+        public Dimension getDefaultMinimumSize() {
+            if (defaultMinimumSize == null) {
+                calculate();
+            }
+            return defaultMinimumSize;
+        }
+
+        /**
+         * Sets the default minimum size.
+         * 
+         * @param size the new default minimum size
+         */
+        public void setDefaultMinimumSize(Dimension size) {
+            defaultMinimumSize = size;
+        }
+
+        /**
+         * Reset the default minimum size to null.
+         */
+        public void reset() {
+            defaultMinimumSize = null;
+        }
+
+        /**
+         * Calculate the default minimum size: to be overridden.
+         */
+        public void calculate() {
+            // to be overridden
+        }
+    }
+
+    //???AWT: private transient AccessibleContext accessibleContext;
+
+    /** The behaviour. */
+    final transient ComponentBehavior behaviour;
+
+    //???AWT: Container parent;
+
+    /** The name. */
+    private String name;
+
+    /** The auto name. */
+    private boolean autoName = true;
+
+    /** The font. */
+    private Font font;
+
+    /** The back color. */
+    private Color backColor;
+
+    /** The fore color. */
+    private Color foreColor;
+
+    /** The deprecated event handler. */
+    boolean deprecatedEventHandler = true;
+
+    /** The enabled events. */
+    private long enabledEvents;
+
+    /** The enabled awt events. */
+    private long enabledAWTEvents;
+
+    /** The component listeners. */
+    private final AWTListenerList<ComponentListener> componentListeners = new AWTListenerList<ComponentListener>(
+            this);
+
+    /** The focus listeners. */
+    private final AWTListenerList<FocusListener> focusListeners = new AWTListenerList<FocusListener>(
+            this);
+
+    /** The hierarchy listeners. */
+    private final AWTListenerList<HierarchyListener> hierarchyListeners = new AWTListenerList<HierarchyListener>(
+            this);
+
+    /** The hierarchy bounds listeners. */
+    private final AWTListenerList<HierarchyBoundsListener> hierarchyBoundsListeners = new AWTListenerList<HierarchyBoundsListener>(
+            this);
+
+    /** The key listeners. */
+    private final AWTListenerList<KeyListener> keyListeners = new AWTListenerList<KeyListener>(
+            this);
+
+    /** The mouse listeners. */
+    private final AWTListenerList<MouseListener> mouseListeners = new AWTListenerList<MouseListener>(
+            this);
+
+    /** The mouse motion listeners. */
+    private final AWTListenerList<MouseMotionListener> mouseMotionListeners = new AWTListenerList<MouseMotionListener>(
+            this);
+
+    /** The mouse wheel listeners. */
+    private final AWTListenerList<MouseWheelListener> mouseWheelListeners = new AWTListenerList<MouseWheelListener>(
+            this);
+
+    /** The input method listeners. */
+    private final AWTListenerList<InputMethodListener> inputMethodListeners = new AWTListenerList<InputMethodListener>(
+            this);
+
+    /** The x. */
+    int x;
+
+    /** The y. */
+    int y;
+
+    /** The w. */
+    int w;
+
+    /** The h. */
+    int h;
+
+    /** The maximum size. */
+    private Dimension maximumSize;
+
+    /** The minimum size. */
+    private Dimension minimumSize;
+
+    /** The preferred size. */
+    private Dimension preferredSize;
+
+    /** The bounds mask param. */
+    private int boundsMaskParam;
+
+    /** The ignore repaint. */
+    private boolean ignoreRepaint;
+
+    /** The enabled. */
+    private boolean enabled = true;
+
+    /** The input methods enabled. */
+    private boolean inputMethodsEnabled = true;
+
+    /** The dispatch to im. */
+    transient boolean dispatchToIM = true;
+
+    /** The focusable. */
+    private boolean focusable = true; // By default, all Components return
+
+    // true from isFocusable() method
+    /** The visible. */
+    boolean visible = true;
+
+    /** The called set focusable. */
+    private boolean calledSetFocusable;
+
+    /** The overriden is focusable. */
+    private boolean overridenIsFocusable = true;
+
+    /** The focus traversal keys enabled. */
+    private boolean focusTraversalKeysEnabled = true;
+
+    /** Possible keys are: FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, UP_CYCLE_TRAVERSAL_KEYS. */
+    private final Map<Integer, Set<? extends AWTKeyStroke>> traversalKeys = new HashMap<Integer, Set<? extends AWTKeyStroke>>();
+
+    /** The traversal i ds. */
+    int[] traversalIDs;
+
+    /** The locale. */
+    private Locale locale;
+
+    /** The orientation. */
+    private ComponentOrientation orientation;
+
+    /** The property change support. */
+    private PropertyChangeSupport propertyChangeSupport;
+
+    //???AWT: private ArrayList<PopupMenu> popups;
+
+    /** The coalescer. */
+    private boolean coalescer;
+
+    /** The events table. */
+    private Hashtable<Integer, LinkedList<AWTEvent>> eventsTable;
+
+    /** Cashed reference used during EventQueue.postEvent() */
+    private LinkedList<AWTEvent> eventsList;
+
+    /** The hierarchy changing counter. */
+    private int hierarchyChangingCounter;
+
+    /** The was showing. */
+    private boolean wasShowing;
+
+    /** The was displayable. */
+    private boolean wasDisplayable;
+
+    /** The cursor. */
+    Cursor cursor;
+
+    //???AWT: DropTarget dropTarget;
+
+    /** The mouse exited expected. */
+    private boolean mouseExitedExpected;
+
+    /** The repaint region. */
+    transient MultiRectArea repaintRegion;
+
+    //???AWT: transient RedrawManager redrawManager;
+    /** The redraw manager. */
+    transient Object redrawManager;
+
+    /** The valid. */
+    private boolean valid;
+
+    /** The updated images. */
+    private HashMap<Image, ImageParameters> updatedImages;
+
+    /**
+     * The lock object for private component's data which don't affect the
+     * component hierarchy.
+     */
+    private class ComponentLock {
+    }
+
+    /** The component lock. */
+    private final transient Object componentLock = new ComponentLock();
+    static {
+        PrivilegedAction<String[]> action = new PrivilegedAction<String[]>() {
+            public String[] run() {
+                String properties[] = new String[2];
+                properties[0] = System.getProperty("awt.image.redrawrate", "100"); //$NON-NLS-1$ //$NON-NLS-2$
+                properties[1] = System.getProperty("awt.image.incrementaldraw", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+                return properties;
+            }
+        };
+        String properties[] = AccessController.doPrivileged(action);
+        // FIXME: rate is never used, can this code and the get property above
+        // be removed?
+        // int rate;
+        //
+        // try {
+        // rate = Integer.decode(properties[0]).intValue();
+        // } catch (NumberFormatException e) {
+        // rate = 100;
+        // }
+        incrementalImageUpdate = properties[1].equals("true"); //$NON-NLS-1$
+    }
+
+    /**
+     * Instantiates a new component.
+     */
+    protected Component() {
+        toolkit.lockAWT();
+        try {
+            orientation = ComponentOrientation.UNKNOWN;
+            redrawManager = null;
+            //???AWT
+            /*
+            traversalIDs = this instanceof Container ? KeyboardFocusManager.contTraversalIDs
+                    : KeyboardFocusManager.compTraversalIDs;
+            for (int element : traversalIDs) {
+                traversalKeys.put(new Integer(element), null);
+            }
+            behaviour = createBehavior();
+            */
+            behaviour = null;
+            
+            deriveCoalescerFlag();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Determine that the class inherited from Component declares the method
+     * coalesceEvents(), and put the results to the childClassesFlags map.
+     */
+    private void deriveCoalescerFlag() {
+        Class<?> thisClass = getClass();
+        boolean flag = true;
+        synchronized (childClassesFlags) {
+            Boolean flagWrapper = childClassesFlags.get(thisClass);
+            if (flagWrapper == null) {
+                Method coalesceMethod = null;
+                for (Class<?> c = thisClass; c != Component.class; c = c.getSuperclass()) {
+                    try {
+                        coalesceMethod = c.getDeclaredMethod("coalesceEvents", new Class[] { //$NON-NLS-1$
+                                Class.forName("java.awt.AWTEvent"), //$NON-NLS-1$
+                                Class.forName("java.awt.AWTEvent") }); //$NON-NLS-1$
+                    } catch (Exception e) {
+                    }
+                    if (coalesceMethod != null) {
+                        break;
+                    }
+                }
+                flag = (coalesceMethod != null);
+                childClassesFlags.put(thisClass, Boolean.valueOf(flag));
+            } else {
+                flag = flagWrapper.booleanValue();
+            }
+        }
+        coalescer = flag;
+        if (flag) {
+            eventsTable = new Hashtable<Integer, LinkedList<AWTEvent>>();
+        } else {
+            eventsTable = null;
+        }
+    }
+
+    /**
+     * Sets the name of the Component.
+     * 
+     * @param name the new name of the Component.
+     */
+    public void setName(String name) {
+        String oldName;
+        toolkit.lockAWT();
+        try {
+            autoName = false;
+            oldName = this.name;
+            this.name = name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("name", oldName, name); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the name of this Component.
+     * 
+     * @return the name of this Component.
+     */
+    public String getName() {
+        toolkit.lockAWT();
+        try {
+            if ((name == null) && autoName) {
+                name = autoName();
+            }
+            return name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Auto name.
+     * 
+     * @return the string
+     */
+    String autoName() {
+        String name = getClass().getName();
+        if (name.indexOf("$") != -1) { //$NON-NLS-1$
+            return null;
+        }
+        //???AWT
+        //int number = toolkit.autoNumber.nextComponent++;
+        int number = 0;
+        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
+        return name;
+    }
+
+    /**
+     * Returns the string representation of the Component.
+     * 
+     * @return the string representation of the Component.
+     */
+    @Override
+    public String toString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code:
+         * 
+         * Component c = new Component(){}; c.setVisible(false);
+         * System.out.println(c);
+         */
+        toolkit.lockAWT();
+        try {
+            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    public void add(PopupMenu popup) {
+        toolkit.lockAWT();
+        try {
+            if (popup.getParent() == this) {
+                return;
+            }
+            if (popups == null) {
+                popups = new ArrayList<PopupMenu>();
+            }
+            popup.setParent(this);
+            popups.add(popup);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Returns true, if the component contains the specified Point.
+     * 
+     * @param p the Point.
+     * 
+     * @return true, if the component contains the specified Point,
+     * false otherwise.
+     */
+    public boolean contains(Point p) {
+        toolkit.lockAWT();
+        try {
+            return contains(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true, if the component contains the point with 
+     * the specified coordinates.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if the component contains the point with 
+     * the specified coordinates, false otherwise.
+     */
+    public boolean contains(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return inside(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by replaced by getSize() method.
+     * 
+     * @return the dimension.
+     * 
+     * @deprecated Replaced by getSize() method.
+     */
+    @Deprecated
+    public Dimension size() {
+        toolkit.lockAWT();
+        try {
+            return new Dimension(w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    
+    //???AWT
+    /*
+    public Container getParent() {
+        toolkit.lockAWT();
+        try {
+            return parent;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * List.
+     * 
+     * @param out the out
+     * @param indent the indent
+     * 
+     * @return the nearest heavyweight ancestor in hierarchy or
+     * <code>null</code> if not found
+     */
+    //???AWT
+    /*
+    Component getHWAncestor() {
+        return (parent != null ? parent.getHWSurface() : null);
+    }
+    */
+    
+    /**
+     * @return heavyweight component that is equal to or is a nearest
+     *         heavyweight container of the current component, or
+     *         <code>null</code> if not found
+     */
+    //???AWT
+    /*
+    Component getHWSurface() {
+        Component parent;
+        for (parent = this; (parent != null) && (parent.isLightweight()); parent = parent
+                .getParent()) {
+            ;
+        }
+        return parent;
+    }
+
+    Window getWindowAncestor() {
+        Component par;
+        for (par = this; par != null && !(par instanceof Window); par = par.getParent()) {
+            ;
+        }
+        return (Window) par;
+    }
+    */
+    
+    /** To be called by container */
+    //???AWT
+    /*
+    void setParent(Container parent) {
+        this.parent = parent;
+        setRedrawManager();
+    }
+
+    void setRedrawManager() {
+        redrawManager = getRedrawManager();
+    }
+
+    public void remove(MenuComponent menu) {
+        toolkit.lockAWT();
+        try {
+            if (menu.getParent() == this) {
+                menu.setParent(null);
+                popups.remove(menu);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    /**
+     * Prints a list of this component with the specified number of 
+     * leading whitespace characters to the specified PrintStream.
+     * 
+     * @param out the output PrintStream object.
+     * @param indent how many leading whitespace characters to prepend
+     */
+    public void list(PrintStream out, int indent) {
+        toolkit.lockAWT();
+        try {
+            out.println(getIndentStr(indent) + this);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component to the specified PrintWriter.
+     * 
+     * @param out the output PrintWriter object.
+     */
+    public void list(PrintWriter out) {
+        toolkit.lockAWT();
+        try {
+            list(out, 1);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component with the specified number of 
+     * leading whitespace characters to the specified PrintWriter.
+     * 
+     * @param out the output PrintWriter object.
+     * @param indent how many leading whitespace characters to prepend
+     */
+    public void list(PrintWriter out, int indent) {
+        toolkit.lockAWT();
+        try {
+            out.println(getIndentStr(indent) + this);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets a string composed of the desired number of 
+     * whitespace characters.
+     * 
+     * @param indent the length of the String to return
+     * 
+     * @return the string composed of the desired number of 
+     * whitespace characters
+     */
+    String getIndentStr(int indent) {
+        char[] ind = new char[indent];
+        for (int i = 0; i < indent; ind[i++] = ' ') {
+            ;
+        }
+        return new String(ind);
+    }
+
+    /**
+     * Prints a list of this component to the specified PrintStream
+     * 
+     * @param out the output PrintStream object.
+     */
+    public void list(PrintStream out) {
+        toolkit.lockAWT();
+        try {
+            // default indent = 1
+            list(out, 1);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component to the standard system 
+     * output stream.
+     */
+    public void list() {
+        toolkit.lockAWT();
+        try {
+            list(System.out);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints this component. 
+     * 
+     * @param g the Graphics to be used for painting. 
+     */
+    public void print(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints the component and all of its subcomponents.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    public void printAll(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paintAll(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the size of the Component specified by width and height
+     * parameters.
+     * 
+     * @param width the width of the Component.
+     * @param height the height of the Component.
+     */
+    public void setSize(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            resize(width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the size of the Component specified by Dimension object.
+     * 
+     * @param d the new size of the Component.
+     */
+    public void setSize(Dimension d) {
+        toolkit.lockAWT();
+        try {
+            resize(d);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setSize(int, int) method.
+     * 
+     * @param width the width.
+     * @param height the height.
+     * 
+     * @deprecated Replaced by setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            boundsMaskParam = NativeWindow.BOUNDS_NOMOVE;
+            setBounds(x, y, width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setSize(int, int) method.
+     * 
+     * @param size the size.
+     * 
+     * @deprecated Replaced by setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(Dimension size) {
+        toolkit.lockAWT();
+        try {
+            setSize(size.width, size.height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this component is completely opaque.
+     * 
+     * @return true, if this component is completely opaque, 
+     *  false by default.
+     */
+    public boolean isOpaque() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isOpaque();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Disables.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method.
+     */
+    @Deprecated
+    public void disable() {
+        toolkit.lockAWT();
+        try {
+            setEnabledImpl(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        //???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, false);
+    }
+
+    /**
+     * Enables this component.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method.
+     */
+    @Deprecated
+    public void enable() {
+        toolkit.lockAWT();
+        try {
+            setEnabledImpl(true);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        //???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, true);
+    }
+
+    /**
+     * Enables or disable this component.
+     * 
+     * @param b the boolean parameter.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method. 
+     */
+    @Deprecated
+    public void enable(boolean b) {
+        toolkit.lockAWT();
+        try {
+            if (b) {
+                enable();
+            } else {
+                disable();
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Stores the location of this component to the specified Point object;
+     * returns the point of the component's top-left corner.
+     * 
+     * @param rv the Point object where the component's top-left corner
+     * position will be stored.
+     * 
+     * @return the Point which specifies the component's top-left corner.
+     */
+    public Point getLocation(Point rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Point();
+            }
+            rv.setLocation(getX(), getY());
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the location of this component on the form;
+     * returns the point of the component's top-left corner.
+     * 
+     * @return the Point which specifies the component's top-left corner.
+     */
+    public Point getLocation() {
+        toolkit.lockAWT();
+        try {
+            return location();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the size of this Component.
+     * 
+     * @return the size of this Component.
+     */
+    public Dimension getSize() {
+        toolkit.lockAWT();
+        try {
+            return size();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Stores the size of this Component to the specified Dimension 
+     * object.
+     * 
+     * @param rv the Dimension object where the size of the Component 
+     * will be stored.
+     * 
+     * @return the Dimension of this Component.
+     */
+    public Dimension getSize(Dimension rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Dimension();
+            }
+            rv.setSize(getWidth(), getHeight());
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is valid. A component is valid 
+     * if it is correctly sized and positioned within its parent container
+     *  and all its children are also valid. 
+     * 
+     * @return true, if the Component is valid, false otherwise.
+     */
+    public boolean isValid() {
+        toolkit.lockAWT();
+        try {
+            return valid && behaviour.isDisplayable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getComponentAt(int, int) method.
+     * 
+     * @return the Point.
+     * 
+     * @deprecated Replaced by getComponentAt(int, int) method.
+     */
+    @Deprecated
+    public Point location() {
+        toolkit.lockAWT();
+        try {
+            return new Point(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Connects this Component to a native screen resource and makes it 
+     * displayable. This method not be called directly by user applications.
+     */
+    public void addNotify() {
+        toolkit.lockAWT();
+        try {
+            prepare4HierarchyChange();
+            behaviour.addNotify();
+            //???AWT
+//            finishHierarchyChange(this, parent, 0);
+//            if (dropTarget != null) {
+//                dropTarget.addNotify(peer);
+//            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Map to display.
+     * 
+     * @param b the b
+     */
+    void mapToDisplay(boolean b) {
+        //???AWT
+        /*
+        if (b && !isDisplayable()) {
+            if ((this instanceof Window) || ((parent != null) && parent.isDisplayable())) {
+                addNotify();
+            }
+        } else if (!b && isDisplayable()) {
+            removeNotify();
+        }
+        */
+    }
+
+    /**
+     * Gets the toolkit.
+     * 
+     * @return accessible context specific for particular component
+     */
+    //???AWT
+    /*
+    AccessibleContext createAccessibleContext() {
+        return null;
+    }
+
+    public AccessibleContext getAccessibleContext() {
+        toolkit.lockAWT();
+        try {
+            if (accessibleContext == null) {
+                accessibleContext = createAccessibleContext();
+            }
+            return accessibleContext;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+ 
+    /**
+     * Gets Toolkit for the current Component.
+     * 
+     * @return the Toolkit of this Component.
+     */
+    public Toolkit getToolkit() {
+        return toolkit;
+    }
+
+    /**
+     * Gets this component's locking object for AWT component tree 
+     * and layout operations.
+     * 
+     * @return the tree locking object.
+     */
+    public final Object getTreeLock() {
+        return toolkit.awtTreeLock;
+    }
+
+    /**
+     * @param evt the Event.
+     * @param what the event's key.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Use ActionListener class for registering event listener.   
+     */
+    @Deprecated
+    public boolean action(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+
+    /**
+     * Gets the property change support.
+     * 
+     * @return the property change support
+     */
+    private PropertyChangeSupport getPropertyChangeSupport() {
+        synchronized (componentLock) {
+            if (propertyChangeSupport == null) {
+                propertyChangeSupport = new PropertyChangeSupport(this);
+            }
+            return propertyChangeSupport;
+        }
+    }
+    
+    //???AWT
+    /*
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        getPropertyChangeSupport().addPropertyChangeListener(listener);
+    }
+
+    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+        getPropertyChangeSupport().addPropertyChangeListener(propertyName, listener);
+    }
+
+    public void applyComponentOrientation(ComponentOrientation orientation) {
+        toolkit.lockAWT();
+        try {
+            setComponentOrientation(orientation);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Returns true if the set of focus traversal keys for the given focus 
+     * traversal operation has been explicitly defined for this Component. 
+     * 
+     * @param id the ID of traversal key.
+     * 
+     * @return true, if the set of focus traversal keys for the given focus 
+     * traversal operation has been explicitly defined for this Component,
+     * false otherwise. 
+     */
+    public boolean areFocusTraversalKeysSet(int id) {
+        toolkit.lockAWT();
+        try {
+            Integer Id = new Integer(id);
+            if (traversalKeys.containsKey(Id)) {
+                return traversalKeys.get(Id) != null;
+            }
+            // awt.14F=invalid focus traversal key identifier
+            throw new IllegalArgumentException(Messages.getString("awt.14F")); //$NON-NLS-1$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the bounds of the Component.
+     * 
+     * @return the rectangle bounds of the Component.
+     * 
+     * @deprecated Use getBounds() methood.
+     */
+    @Deprecated
+    public Rectangle bounds() {
+        toolkit.lockAWT();
+        try {
+            return new Rectangle(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the construction status of a specified image
+     * with the specified width and height that is being created.
+     * 
+     * 
+     * @param image the image to be checked.
+     * @param width the width of scaled image which status is being checked, or -1.
+     * @param height the height of scaled image which status is being checked, or -1.
+     * @param observer the ImageObserver object to be notified while 
+     * the image is being prepared.
+     * 
+     * @return the ImageObserver flags of the current state of the image data.
+     */
+    public int checkImage(Image image, int width, int height, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.checkImage(image, width, height, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the construction status of a specified image that is being created.
+     * 
+     * 
+     * @param image the image to be checked.
+     * @param observer the ImageObserver object to be notified while 
+     * the image is being prepared.
+     * 
+     * @return the ImageObserver flags of the current state of the image data.
+     */
+    public int checkImage(Image image, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.checkImage(image, -1, -1, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Coalesces the existed event with new event.
+     * 
+     * @param existingEvent the existing event in the EventQueue.
+     * @param newEvent the new event to be posted to the EventQueue.
+     * 
+     * @return the coalesced AWTEvent, or null if there is no coalescing done. 
+     */
+    protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent) {
+        toolkit.lockAWT();
+        try {
+            // Nothing to do:
+            // 1. Mouse events coalesced at WTK level
+            // 2. Paint events handled by RedrawManager
+            // This method is for overriding only
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if this Component is a coalescer.
+     * 
+     * @return true, if is coalescer
+     */
+    boolean isCoalescer() {
+        return coalescer;
+    }
+
+    /**
+     * Gets the relative event.
+     * 
+     * @param id the id
+     * 
+     * @return the relative event
+     */
+    AWTEvent getRelativeEvent(int id) {
+        Integer idWrapper = new Integer(id);
+        eventsList = eventsTable.get(idWrapper);
+        if (eventsList == null) {
+            eventsList = new LinkedList<AWTEvent>();
+            eventsTable.put(idWrapper, eventsList);
+            return null;
+        }
+        if (eventsList.isEmpty()) {
+            return null;
+        }
+        return eventsList.getLast();
+    }
+
+    /**
+     * Adds the new event.
+     * 
+     * @param event the event
+     */
+    void addNewEvent(AWTEvent event) {
+        eventsList.addLast(event);
+    }
+
+    /**
+     * Removes the relative event.
+     */
+    void removeRelativeEvent() {
+        eventsList.removeLast();
+    }
+
+    /**
+     * Removes the next event.
+     * 
+     * @param id the id
+     */
+    void removeNextEvent(int id) {
+        eventsTable.get(new Integer(id)).removeFirst();
+    }
+
+    /**
+     * Creates the image with the specified ImageProducer.
+     * 
+     * @param producer the ImageProducer to be used for image creation.
+     * 
+     * @return the image with the specified ImageProducer.
+     */
+    public Image createImage(ImageProducer producer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.createImage(producer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates an off-screen drawable image to be used for double buffering.
+     * 
+     * @param width the width of the image.
+     * @param height the height of the image.
+     * 
+     * @return the off-screen drawable image or null if the component is not 
+     * displayable or GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public Image createImage(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            ColorModel cm = gc.getColorModel(Transparency.OPAQUE);
+            WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
+            Image image = new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates an off-screen drawable image with the specified width,
+     * height and ImageCapabilities.
+     * 
+     * @param width the width
+     * @param height the height
+     * @param caps the ImageCapabilities.
+     * 
+     * @return the volatile image
+     * 
+     * @throws AWTException if an image with the specified capabilities 
+     * cannot be created.
+     */
+    public VolatileImage createVolatileImage(int width, int height, ImageCapabilities caps)
+            throws AWTException {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            VolatileImage image = gc.createCompatibleVolatileImage(width, height, caps);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates a volatile off-screen drawable image which is used 
+     * for double buffering.
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * 
+     * @return the volatile image a volatile off-screen drawable image 
+     * which is used for double buffering or null if the component 
+     * is not displayable, or GraphicsEnvironment.isHeadless() method
+     * returns true.
+     */
+    public VolatileImage createVolatileImage(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            VolatileImage image = gc.createCompatibleVolatileImage(width, height);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Fill the image being created by createImage() or createVolatileImage()
+     * with the component's background color to prepare it for double-buffered
+     * painting.
+     * 
+     * @param image the image
+     * @param width the width
+     * @param height the height
+     */
+    private void fillImageBackground(Image image, int width, int height) {
+        Graphics gr = image.getGraphics();
+        gr.setColor(getBackground());
+        gr.fillRect(0, 0, width, height);
+        gr.dispose();
+    }
+
+    /**
+     * Delivers event.
+     * 
+     * @param evt the event.
+     * 
+     * @deprecated Replaced by dispatchEvent(AWTEvent e) method.
+     */
+    @Deprecated
+    public void deliverEvent(Event evt) {
+        postEvent(evt);
+    }
+
+    /**
+     * Prompts the layout manager to lay out this component. 
+     */
+    public void doLayout() {
+        toolkit.lockAWT();
+        try {
+            layout();
+        } finally {
+            toolkit.unlockAWT();
+        }
+        // Implemented in Container
+    }
+
+    /**
+     * Fire property change impl.
+     * 
+     * @param propertyName the property name
+     * @param oldValue the old value
+     * @param newValue the new value
+     */
+    private void firePropertyChangeImpl(String propertyName, Object oldValue, Object newValue) {
+        PropertyChangeSupport pcs;
+        synchronized (componentLock) {
+            if (propertyChangeSupport == null) {
+                return;
+            }
+            pcs = propertyChangeSupport;
+        }
+        pcs.firePropertyChange(propertyName, oldValue, newValue);
+    }
+
+    /**
+     * Reports a bound property changes for int properties.
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    protected void firePropertyChange(String propertyName, int oldValue, int newValue) {
+        firePropertyChangeImpl(propertyName, new Integer(oldValue), new Integer(newValue));
+    }
+
+    /**
+     * Report a bound property change for a boolean-valued property. 
+     *  
+     * @param propertyName the property name.
+     * @param oldValue the property's old value.
+     * @param newValue the property's new value.
+     */
+    protected void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
+        firePropertyChangeImpl(propertyName, Boolean.valueOf(oldValue), Boolean
+                .valueOf(newValue));
+    }
+
+    /**
+     * Reports a bound property change for an Object-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the property's old value
+     * @param newValue the property's new value
+     */
+    protected void firePropertyChange(final String propertyName, final Object oldValue,
+            final Object newValue) {
+        firePropertyChangeImpl(propertyName, oldValue, newValue);
+    }
+
+    /**
+     * Report a bound property change for a byte-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the property's old value.
+     * @param newValue the property's new value.
+     */
+    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
+        firePropertyChangeImpl(propertyName, new Byte(oldValue), new Byte(newValue));
+    }
+
+    /**
+     * Report a bound property change for a char-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, char oldValue, char newValue) {
+        firePropertyChangeImpl(propertyName, new Character(oldValue), new Character(newValue));
+    }
+
+    /**
+     * Report a bound property change for a short-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, short oldValue, short newValue) {
+        firePropertyChangeImpl(propertyName, new Short(oldValue), new Short(newValue));
+    }
+
+    /**
+     * Report a bound property change for a long-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, long oldValue, long newValue) {
+        firePropertyChangeImpl(propertyName, new Long(oldValue), new Long(newValue));
+    }
+
+    /**
+     * Report a bound property change for a float-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, float oldValue, float newValue) {
+        firePropertyChangeImpl(propertyName, new Float(oldValue), new Float(newValue));
+    }
+
+    /**
+     * Report a bound property change for a double-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, double oldValue, double newValue) {
+        firePropertyChangeImpl(propertyName, new Double(oldValue), new Double(newValue));
+    }
+
+    /**
+     * Gets the alignment along the x axis. 
+     * 
+     * @return the alignment along the x axis. 
+     */
+    public float getAlignmentX() {
+        toolkit.lockAWT();
+        try {
+            return CENTER_ALIGNMENT;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the alignment along the y axis. 
+     * 
+     * @return the alignment along y axis.
+     */
+    public float getAlignmentY() {
+        toolkit.lockAWT();
+        try {
+            return CENTER_ALIGNMENT;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the background color for this component.
+     * 
+     * @return the background color for this component.
+     */
+    public Color getBackground() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if ((backColor == null) && (parent != null)) {
+                return parent.getBackground();
+            }
+            */
+            return backColor;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the bounding rectangle of this component.
+     * 
+     * @return the bounding rectangle of this component.
+     */
+    public Rectangle getBounds() {
+        toolkit.lockAWT();
+        try {
+            return bounds();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Writes the data of the bounding rectangle to the specified 
+     * Rectangle object.
+     * 
+     * @param rv the Rectangle object where the bounding rectangle's data is stored.  
+     * 
+     * @return the bounding rectangle.
+     */
+    public Rectangle getBounds(Rectangle rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Rectangle();
+            }
+            rv.setBounds(x, y, w, h);
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the color model of the Component.
+     * 
+     * @return the color model of the Component.
+     */
+    public ColorModel getColorModel() {
+        toolkit.lockAWT();
+        try {
+            return getToolkit().getColorModel();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Component which contains the specified Point.
+     * 
+     * @param p the Point.
+     * 
+     * @return the Component which contains the specified Point.
+     */
+    public Component getComponentAt(Point p) {
+        toolkit.lockAWT();
+        try {
+            return getComponentAt(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Component which contains the point with the
+     * specified coordinates.
+     * 
+     * @param x the x coordinate of the point.
+     * @param y the y coordinate of the point.
+     * 
+     * @return the Component which contains the point with the
+     * specified coordinates.
+     */
+    public Component getComponentAt(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return locate(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the component's orientation.
+     * 
+     * @return the component's orientation.
+     */
+    public ComponentOrientation getComponentOrientation() {
+        toolkit.lockAWT();
+        try {
+            return orientation;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the cursor of the Component.
+     * 
+     * @return the Cursor.
+     */
+    public Cursor getCursor() {
+        toolkit.lockAWT();
+        try {
+            if (cursor != null) {
+                return cursor;
+            //???AWT
+            /*
+            } else if (parent != null) {
+                return parent.getCursor();
+            */
+            }
+            return Cursor.getDefaultCursor();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    public DropTarget getDropTarget() {
+        toolkit.lockAWT();
+        try {
+            return dropTarget;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    
+    public Container getFocusCycleRootAncestor() {
+        toolkit.lockAWT();
+        try {
+            for (Container c = parent; c != null; c = c.getParent()) {
+                if (c.isFocusCycleRoot()) {
+                    return c;
+                }
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
+        toolkit.lockAWT();
+        try {
+            Integer kId = new Integer(id);
+            KeyboardFocusManager.checkTraversalKeysID(traversalKeys, kId);
+            Set<? extends AWTKeyStroke> keys = traversalKeys.get(kId);
+            if (keys == null && parent != null) {
+                keys = parent.getFocusTraversalKeys(id);
+            }
+            if (keys == null) {
+                keys = KeyboardFocusManager.getCurrentKeyboardFocusManager()
+                        .getDefaultFocusTraversalKeys(id);
+            }
+            return (Set<AWTKeyStroke>) keys;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * Checks if the the focus traversal keys are enabled for this component.
+     * 
+     * @return true, if the the focus traversal keys are enabled for 
+     * this component, false otherwise.
+     */
+    public boolean getFocusTraversalKeysEnabled() {
+        toolkit.lockAWT();
+        try {
+            return focusTraversalKeysEnabled;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the font metrics of the specified Font.
+     * 
+     * @param f the Font.
+     * 
+     * @return the FontMetrics of the specified Font.
+     */
+    @SuppressWarnings("deprecation")
+    public FontMetrics getFontMetrics(Font f) {
+        return toolkit.getFontMetrics(f);
+    }
+
+    /**
+     * Gets the foreground color of the Component.
+     * 
+     * @return the foreground color of the Component.
+     */
+    public Color getForeground() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if (foreColor == null && parent != null) {
+                return parent.getForeground();
+            }
+            */
+            return foreColor;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Graphics of the Component or null if this Component
+     * is not displayable.
+     * 
+     * @return the Graphics of the Component or null if this Component
+     * is not displayable.
+     */
+    public Graphics getGraphics() {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            Graphics g = behaviour.getGraphics(0, 0, w, h);
+            g.setColor(foreColor);
+            g.setFont(font);
+            return g;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+
+    /**
+     * Gets the GraphicsConfiguration associated with this Component.
+     * 
+     * @return the GraphicsConfiguration associated with this Component.
+     */
+    public GraphicsConfiguration getGraphicsConfiguration() {
+        //???AWT
+        /*
+        toolkit.lockAWT();
+        try {
+            Window win = getWindowAncestor();
+            if (win == null) {
+                return null;
+            }
+            return win.getGraphicsConfiguration();
+        } finally {
+            toolkit.unlockAWT();
+        }
+        */
+        return null;
+    }
+
+    /**
+     * Gets the height of the Component.
+     * 
+     * @return the height of the Component.
+     */
+    public int getHeight() {
+        toolkit.lockAWT();
+        try {
+            return h;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true if paint messages received from the operating system 
+     * should be ignored.
+     * 
+     * @return true if paint messages received from the operating system 
+     * should be ignored, false otherwise.
+     */
+    public boolean getIgnoreRepaint() {
+        toolkit.lockAWT();
+        try {
+            return ignoreRepaint;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the input context of this component for handling 
+     * the communication with input methods when text is entered 
+     * in this component.
+     * 
+     * @return the InputContext used by this Component or 
+     * null if no context is specifined.
+     */
+    public InputContext getInputContext() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            Container parent = getParent();
+            if (parent != null) {
+                return parent.getInputContext();
+            }
+            */
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the input method request handler which supports requests
+     * from input methods for this component, or null for default.
+     * 
+     * @return the input method request handler which supports requests
+     * from input methods for this component, or null for default.
+     */
+    public InputMethodRequests getInputMethodRequests() {
+        return null;
+    }
+
+    /**
+     * Gets the locale of this Component.
+     * 
+     * @return the locale of this Component.
+     */
+    public Locale getLocale() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if (locale == null) {
+                if (parent == null) {
+                    if (this instanceof Window) {
+                        return Locale.getDefault();
+                    }
+                    // awt.150=no parent
+                    throw new IllegalComponentStateException(Messages.getString("awt.150")); //$NON-NLS-1$
+                }
+                return getParent().getLocale();
+            }
+            */
+            return locale;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the location of this component in the form of a point 
+     * specifying the component's top-left corner in the 
+     * screen's coordinate space.
+     * 
+     * @return the Point giving the component's location in the 
+     * screen's coordinate space.
+     * 
+     * @throws IllegalComponentStateException if the component is 
+     * not shown on the screen.
+     */
+    public Point getLocationOnScreen() throws IllegalComponentStateException {
+        toolkit.lockAWT();
+        try {
+            Point p = new Point();
+            if (isShowing()) {
+                //???AWT
+                /*
+                Component comp;
+                for (comp = this; comp != null && !(comp instanceof Window); comp = comp
+                        .getParent()) {
+                    p.translate(comp.getX(), comp.getY());
+                }
+                if (comp instanceof Window) {
+                    p.translate(comp.getX(), comp.getY());
+                }
+                */
+                return p;
+            }
+            // awt.151=component must be showing on the screen to determine its location
+            throw new IllegalComponentStateException(Messages.getString("awt.151")); //$NON-NLS-1$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the peer. This method should not be called directly by
+     * user applications.
+     * 
+     * @return the ComponentPeer.
+     * 
+     * @deprecated Replaced by isDisplayable().
+     */
+    @Deprecated
+    public ComponentPeer getPeer() {
+        toolkit.lockAWT();
+        try {
+            if (behaviour.isDisplayable()) {
+                return peer;
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets an array of the property change listeners registered to
+     * this Component.
+     * 
+     * @return an array of the PropertyChangeListeners registered to
+     * this Component.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        return getPropertyChangeSupport().getPropertyChangeListeners();
+    }
+
+    /**
+     * Gets an array of PropertyChangeListener objects registered
+     * to this Component for the specified property.
+     * 
+     * @param propertyName the property name.
+     * 
+     * @return an array of PropertyChangeListener objects registered
+     * to this Component for the specified property.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
+        return getPropertyChangeSupport().getPropertyChangeListeners(propertyName);
+    }
+
+    /**
+     * Gets the width of the Component.
+     * 
+     * @return the width of the Component.
+     */
+    public int getWidth() {
+        toolkit.lockAWT();
+        try {
+            return w;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the x coordinate of the component's top-left corner.
+     * 
+     * @return the x coordinate of the component's top-left corner.
+     */
+    public int getX() {
+        toolkit.lockAWT();
+        try {
+            return x;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the y coordinate of the component's top-left corner.
+     * 
+     * @return the y coordinate of the component's top-left corner.
+     */
+    public int getY() {
+        toolkit.lockAWT();
+        try {
+            return y;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Got the focus.
+     * 
+     * @param evt the Event.
+     * @param what the Object.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processFocusEvent(FocusEvent) method.
+     */
+    @Deprecated
+    public boolean gotFocus(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Handles event.
+     * 
+     * @param evt the Event.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processEvent(AWTEvent) method.
+     */
+    @Deprecated
+    public boolean handleEvent(Event evt) {
+        switch (evt.id) {
+            case Event.ACTION_EVENT:
+                return action(evt, evt.arg);
+            case Event.GOT_FOCUS:
+                return gotFocus(evt, null);
+            case Event.LOST_FOCUS:
+                return lostFocus(evt, null);
+            case Event.MOUSE_DOWN:
+                return mouseDown(evt, evt.x, evt.y);
+            case Event.MOUSE_DRAG:
+                return mouseDrag(evt, evt.x, evt.y);
+            case Event.MOUSE_ENTER:
+                return mouseEnter(evt, evt.x, evt.y);
+            case Event.MOUSE_EXIT:
+                return mouseExit(evt, evt.x, evt.y);
+            case Event.MOUSE_MOVE:
+                return mouseMove(evt, evt.x, evt.y);
+            case Event.MOUSE_UP:
+                return mouseUp(evt, evt.x, evt.y);
+            case Event.KEY_ACTION:
+            case Event.KEY_PRESS:
+                return keyDown(evt, evt.key);
+            case Event.KEY_ACTION_RELEASE:
+            case Event.KEY_RELEASE:
+                return keyUp(evt, evt.key);
+        }
+        return false;// event not handled
+    }
+
+    /**
+     * Checks whether the Component is the focus owner or not.
+     * 
+     * @return true, if the Component is the focus owner, false otherwise.
+     */
+    public boolean hasFocus() {
+        toolkit.lockAWT();
+        try {
+            //???AWT: return isFocusOwner();
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Hides the Component.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void hide() {
+        toolkit.lockAWT();
+        try {
+            if (!visible) {
+                return;
+            }
+            prepare4HierarchyChange();
+            visible = false;
+            moveFocusOnHide();
+            behaviour.setVisible(false);
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_HIDDEN));
+            //???AWT: finishHierarchyChange(this, parent, 0);
+            notifyInputMethod(null);
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the point with the specified coordinates 
+     * belongs to the Commponent.
+     * 
+     * @param x the x coordinate of the Point.
+     * @param y the y coordinate of the Point.
+     * 
+     * @return true, if the point with the specified coordinates 
+     * belongs to the Commponent, false otherwise.
+     * 
+     * @deprecated Replaced by contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Invalidates the component, this component and all parents 
+     * above it are marked as needing to be laid out. 
+     */
+    public void invalidate() {
+        toolkit.lockAWT();
+        try {
+            valid = false;
+            resetDefaultSize();
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the background color is set to this Component.
+     * 
+     * @return true, if the background color is set to this Component,
+     * false otherwise.
+     */
+    public boolean isBackgroundSet() {
+        toolkit.lockAWT();
+        try {
+            return backColor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not a cursor is set for the Component.
+     * 
+     * @return true, if a cursor is set for the Component,
+     * false otherwise.
+     */
+    public boolean isCursorSet() {
+        toolkit.lockAWT();
+        try {
+            return cursor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is displayable.
+     * 
+     * @return true, if this Component is displayable, false otherwise.
+     */
+    public boolean isDisplayable() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isDisplayable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this component is painted to an buffer
+     * which is copied to the screen later.
+     * 
+     * @return true, if this component is painted to an buffer
+     * which is copied to the screen later, false otherwise.
+     */
+    public boolean isDoubleBuffered() {
+        toolkit.lockAWT();
+        try {
+            // false by default
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is enabled.
+     * 
+     * @return true, if this Component is enabled, false otherwise.
+     */
+    public boolean isEnabled() {
+        toolkit.lockAWT();
+        try {
+            return enabled;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * "Recursive" isEnabled().
+     * 
+     * @return true if not only component itself is enabled but its heavyweight
+     * parent is also "indirectly" enabled
+     */
+    boolean isIndirectlyEnabled() {
+        Component comp = this;
+        while (comp != null) {
+            if (!comp.isLightweight() && !comp.isEnabled()) {
+                return false;
+            }
+            //???AWT: comp = comp.getRealParent();
+        }
+        return true;
+    }
+
+    /**
+     * Checks if the component is key enabled.
+     * 
+     * @return true, if the component is enabled and indirectly enabled
+     */
+    boolean isKeyEnabled() {
+        if (!isEnabled()) {
+            return false;
+        }
+        return isIndirectlyEnabled();
+    }
+
+    /**
+     * Gets only parent of a child component, but not owner of a window.
+     * 
+     * @return parent of child component, null if component is a top-level
+     * (Window instance)
+     */
+    //???AWT
+    /*
+    Container getRealParent() {
+        return (!(this instanceof Window) ? getParent() : null);
+    }
+
+    public boolean isFocusCycleRoot(Container container) {
+        toolkit.lockAWT();
+        try {
+            return getFocusCycleRootAncestor() == container;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    public boolean isFocusOwner() {
+        toolkit.lockAWT();
+        try {
+            return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == this;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * Checks whether or not this Component can be focusable.
+     * 
+     * @return true, if this Component can be focusable, false otherwise.
+     * 
+     * @deprecated Replaced by isFocusable(). 
+     */
+    @Deprecated
+    public boolean isFocusTraversable() {
+        toolkit.lockAWT();
+        try {
+            overridenIsFocusable = false;
+            return focusable; // a Component must either be both focusable and
+            // focus traversable, or neither
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if this Component can be focusable or not.
+     * 
+     * @return true, if this Component can be focusable, false otherwise.
+     */
+    public boolean isFocusable() {
+        toolkit.lockAWT();
+        try {
+            return isFocusTraversable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if the Font is set for this Component or not.
+     * 
+     * @return true, if the Font is set, false otherwise.
+     */
+    public boolean isFontSet() {
+        toolkit.lockAWT();
+        try {
+            return font != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if foreground color is set for the Component or not.
+     * 
+     * @return true, if is foreground color is set for the Component,
+     * false otherwise.
+     */
+    public boolean isForegroundSet() {
+        toolkit.lockAWT();
+        try {
+            return foreColor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true if this component has a lightweight peer.
+     * 
+     * @return true, if this component has a lightweight peer,
+     * false if it has a native peer or no peer.
+     */
+    public boolean isLightweight() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isLightweight();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+
+    /**
+     * Checks whether or not this Component is shown.
+     * 
+     * @return true, if this Component is shown, false otherwise.
+     */
+    public boolean isShowing() {
+        //???AWT
+        /*
+        toolkit.lockAWT();
+        try {
+            return (isVisible() && isDisplayable() && (parent != null) && parent.isShowing());
+        } finally {
+            toolkit.unlockAWT();
+        }
+        */
+        return false;
+    }
+
+    /**
+     * Checks whether or not this Component is visible.
+     * 
+     * @return true, if the Component is visible, false otherwise.
+     */
+    public boolean isVisible() {
+        toolkit.lockAWT();
+        try {
+            return visible;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
+     * 
+     * @param evt the Event.
+     * @param key the key code.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by replaced by processKeyEvent(KeyEvent) method.
+     */
+    @Deprecated
+    public boolean keyDown(Event evt, int key) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
+     * 
+     * @param evt the Event.
+     * @param key the key code.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processKeyEvent(KeyEvent) method.
+     */
+    @Deprecated
+    public boolean keyUp(Event evt, int key) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: Replaced by doLayout() method.
+     * 
+     * @deprecated Replaced by doLayout() method.
+     */
+    @Deprecated
+    public void layout() {
+        toolkit.lockAWT();
+        try {
+            // Implemented in Container
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getComponentAt(int, int) method.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return The component.
+     * 
+     * @deprecated Replaced by getComponentAt(int, int) method.
+     */
+    @Deprecated
+    public Component locate(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            if (contains(x, y)) {
+                return this;
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by processFocusEvent(FocusEvent). 
+     * 
+     * @param evt the Event.
+     * @param what the Object.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processFocusEvent(FocusEvent).
+     */
+    @Deprecated
+    public boolean lostFocus(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the MouseEvent.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseDown(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by getMinimumSize() method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by getMinimumSize() method.
+     */
+    @Deprecated
+    public boolean mouseDrag(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseEnter(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseExit(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @return true, if successful.
+     */
+    @Deprecated
+    public boolean mouseMove(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseUp(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by setLocation(int, int) method.
+     * 
+     * @param x the x coordinates.
+     * @param y the y coordinates.
+     * 
+     * @deprecated Replaced by setLocation(int, int) method.
+     */
+    @Deprecated
+    public void move(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            boundsMaskParam = NativeWindow.BOUNDS_NOSIZE;
+            setBounds(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    @Deprecated
+    public void nextFocus() {
+        toolkit.lockAWT();
+        try {
+            transferFocus(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Returns a string representation of the component's state.
+     * 
+     * @return the string representation of the component's state.
+     */
+    protected String paramString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code:
+         * 
+         * Component c = new Component(){}; c.setVisible(false);
+         * System.out.println(c);
+         */
+        toolkit.lockAWT();
+        try {
+            return getName() + "," + getX() + "," + getY() + "," + getWidth() + "x" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                    + getHeight() + (!isVisible() ? ",hidden" : ""); //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    @Deprecated
+    @SuppressWarnings("deprecation")
+    public boolean postEvent(Event evt) {
+        boolean handled = handleEvent(evt);
+        if (handled) {
+            return true;
+        }
+        //???AWT
+        /*
+
+        // propagate non-handled events up to parent
+        Component par = parent;
+        // try to call postEvent only on components which
+        // override any of deprecated method handlers
+        // while (par != null && !par.deprecatedEventHandler) {
+        // par = par.parent;
+        // }
+        // translate event coordinates before posting it to parent
+        if (par != null) {
+            evt.translate(x, y);
+            par.postEvent(evt);
+        }
+        
+        */
+        return false;
+    }
+
+    /**
+     * Prepares an image for rendering on the Component. 
+     *  
+     * @param image the Image to be prepared.
+     * @param observer the ImageObserver object to be notified as soon as 
+     * the image is prepared.
+     * 
+     * @return true if the image has been fully prepared,
+     * false otherwise.
+     */
+    public boolean prepareImage(Image image, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.prepareImage(image, -1, -1, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prepares an image for rendering on the Component with the
+     * specified width, height, and ImageObserver. 
+     * 
+     * @param image the Image to be prepared.
+     * @param width the width of scaled image.
+     * @param height the height of scaled height.
+     * @param observer the ImageObserver object to be notified as soon as 
+     * the image is prepared.
+     * 
+     * @return true if the image is been fully prepared,
+     * false otherwise.
+     */
+    public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.prepareImage(image, width, height, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Makes this Component undisplayable.
+     */
+    public void removeNotify() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if (dropTarget != null) {
+                dropTarget.removeNotify(peer);
+            }
+            */
+            prepare4HierarchyChange();
+            ///???AWT: moveFocus();
+            behaviour.removeNotify();
+            //???AWT: finishHierarchyChange(this, parent, 0);
+            removeNotifyInputContext();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Calls InputContext.removeNotify
+     */
+    private void removeNotifyInputContext() {
+        if (!inputMethodsEnabled) {
+            return;
+        }
+        InputContext ic = getInputContext();
+        if (ic != null) {
+            //???AWT: ic.removeNotify(this);
+        }
+    }
+
+    /**
+     * This method is called when some property of a component changes, making
+     * it unfocusable, e. g. hide(), removeNotify(), setEnabled(false),
+     * setFocusable(false) is called, and therefore automatic forward focus
+     * traversal is necessary
+     */
+    //???AWT
+    /*
+    void moveFocus() {
+        // don't use transferFocus(), but query focus traversal policy directly
+        // and if it returns null, transfer focus up cycle
+        // and find next focusable component there
+        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+        Container root = kfm.getCurrentFocusCycleRoot();
+        Component nextComp = this;
+        boolean success = !isFocusOwner();
+        while (!success) {
+            if (root != nextComp.getFocusCycleRootAncestor()) {
+                // component was probably removed from container
+                // so focus will be lost in some time
+                return;
+            }
+            nextComp = root.getFocusTraversalPolicy().getComponentAfter(root, nextComp);
+            if (nextComp == this) {
+                nextComp = null; // avoid looping
+            }
+            if (nextComp != null) {
+                success = nextComp.requestFocusInWindow();
+            } else {
+                nextComp = root;
+                root = root.getFocusCycleRootAncestor();
+                // if no acceptable component is found at all - clear global
+                // focus owner
+                if (root == null) {
+                    if (nextComp instanceof Window) {
+                        Window wnd = (Window) nextComp;
+                        wnd.setFocusOwner(null);
+                        wnd.setRequestedFocus(null);
+                    }
+                    kfm.clearGlobalFocusOwner();
+                    return;
+                }
+            }
+        }
+    }
+    */
+
+    /**
+     * For Container there's a difference between moving focus when being made
+     * invisible or made unfocusable in some other way, because when container
+     * is made invisible, component still remains visible, i. e. its hide() or
+     * setVisible() is not called.
+     */
+    void moveFocusOnHide() {
+        //???AWT: moveFocus();
+    }
+
+    /**
+     * Removes the property change listener registered for this component.
+     * 
+     * @param listener the PropertyChangeListener.
+     */
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        getPropertyChangeSupport().removePropertyChangeListener(listener);
+    }
+
+    /**
+     * Removes the property change listener registered fot this component 
+     * for the specified propertyy.
+     * 
+     * @param propertyName the property name.
+     * @param listener the PropertyChangeListener.
+     */
+    public void removePropertyChangeListener(String propertyName,
+            PropertyChangeListener listener) {
+        getPropertyChangeSupport().removePropertyChangeListener(propertyName, listener);
+    }
+
+
+    /**
+     * Repaints the specified rectangle of this component within 
+     * tm milliseconds.
+     * 
+     * @param tm the time in milliseconds before updating.
+     * @param x the x coordinate of Rectangle.
+     * @param y the y coordinate of Rectangle.
+     * @param width the width of Rectangle.
+     * @param height the height of Rectangle.
+     */
+    public void repaint(long tm, int x, int y, int width, int height) {
+        //???AWT
+        /*
+        toolkit.lockAWT();
+        try {
+            if (width <= 0 || height <= 0 || (redrawManager == null) || !isShowing()) {
+                return;
+            }
+            if (behaviour instanceof LWBehavior) {
+                if (parent == null || !parent.visible || !parent.behaviour.isDisplayable()) {
+                    return;
+                }
+                if (repaintRegion == null) {
+                    repaintRegion = new MultiRectArea(new Rectangle(x, y, width, height));
+                }
+                repaintRegion.intersect(new Rectangle(0, 0, this.w, this.h));
+                repaintRegion.translate(this.x, this.y);
+                parent.repaintRegion = repaintRegion;
+                repaintRegion = null;
+                parent.repaint(tm, x + this.x, y + this.y, width, height);
+            } else {
+                if (repaintRegion != null) {
+                    redrawManager.addUpdateRegion(this, repaintRegion);
+                    repaintRegion = null;
+                } else {
+                    redrawManager.addUpdateRegion(this, new Rectangle(x, y, width, height));
+                }
+                toolkit.getSystemEventQueueCore().notifyEventMonitor(toolkit);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        */
+    }
+
+    /**
+     * Post event.
+     * 
+     * @param e the e
+     */
+    void postEvent(AWTEvent e) {
+        getToolkit().getSystemEventQueueImpl().postEvent(e);
+    }
+
+    /**
+     * Repaints the specified Rectangle of this Component.
+     * 
+     * @param x the x coordinate of Rectangle.
+     * @param y the y coordinate of Rectangle.
+     * @param width the width of Rectangle.
+     * @param height the height of Rectangle.
+     */
+    public void repaint(int x, int y, int width, int height) {
+        toolkit.lockAWT();
+        try {
+            repaint(0, x, y, width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Repaints this component.
+     */
+    public void repaint() {
+        toolkit.lockAWT();
+        try {
+            if (w > 0 && h > 0) {
+                repaint(0, 0, 0, w, h);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Repaints the component within tm milliseconds.
+     * 
+     * @param tm the time in milliseconds before updating.
+     */
+    public void repaint(long tm) {
+        toolkit.lockAWT();
+        try {
+            repaint(tm, 0, 0, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Requests that this Component get the input focus temporarily. 
+     * This component must be displayable, visible, and focusable.
+     * 
+     * @param temporary this parameter is true if the focus change 
+     * is temporary, when the window loses the focus.
+     * 
+     * @return true if the focus change request is succeeded,
+     * false otherwise.
+     */
+    protected boolean requestFocus(boolean temporary) {
+        toolkit.lockAWT();
+        try {
+            //???AWT: return requestFocusImpl(temporary, true, false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        //???AWT
+        return false;
+    }
+
+    /**
+     * Requests that this Component get the input focus. 
+     * This component must be displayable, visible, and focusable.
+     */
+    public void requestFocus() {
+        toolkit.lockAWT();
+        try {
+            requestFocus(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    protected boolean requestFocusInWindow(boolean temporary) {
+        toolkit.lockAWT();
+        try {
+            Window wnd = getWindowAncestor();
+            if ((wnd == null) || !wnd.isFocused()) {
+                return false;
+            }
+            return requestFocusImpl(temporary, false, false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    boolean requestFocusImpl(boolean temporary, boolean crossWindow, boolean rejectionRecovery) {
+        if (!rejectionRecovery && isFocusOwner()) {
+            return true;
+        }
+        Window wnd = getWindowAncestor();
+        Container par = getRealParent();
+        if ((par != null) && par.isRemoved) {
+            return false;
+        }
+        if (!isShowing() || !isFocusable() || !wnd.isFocusableWindow()) {
+            return false;
+        }
+        return KeyboardFocusManager.getCurrentKeyboardFocusManager().requestFocus(this,
+                temporary, crossWindow, true);
+    }
+
+    public boolean requestFocusInWindow() {
+        toolkit.lockAWT();
+        try {
+            return requestFocusInWindow(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Deprecated: replaced by setBounds(int, int, int, int) method.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param w the width. 
+     * @param h the height.
+     * 
+     * @deprecated Replaced by setBounds(int, int, int, int) method.
+     */
+    @Deprecated
+    public void reshape(int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            setBounds(x, y, w, h, boundsMaskParam, true);
+            boundsMaskParam = 0;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets rectangle for this Component to be the rectangle with the specified 
+     * x,y coordinates of the top-left corner and the width and height.
+     * 
+     * @param x the x coordinate of the rectangle's top-left corner.
+     * @param y the y coordinate of the rectangle's top-left corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle. 
+     */
+    public void setBounds(int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            reshape(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets rectangle for this Component to be the rectangle with the specified 
+     * x,y coordinates of the top-left corner and the width and height
+     * and posts the appropriate events.
+     * 
+     * @param x the x coordinate of the rectangle's top-left corner.
+     * @param y the y coordinate of the rectangle's top-left corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle. 
+     * @param bMask the bitmask of bounds options
+     * @param updateBehavior the whether to update the behavoir's bounds as well
+     */
+    void setBounds(int x, int y, int w, int h, int bMask, boolean updateBehavior) {
+        int oldX = this.x;
+        int oldY = this.y;
+        int oldW = this.w;
+        int oldH = this.h;
+        setBoundsFields(x, y, w, h, bMask);
+        // Moved
+        if ((oldX != this.x) || (oldY != this.y)) {
+            //???AWT: invalidateRealParent();
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED));
+            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_MOVED);
+        }
+        // Resized
+        if ((oldW != this.w) || (oldH != this.h)) {
+            invalidate();
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
+            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_RESIZED);
+        }
+        if (updateBehavior) {
+            behaviour.setBounds(this.x, this.y, this.w, this.h, bMask);
+        }
+        notifyInputMethod(new Rectangle(x, y, w, h));
+    }
+
+    /**
+     * Calls InputContextImpl.notifyClientWindowChanged.
+     * 
+     * @param bounds the bounds
+     */
+    void notifyInputMethod(Rectangle bounds) {
+        // only Window actually notifies IM of bounds change
+    }
+
+    /**
+     * Sets the bounds fields.
+     * 
+     * @param x the x
+     * @param y the y
+     * @param w the w
+     * @param h the h
+     * @param bMask the b mask
+     */
+    private void setBoundsFields(int x, int y, int w, int h, int bMask) {
+        if ((bMask & NativeWindow.BOUNDS_NOSIZE) == 0) {
+            this.w = w;
+            this.h = h;
+        }
+        if ((bMask & NativeWindow.BOUNDS_NOMOVE) == 0) {
+            this.x = x;
+            this.y = y;
+        }
+    }
+
+    /**
+     * Gets the native insets.
+     * 
+     * @return the native insets
+     */
+    Insets getNativeInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * Gets the insets.
+     * 
+     * @return the insets
+     */
+    Insets getInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * Checks if is mouse exited expected.
+     * 
+     * @return true, if is mouse exited expected
+     */
+    boolean isMouseExitedExpected() {
+        return mouseExitedExpected;
+    }
+
+    /**
+     * Sets the mouse exited expected.
+     * 
+     * @param expected the new mouse exited expected
+     */
+    void setMouseExitedExpected(boolean expected) {
+        mouseExitedExpected = expected;
+    }
+
+    /**
+     * Sets the new bounding rectangle for this Component.
+     * 
+     * @param r the new bounding rectangle.
+     */
+    public void setBounds(Rectangle r) {
+        toolkit.lockAWT();
+        try {
+            setBounds(r.x, r.y, r.width, r.height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the component orientation which affects the component's
+     * elements and text within this component. 
+     * 
+     * @param o the ComponentOrientation object.
+     */
+    public void setComponentOrientation(ComponentOrientation o) {
+        ComponentOrientation oldOrientation;
+        toolkit.lockAWT();
+        try {
+            oldOrientation = orientation;
+            orientation = o;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("componentOrientation", oldOrientation, orientation); //$NON-NLS-1$
+        invalidate();
+    }
+
+    /**
+     * Sets the specified cursor for this Component.
+     * 
+     * @param cursor the new Cursor.
+     */
+    public void setCursor(Cursor cursor) {
+        toolkit.lockAWT();
+        try {
+            this.cursor = cursor;
+            setCursor();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Set current cursor shape to Component's Cursor.
+     */
+    void setCursor() {
+        if (isDisplayable() && isShowing()) {
+            Rectangle absRect = new Rectangle(getLocationOnScreen(), getSize());
+            Point absPointerPos = toolkit.dispatcher.mouseDispatcher.getPointerPos();
+            //???AWT
+            /*
+            if (absRect.contains(absPointerPos)) {
+                // set Cursor only on top-level Windows(on X11)
+                Window topLevelWnd = getWindowAncestor();
+                if (topLevelWnd != null) {
+                    Point pointerPos = MouseDispatcher.convertPoint(null, absPointerPos,
+                            topLevelWnd);
+                    Component compUnderCursor = topLevelWnd.findComponentAt(pointerPos);
+                    // if (compUnderCursor == this ||
+                    // compUnderCursor.getCursorAncestor() == this) {
+                    NativeWindow wnd = topLevelWnd.getNativeWindow();
+                    if (compUnderCursor != null && wnd != null) {
+                        compUnderCursor.getRealCursor().getNativeCursor()
+                                .setCursor(wnd.getId());
+                    }
+                    // }
+                }
+            }
+            */
+        }
+    }
+
+    /**
+     * Gets the ancestor Cursor if Component is disabled (directly or via an
+     * ancestor) even if Cursor is explicitly set.
+     * 
+     * @param value the value
+     * 
+     * @return actual Cursor to be displayed
+     */
+    //???AWT
+    /*
+    Cursor getRealCursor() {
+        Component cursorAncestor = getCursorAncestor();
+        return cursorAncestor != null ? cursorAncestor.getCursor() : Cursor.getDefaultCursor();
+    }
+    */
+
+    /**
+     * Gets the ancestor(or component itself) whose cursor is set when pointer
+     * is inside component
+     * 
+     * @return actual Cursor to be displayed
+     */
+    //???AWT
+    /*
+    Component getCursorAncestor() {
+        Component comp;
+        for (comp = this; comp != null; comp = comp.getParent()) {
+            if (comp instanceof Window || comp.isCursorSet() && comp.isKeyEnabled()) {
+                return comp;
+            }
+        }
+        return null;
+    }
+
+    public void setDropTarget(DropTarget dt) {
+        toolkit.lockAWT();
+        try {
+            if (dropTarget == dt) {
+                return;
+            }
+            DropTarget oldDropTarget = dropTarget;
+            dropTarget = dt;
+            if (oldDropTarget != null) {
+                if (behaviour.isDisplayable()) {
+                    oldDropTarget.removeNotify(peer);
+                }
+                oldDropTarget.setComponent(null);
+            }
+            if (dt != null) {
+                dt.setComponent(this);
+                if (behaviour.isDisplayable()) {
+                    dt.addNotify(peer);
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * Sets this component to the "enabled" or "disabled" state depending
+     * on the specified boolean parameter.
+     * 
+     * @param value true if this component should be enabled; false
+     * if this component should be disabled.
+     */
+    public void setEnabled(boolean value) {
+        toolkit.lockAWT();
+        try {
+            enable(value);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the enabled impl.
+     * 
+     * @param value the new enabled impl
+     */
+    void setEnabledImpl(boolean value) {
+        if (enabled != value) {
+            enabled = value;
+            setCursor();
+            if (!enabled) {
+                moveFocusOnHide();
+            }
+            behaviour.setEnabled(value);
+        }
+    }
+
+    //???AWT
+    /*
+    private void fireAccessibleStateChange(AccessibleState state, boolean value) {
+        if (behaviour.isLightweight()) {
+            return;
+        }
+        AccessibleContext ac = getAccessibleContext();
+        if (ac != null) {
+            AccessibleState oldValue = null;
+            AccessibleState newValue = null;
+            if (value) {
+                newValue = state;
+            } else {
+                oldValue = state;
+            }
+            ac.firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, oldValue,
+                    newValue);
+        }
+    }
+    */
+
+    //???AWT
+    /*
+    public void setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke> keystrokes) {
+        Set<? extends AWTKeyStroke> oldTraversalKeys;
+        String propName = "FocusTraversalKeys"; //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            Integer kId = new Integer(id);
+            KeyboardFocusManager.checkTraversalKeysID(traversalKeys, kId);
+            Map<Integer, Set<? extends AWTKeyStroke>> keys = new HashMap<Integer, Set<? extends AWTKeyStroke>>();
+            for (int kid : traversalIDs) {
+                Integer key = new Integer(kid);
+                keys.put(key, getFocusTraversalKeys(kid));
+            }
+            KeyboardFocusManager.checkKeyStrokes(traversalIDs, keys, kId, keystrokes);
+            oldTraversalKeys = traversalKeys.get(new Integer(id));
+            // put a copy of keystrokes object into map:
+            Set<? extends AWTKeyStroke> newKeys = keystrokes;
+            if (keystrokes != null) {
+                newKeys = new HashSet<AWTKeyStroke>(keystrokes);
+            }
+            traversalKeys.put(kId, newKeys);
+            String direction = ""; //$NON-NLS-1$
+            switch (id) {
+                case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+                    direction = "forward"; //$NON-NLS-1$
+                    break;
+                case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+                    direction = "backward"; //$NON-NLS-1$
+                    break;
+                case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
+                    direction = "upCycle"; //$NON-NLS-1$
+                    break;
+                case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
+                    direction = "downCycle"; //$NON-NLS-1$
+                    break;
+            }
+            propName = direction + propName;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange(propName, oldTraversalKeys, keystrokes);
+    }
+    */
+
+    /**
+     * Sets the focus traversal keys state for this component.
+     * 
+     * @param value true if the focus traversal keys state is enabled,
+     * false if the focus traversal keys state is disabled.
+     */
+    public void setFocusTraversalKeysEnabled(boolean value) {
+        boolean oldFocusTraversalKeysEnabled;
+        toolkit.lockAWT();
+        try {
+            oldFocusTraversalKeysEnabled = focusTraversalKeysEnabled;
+            focusTraversalKeysEnabled = value;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("focusTraversalKeysEnabled", oldFocusTraversalKeysEnabled, //$NON-NLS-1$
+                focusTraversalKeysEnabled);
+    }
+
+    //???AWT
+    /*
+    public void setFocusable(boolean focusable) {
+        boolean oldFocusable;
+        toolkit.lockAWT();
+        try {
+            calledSetFocusable = true;
+            oldFocusable = this.focusable;
+            this.focusable = focusable;
+            if (!focusable) {
+                moveFocus();
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("focusable", oldFocusable, focusable); //$NON-NLS-1$
+    }
+
+    public Font getFont() {
+        toolkit.lockAWT();
+        try {
+            return (font == null) && (parent != null) ? parent.getFont() : font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Sets the font for this Component.
+     * 
+     * @param f the new font of the Component.
+     */
+    public void setFont(Font f) {
+        Font oldFont;
+        toolkit.lockAWT();
+        try {
+            oldFont = font;
+            setFontImpl(f);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("font", oldFont, font); //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the font impl.
+     * 
+     * @param f the new font impl
+     */
+    void setFontImpl(Font f) {
+        font = f;
+        invalidate();
+        if (isShowing()) {
+            repaint();
+        }
+    }
+
+
+    /**
+     * Invalidate the component if it inherits the font from the parent. This
+     * method is overridden in Container.
+     * 
+     * @return true if the component was invalidated, false otherwise
+     */
+    boolean propagateFont() {
+        if (font == null) {
+            invalidate();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sets the foreground color for this Component.
+     * 
+     * @param c the new foreground color.
+     */
+    public void setForeground(Color c) {
+        Color oldFgColor;
+        toolkit.lockAWT();
+        try {
+            oldFgColor = foreColor;
+            foreColor = c;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("foreground", oldFgColor, foreColor); //$NON-NLS-1$
+        repaint();
+    }
+
+    /**
+     * Sets the background color for the Component.
+     * 
+     * @param c the new background color for this component.
+     */
+    public void setBackground(Color c) {
+        Color oldBkColor;
+        toolkit.lockAWT();
+        try {
+            oldBkColor = backColor;
+            backColor = c;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("background", oldBkColor, backColor); //$NON-NLS-1$
+        repaint();
+    }
+
+    /**
+     * Sets the flag for whether paint messages received from the operating 
+     * system should be ignored or not. 
+     * 
+     * @param value true if paint messages received from the operating 
+     * system should be ignored, false otherwise.
+     */
+    public void setIgnoreRepaint(boolean value) {
+        toolkit.lockAWT();
+        try {
+            ignoreRepaint = value;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the locale of the component.
+     * 
+     * @param locale the new Locale.
+     */
+    public void setLocale(Locale locale) {
+        Locale oldLocale;
+        toolkit.lockAWT();
+        try {
+            oldLocale = this.locale;
+            this.locale = locale;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("locale", oldLocale, locale); //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the location of the Component to the specified point.
+     * 
+     * @param p the new location of the Component
+     */
+    public void setLocation(Point p) {
+        toolkit.lockAWT();
+        try {
+            setLocation(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the location of the Component to the specified x, y coordinates.  
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     */
+    public void setLocation(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            move(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the visibility state of the component.
+     * 
+     * @param b true if the component is visible, false if the component
+     * is not shown.
+     */
+    public void setVisible(boolean b) {
+        // show() & hide() are not deprecated for Window,
+        // so have to call them from setVisible()
+        show(b);
+    }
+
+    /**
+     * Deprecated: replaced by setVisible(boolean) method.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void show() {
+        toolkit.lockAWT();
+        try {
+            if (visible) {
+                return;
+            }
+            prepare4HierarchyChange();
+            mapToDisplay(true);
+            validate();
+            visible = true;
+            behaviour.setVisible(true);
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_SHOWN));
+            //???AWT: finishHierarchyChange(this, parent, 0);
+            notifyInputMethod(new Rectangle(x, y, w, h));
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setVisible(boolean) method.
+     * 
+     * @param b the visibility's state.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void show(boolean b) {
+        if (b) {
+            show();
+        } else {
+            hide();
+        }
+    }
+
+    //???AWT
+    /*
+    void transferFocus(int dir) {
+        Container root = null;
+        if (this instanceof Container) {
+            Container cont = (Container) this;
+            if (cont.isFocusCycleRoot()) {
+                root = cont.getFocusTraversalRoot();
+            }
+        }
+        if (root == null) {
+            root = getFocusCycleRootAncestor();
+        }
+        // transfer focus up cycle if root is unreachable
+        Component comp = this;
+        while ((root != null)
+                && !(root.isFocusCycleRoot() && root.isShowing() && root.isEnabled() && root
+                        .isFocusable())) {
+            comp = root;
+            root = root.getFocusCycleRootAncestor();
+        }
+        if (root == null) {
+            return;
+        }
+        FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
+        Component nextComp = null;
+        switch (dir) {
+            case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+                nextComp = policy.getComponentAfter(root, comp);
+                break;
+            case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+                nextComp = policy.getComponentBefore(root, comp);
+                break;
+        }
+        if (nextComp != null) {
+            nextComp.requestFocus(false);
+        }
+    }
+    
+    public void transferFocus() {
+        toolkit.lockAWT();
+        try {
+            nextFocus();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    public void transferFocusBackward() {
+        toolkit.lockAWT();
+        try {
+            transferFocus(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    public void transferFocusUpCycle() {
+        toolkit.lockAWT();
+        try {
+            KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+            Container root = kfm.getCurrentFocusCycleRoot();
+            
+            if(root == null) {
+                return;
+            }
+            
+            boolean success = false;
+            Component nextComp = null;
+            Container newRoot = root;
+            do {
+                nextComp = newRoot instanceof Window ? newRoot.getFocusTraversalPolicy()
+                        .getDefaultComponent(newRoot) : newRoot;
+                newRoot = newRoot.getFocusCycleRootAncestor();
+                if (nextComp == null) {
+                    break;
+                }
+                success = nextComp.requestFocusInWindow();
+                if (newRoot == null) {
+                    break;
+                }
+                kfm.setGlobalCurrentFocusCycleRoot(newRoot);
+            } while (!success);
+            if (!success && root != newRoot) {
+                kfm.setGlobalCurrentFocusCycleRoot(root);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Validates that this component has a valid layout.
+     */
+    public void validate() {
+        toolkit.lockAWT();
+        try {
+            if (!behaviour.isDisplayable()) {
+                return;
+            }
+            validateImpl();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Validate impl.
+     */
+    void validateImpl() {
+        valid = true;
+    }
+
+    /**
+     * Gets the native window.
+     * 
+     * @return the native window
+     */
+    NativeWindow getNativeWindow() {
+        return behaviour.getNativeWindow();
+    }
+
+    /**
+     * Checks whether or not a maximum size is set for the Component.
+     * 
+     * @return true, if the maximum size is set for the Component,
+     * false otherwise.
+     */
+    public boolean isMaximumSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return maximumSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the minimum size is set for the component.
+     * 
+     * @return true, if the minimum size is set for the component,
+     * false otherwise.
+     */
+    public boolean isMinimumSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return minimumSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the preferred size is set for the Component.
+     * 
+     * @return true, if the preferred size is set for the Component,
+     * false otherwise.
+     */
+    public boolean isPreferredSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return preferredSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the maximum size of the Component.
+     * 
+     * @return the maximum size of the Component.
+     */
+    public Dimension getMaximumSize() {
+        toolkit.lockAWT();
+        try {
+            return isMaximumSizeSet() ? new Dimension(maximumSize) : new Dimension(
+                    Short.MAX_VALUE, Short.MAX_VALUE);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the minimum size of the Component.
+     * 
+     * @return the minimum size of the Component.
+     */
+    public Dimension getMinimumSize() {
+        toolkit.lockAWT();
+        try {
+            return minimumSize();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getMinimumSize() method.
+     * 
+     * @return the Dimension.
+     * 
+     * @deprecated Replaced by getMinimumSize() method.
+     */
+    @Deprecated
+    public Dimension minimumSize() {
+        toolkit.lockAWT();
+        try {
+            if (isMinimumSizeSet()) {
+                return (Dimension)minimumSize.clone();
+            }
+            Dimension defSize = getDefaultMinimumSize();
+            if (defSize != null) {
+                return (Dimension)defSize.clone();
+            }
+            return isDisplayable()? new Dimension(1, 1) : new Dimension(w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the preferred size of the Component.
+     * 
+     * @return the preferred size of the Component.
+     */
+    public Dimension getPreferredSize() {
+        toolkit.lockAWT();
+        try {
+            return preferredSize();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getPreferredSize() method.
+     * 
+     * @return the Dimension.
+     * 
+     * @deprecated Replaced by getPreferredSize() method.
+     */
+    @Deprecated
+    public Dimension preferredSize() {
+        toolkit.lockAWT();
+        try {
+            if (isPreferredSizeSet()) {
+                return new Dimension(preferredSize);
+            }
+            Dimension defSize = getDefaultPreferredSize();
+            if (defSize != null) {
+                return new Dimension(defSize);
+            }
+            return new Dimension(getMinimumSize());
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the maximum size of the Component.
+     * 
+     * @param maximumSize the new maximum size of the Component.
+     */
+    public void setMaximumSize(Dimension maximumSize) {
+        Dimension oldMaximumSize;
+        toolkit.lockAWT();
+        try {
+            oldMaximumSize = this.maximumSize;
+            if (oldMaximumSize != null) {
+                oldMaximumSize = oldMaximumSize.getSize();
+            }
+            if (this.maximumSize == null) {
+                if (maximumSize != null) {
+                    this.maximumSize = new Dimension(maximumSize);
+                }
+            } else {
+                if (maximumSize != null) {
+                    this.maximumSize.setSize(maximumSize);
+                } else {
+                    this.maximumSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("maximumSize", oldMaximumSize, this.maximumSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the minimum size of the Component.
+     * 
+     * @param minimumSize the new minimum size of the Component.
+     */
+    public void setMinimumSize(Dimension minimumSize) {
+        Dimension oldMinimumSize;
+        toolkit.lockAWT();
+        try {
+            oldMinimumSize = this.minimumSize;
+            if (oldMinimumSize != null) {
+                oldMinimumSize = oldMinimumSize.getSize();
+            }
+            if (this.minimumSize == null) {
+                if (minimumSize != null) {
+                    this.minimumSize = new Dimension(minimumSize);
+                }
+            } else {
+                if (minimumSize != null) {
+                    this.minimumSize.setSize(minimumSize);
+                } else {
+                    this.minimumSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("minimumSize", oldMinimumSize, this.minimumSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the preferred size of the Component.
+     * 
+     * @param preferredSize the new preferred size of the Component.
+     */
+    public void setPreferredSize(Dimension preferredSize) {
+        Dimension oldPreferredSize;
+        toolkit.lockAWT();
+        try {
+            oldPreferredSize = this.preferredSize;
+            if (oldPreferredSize != null) {
+                oldPreferredSize = oldPreferredSize.getSize();
+            }
+            if (this.preferredSize == null) {
+                if (preferredSize != null) {
+                    this.preferredSize = new Dimension(preferredSize);
+                }
+            } else {
+                if (preferredSize != null) {
+                    this.preferredSize.setSize(preferredSize);
+                } else {
+                    this.preferredSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("preferredSize", oldPreferredSize, this.preferredSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    RedrawManager getRedrawManager() {
+        if (parent == null) {
+            return null;
+        }
+        return parent.getRedrawManager();
+    }
+    */
+
+    /**
+     * Checks if is focusability explicitly set.
+     * 
+     * @return true if component has a focusable peer
+     */
+    //???AWT
+    /*
+    boolean isPeerFocusable() {
+        // The recommendations for Windows and Unix are that
+        // Canvases, Labels, Panels, Scrollbars, ScrollPanes, Windows,
+        // and lightweight Components have non-focusable peers,
+        // and all other Components have focusable peers.
+        if (this instanceof Canvas || this instanceof Label || this instanceof Panel
+                || this instanceof Scrollbar || this instanceof ScrollPane
+                || this instanceof Window || isLightweight()) {
+            return false;
+        }
+        return true;
+    }
+    */
+
+    /**
+     * @return true if focusability was explicitly set via a call to
+     *         setFocusable() or via overriding isFocusable() or
+     *         isFocusTraversable()
+     */
+    boolean isFocusabilityExplicitlySet() {
+        return calledSetFocusable || overridenIsFocusable;
+    }
+
+    /**
+     * Paints the component and all of its subcomponents.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    public void paintAll(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Updates this Component.
+     * 
+     * @param g the Graphics to be used for updating.
+     */
+    public void update(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            if (!isLightweight() && !isPrepainter()) {
+                g.setColor(getBackground());
+                g.fillRect(0, 0, w, h);
+                g.setColor(getForeground());
+            }
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Paints this component.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    public void paint(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            // Just to nothing
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prepares the component to be painted.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    void prepaint(Graphics g) {
+        // Just to nothing. For overriding.
+    }
+
+    /**
+     * Checks if is prepainter.
+     * 
+     * @return true, if is prepainter
+     */
+    boolean isPrepainter() {
+        return false;
+    }
+
+    /**
+     * Prepare4 hierarchy change.
+     */
+    void prepare4HierarchyChange() {
+        if (hierarchyChangingCounter++ == 0) {
+            wasShowing = isShowing();
+            wasDisplayable = isDisplayable();
+            prepareChildren4HierarchyChange();
+        }
+    }
+
+    /**
+     * Prepare children4 hierarchy change.
+     */
+    void prepareChildren4HierarchyChange() {
+        // To be inherited by Container
+    }
+
+    //???AWT
+    /*
+    void finishHierarchyChange(Component changed, Container changedParent, int ancestorFlags) {
+        if (--hierarchyChangingCounter == 0) {
+            int changeFlags = ancestorFlags;
+            if (wasShowing != isShowing()) {
+                changeFlags |= HierarchyEvent.SHOWING_CHANGED;
+            }
+            if (wasDisplayable != isDisplayable()) {
+                changeFlags |= HierarchyEvent.DISPLAYABILITY_CHANGED;
+            }
+            if (changeFlags > 0) {
+                postEvent(new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED, changed,
+                        changedParent, changeFlags));
+            }
+            finishChildrenHierarchyChange(changed, changedParent, ancestorFlags);
+        }
+    }
+
+
+    void finishChildrenHierarchyChange(Component changed, Container changedParent,
+            int ancestorFlags) {
+        // To be inherited by Container
+    }
+
+    void postHierarchyBoundsEvents(Component changed, int id) {
+        postEvent(new HierarchyEvent(this, id, changed, null, 0));
+    }
+    */
+    
+    /**
+     * Spread hierarchy bounds events.
+     * 
+     * @param changed the changed
+     * @param id the id
+     */
+    void spreadHierarchyBoundsEvents(Component changed, int id) {
+        // To be inherited by Container
+    }
+
+    /**
+     * Dispatches an event to this component.
+     * 
+     * @param e the Event.
+     */
+    public final void dispatchEvent(AWTEvent e) {
+        //???AWT
+        /*
+        if (e.isConsumed()) {
+            return;
+        }
+        if (e instanceof PaintEvent) {
+            toolkit.dispatchAWTEvent(e);
+            processPaintEvent((PaintEvent) e);
+            return;
+        }
+        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+        if (!e.dispatchedByKFM && kfm.dispatchEvent(e)) {
+            return;
+        }
+        if (e instanceof KeyEvent) {
+            KeyEvent ke = (KeyEvent) e;
+            // consumes KeyEvent which represents a focus traversal key
+            if (getFocusTraversalKeysEnabled()) {
+                kfm.processKeyEvent(this, ke);
+                if (ke.isConsumed()) {
+                    return;
+                }
+            }
+        }
+        if (inputMethodsEnabled && dispatchToIM && e.isPosted && dispatchEventToIM(e)) {
+            return;
+        }
+        if (e.getID() == WindowEvent.WINDOW_ICONIFIED) {
+            notifyInputMethod(null);
+        }
+        AWTEvent.EventDescriptor descriptor = toolkit.eventTypeLookup.getEventDescriptor(e);
+        toolkit.dispatchAWTEvent(e);
+        if (descriptor != null) {
+            if (isEventEnabled(descriptor.eventMask)
+                    || (getListeners(descriptor.listenerType).length > 0)) {
+                processEvent(e);
+            }
+            // input events can be consumed by user listeners:
+            if (!e.isConsumed() && ((enabledAWTEvents & descriptor.eventMask) != 0)) {
+                postprocessEvent(e, descriptor.eventMask);
+            }
+        }
+        postDeprecatedEvent(e);
+        */
+    }
+
+    /**
+     * Post deprecated event.
+     * 
+     * @param e the e
+     */
+    private void postDeprecatedEvent(AWTEvent e) {
+        if (deprecatedEventHandler) {
+            Event evt = e.getEvent();
+            if (evt != null) {
+                postEvent(evt);
+            }
+        }
+    }
+
+    /**
+     * Postprocess event.
+     * 
+     * @param e the e
+     * @param eventMask the event mask
+     */
+    void postprocessEvent(AWTEvent e, long eventMask) {
+        toolkit.lockAWT();
+        try {
+            // call system listeners under AWT lock
+            if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
+                preprocessFocusEvent((FocusEvent) e);
+            } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
+                preprocessKeyEvent((KeyEvent) e);
+            } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
+                preprocessMouseEvent((MouseEvent) e);
+            } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
+                preprocessMouseMotionEvent((MouseEvent) e);
+            } else if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
+                preprocessComponentEvent((ComponentEvent) e);
+            } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
+                preprocessMouseWheelEvent((MouseWheelEvent) e);
+            } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
+                preprocessInputMethodEvent((InputMethodEvent) e);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Preprocess input method event.
+     * 
+     * @param e the e
+     */
+    private void preprocessInputMethodEvent(InputMethodEvent e) {
+        processInputMethodEventImpl(e, inputMethodListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse wheel event.
+     * 
+     * @param e the e
+     */
+    private void preprocessMouseWheelEvent(MouseWheelEvent e) {
+        processMouseWheelEventImpl(e, mouseWheelListeners.getSystemListeners());
+    }
+
+    /**
+     * Process mouse wheel event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processMouseWheelEventImpl(MouseWheelEvent e, Collection<MouseWheelListener> c) {
+        for (MouseWheelListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_WHEEL:
+                    listener.mouseWheelMoved(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Preprocess component event.
+     * 
+     * @param e the e
+     */
+    private void preprocessComponentEvent(ComponentEvent e) {
+        processComponentEventImpl(e, componentListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse motion event.
+     * 
+     * @param e the e
+     */
+    void preprocessMouseMotionEvent(MouseEvent e) {
+        processMouseMotionEventImpl(e, mouseMotionListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse event.
+     * 
+     * @param e the e
+     */
+    void preprocessMouseEvent(MouseEvent e) {
+        processMouseEventImpl(e, mouseListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess key event.
+     * 
+     * @param e the e
+     */
+    void preprocessKeyEvent(KeyEvent e) {
+        processKeyEventImpl(e, keyListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess focus event.
+     * 
+     * @param e the e
+     */
+    void preprocessFocusEvent(FocusEvent e) {
+        processFocusEventImpl(e, focusListeners.getSystemListeners());
+    }
+
+    /**
+     * Processes AWTEvent occurred on this component. 
+     * 
+     * @param e the AWTEvent.
+     */
+    protected void processEvent(AWTEvent e) {
+        long eventMask = toolkit.eventTypeLookup.getEventMask(e);
+        if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
+            processComponentEvent((ComponentEvent) e);
+        } else if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
+            processFocusEvent((FocusEvent) e);
+        } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
+            processKeyEvent((KeyEvent) e);
+        } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
+            processMouseEvent((MouseEvent) e);
+        } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
+            processMouseWheelEvent((MouseWheelEvent) e);
+        } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
+            processMouseMotionEvent((MouseEvent) e);
+        } else if (eventMask == AWTEvent.HIERARCHY_EVENT_MASK) {
+            processHierarchyEvent((HierarchyEvent) e);
+        } else if (eventMask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) {
+            processHierarchyBoundsEvent((HierarchyEvent) e);
+        } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
+            processInputMethodEvent((InputMethodEvent) e);
+        }
+    }
+
+    /**
+     * Gets an array of all listener's objects based on the specified
+     * listener type and registered to this Component.
+     * 
+     * @param listenerType the listener type.
+     * 
+     * @return an array of all listener's objects based on the specified
+     * listener type and registered to this Component. 
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
+        if (ComponentListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getComponentListeners();
+        } else if (FocusListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getFocusListeners();
+        } else if (HierarchyBoundsListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getHierarchyBoundsListeners();
+        } else if (HierarchyListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getHierarchyListeners();
+        } else if (InputMethodListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getInputMethodListeners();
+        } else if (KeyListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getKeyListeners();
+        } else if (MouseWheelListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getMouseWheelListeners();
+        } else if (MouseMotionListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getMouseMotionListeners();
+        } else if (MouseListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getMouseListeners();
+        } else if (PropertyChangeListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getPropertyChangeListeners();
+        }
+        return (T[]) Array.newInstance(listenerType, 0);
+    }
+
+    /**
+     * Process paint event.
+     * 
+     * @param event the event
+     */
+    private void processPaintEvent(PaintEvent event) {
+        if (redrawManager == null) {
+            return;
+        }
+        Rectangle clipRect = event.getUpdateRect();
+        if ((clipRect.width <= 0) || (clipRect.height <= 0)) {
+            return;
+        }
+        Graphics g = getGraphics();
+        if (g == null) {
+            return;
+        }
+        initGraphics(g, event);
+        if (!getIgnoreRepaint()) {
+            if (event.getID() == PaintEvent.PAINT) {
+                paint(g);
+            } else {
+                update(g);
+            }
+        }
+        g.dispose();
+    }
+
+    /**
+     * Inits the graphics.
+     * 
+     * @param g the g
+     * @param e the e
+     */
+    void initGraphics(Graphics g, PaintEvent e) {
+        Rectangle clip = e.getUpdateRect();
+        if (clip instanceof ClipRegion) {
+            g.setClip(((ClipRegion) clip).getClip());
+        } else {
+            g.setClip(clip);
+        }
+        if (isPrepainter()) {
+            prepaint(g);
+        } else if (!isLightweight() && (e.getID() == PaintEvent.PAINT)) {
+            g.setColor(getBackground());
+            g.fillRect(0, 0, w, h);
+        }
+        g.setFont(getFont());
+        g.setColor(getForeground());
+    }
+
+    /**
+     * Enables the events with the specified event mask to be delivered to 
+     * this component.
+     * 
+     * @param eventsToEnable the events mask which specifies the types 
+     * of events to enable.
+     */
+    protected final void enableEvents(long eventsToEnable) {
+        toolkit.lockAWT();
+        try {
+            enabledEvents |= eventsToEnable;
+            deprecatedEventHandler = false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Enable awt events.
+     * 
+     * @param eventsToEnable the events to enable
+     */
+    private void enableAWTEvents(long eventsToEnable) {
+        enabledAWTEvents |= eventsToEnable;
+    }
+
+    /**
+     * Disables the events with types specified by the specified event mask 
+     * from being delivered to this component.
+     * 
+     * @param eventsToDisable the event mask specifying the event types. 
+     */
+    protected final void disableEvents(long eventsToDisable) {
+        toolkit.lockAWT();
+        try {
+            enabledEvents &= ~eventsToDisable;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /*
+     * For use in MouseDispatcher only. Really it checks not only mouse events.
+     */
+    /**
+     * Checks if is mouse event enabled.
+     * 
+     * @param eventMask the event mask
+     * 
+     * @return true, if is mouse event enabled
+     */
+    boolean isMouseEventEnabled(long eventMask) {
+        return (isEventEnabled(eventMask) || (enabledAWTEvents & eventMask) != 0);
+    }
+
+    /**
+     * Checks if is event enabled.
+     * 
+     * @param eventMask the event mask
+     * 
+     * @return true, if is event enabled
+     */
+    boolean isEventEnabled(long eventMask) {
+        return ((enabledEvents & eventMask) != 0);
+    }
+
+    /**
+     * Enables or disables input method support for this component. 
+     * 
+     * @param enable true to enable input method support, false to disable it. 
+     */
+    public void enableInputMethods(boolean enable) {
+        toolkit.lockAWT();
+        try {
+            if (!enable) {
+                removeNotifyInputContext();
+            }
+            inputMethodsEnabled = enable;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets an array of all component's listeners registered for this
+     * component.
+     * 
+     * @return an array of all component's listeners registered for this
+     * component.
+     */
+    public ComponentListener[] getComponentListeners() {
+        return componentListeners.getUserListeners(new ComponentListener[0]);
+    }
+
+    /**
+     * Adds the specified component listener to the Component for receiving
+     * component's event.
+     * 
+     * @param l the ComponentListener.
+     */
+    public void addComponentListener(ComponentListener l) {
+        componentListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the component listener registered for this Component.
+     * 
+     * @param l the ComponentListener.
+     */
+    public void removeComponentListener(ComponentListener l) {
+        componentListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a component event that has occurred on this component 
+     * by dispatching them to any registered ComponentListener objects.
+     * 
+     * @param e the ComponentEvent.
+     */
+    protected void processComponentEvent(ComponentEvent e) {
+        processComponentEventImpl(e, componentListeners.getUserListeners());
+    }
+
+    /**
+     * Process component event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processComponentEventImpl(ComponentEvent e, Collection<ComponentListener> c) {
+        for (ComponentListener listener : c) {
+            switch (e.getID()) {
+                case ComponentEvent.COMPONENT_HIDDEN:
+                    listener.componentHidden(e);
+                    break;
+                case ComponentEvent.COMPONENT_MOVED:
+                    listener.componentMoved(e);
+                    break;
+                case ComponentEvent.COMPONENT_RESIZED:
+                    listener.componentResized(e);
+                    break;
+                case ComponentEvent.COMPONENT_SHOWN:
+                    listener.componentShown(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of focus listeners registered for this Component.
+     * 
+     * @return the array of focus listeners registered for this Component.
+     */
+    public FocusListener[] getFocusListeners() {
+        return focusListeners.getUserListeners(new FocusListener[0]);
+    }
+
+    /**
+     * Adds the specified focus listener to the Component for receiving
+     * focus events.
+     * 
+     * @param l the FocusListener.
+     */
+    public void addFocusListener(FocusListener l) {
+        focusListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt focus listener.
+     * 
+     * @param l the l
+     */
+    void addAWTFocusListener(FocusListener l) {
+        enableAWTEvents(AWTEvent.FOCUS_EVENT_MASK);
+        focusListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the focus listener registered for this Component.
+     * 
+     * @param l the FocusListener.
+     */
+    public void removeFocusListener(FocusListener l) {
+        focusListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a FocusEvent that has occurred on this component
+     * by dispatching it to the registered listeners.
+     *  
+     * @param e the FocusEvent.
+     */
+    protected void processFocusEvent(FocusEvent e) {
+        processFocusEventImpl(e, focusListeners.getUserListeners());
+    }
+
+    /**
+     * Process focus event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processFocusEventImpl(FocusEvent e, Collection<FocusListener> c) {
+        for (FocusListener listener : c) {
+            switch (e.getID()) {
+                case FocusEvent.FOCUS_GAINED:
+                    listener.focusGained(e);
+                    break;
+                case FocusEvent.FOCUS_LOST:
+                    listener.focusLost(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of registered HierarchyListeners for
+     * this Component.
+     * 
+     * @return an array of registered HierarchyListeners for
+     * this Component.
+     */
+    public HierarchyListener[] getHierarchyListeners() {
+        return hierarchyListeners.getUserListeners(new HierarchyListener[0]);
+    }
+
+    /**
+     * Adds the specified hierarchy listener.
+     * 
+     * @param l the HierarchyListener.
+     */
+    public void addHierarchyListener(HierarchyListener l) {
+        hierarchyListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the hierarchy listener registered for this component.
+     * 
+     * @param l the HierarchyListener.
+     */
+    public void removeHierarchyListener(HierarchyListener l) {
+        hierarchyListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a hierarchy event that has occurred on this component
+     * by dispatching it to the registered listeners. 
+     * 
+     * @param e the HierarchyEvent.
+     */
+    protected void processHierarchyEvent(HierarchyEvent e) {
+        for (HierarchyListener listener : hierarchyListeners.getUserListeners()) {
+            switch (e.getID()) {
+                case HierarchyEvent.HIERARCHY_CHANGED:
+                    listener.hierarchyChanged(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of HierarchyBoundsListener objects registered
+     * to this Component.
+     * 
+     * @return an array of HierarchyBoundsListener objects.
+     */
+    public HierarchyBoundsListener[] getHierarchyBoundsListeners() {
+        return hierarchyBoundsListeners.getUserListeners(new HierarchyBoundsListener[0]);
+    }
+
+    /**
+     * Adds the specified hierarchy bounds listener.
+     * 
+     * @param l the HierarchyBoundsListener.
+     */
+    public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
+        hierarchyBoundsListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the hierarchy bounds listener registered for this Component.
+     * 
+     * @param l the HierarchyBoundsListener.
+     */
+    public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
+        hierarchyBoundsListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a hierarchy bounds event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     *  
+     * @param e the HierarchyBoundsEvent.
+     */
+    protected void processHierarchyBoundsEvent(HierarchyEvent e) {
+        for (HierarchyBoundsListener listener : hierarchyBoundsListeners.getUserListeners()) {
+            switch (e.getID()) {
+                case HierarchyEvent.ANCESTOR_MOVED:
+                    listener.ancestorMoved(e);
+                    break;
+                case HierarchyEvent.ANCESTOR_RESIZED:
+                    listener.ancestorResized(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the key listeners registered to the Component.
+     * 
+     * @return an array of the key listeners registered to the Component.
+     */
+    public KeyListener[] getKeyListeners() {
+        return keyListeners.getUserListeners(new KeyListener[0]);
+    }
+
+    /**
+     * Adds the specified key listener.
+     * 
+     * @param l the KeyListener.
+     */
+    public void addKeyListener(KeyListener l) {
+        keyListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt key listener.
+     * 
+     * @param l the l
+     */
+    void addAWTKeyListener(KeyListener l) {
+        enableAWTEvents(AWTEvent.KEY_EVENT_MASK);
+        keyListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the key listener registered for this Component.
+     * 
+     * @param l the KeyListener.
+     */
+    public void removeKeyListener(KeyListener l) {
+        keyListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a key event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the KeyEvent.
+     */
+    protected void processKeyEvent(KeyEvent e) {
+        processKeyEventImpl(e, keyListeners.getUserListeners());
+    }
+
+    /**
+     * Process key event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processKeyEventImpl(KeyEvent e, Collection<KeyListener> c) {
+        for (KeyListener listener : c) {
+            switch (e.getID()) {
+                case KeyEvent.KEY_PRESSED:
+                    listener.keyPressed(e);
+                    break;
+                case KeyEvent.KEY_RELEASED:
+                    listener.keyReleased(e);
+                    break;
+                case KeyEvent.KEY_TYPED:
+                    listener.keyTyped(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the mouse listeners registered to the Component.
+     * 
+     * @return an array of the mouse listeners registered to the Component.
+     */
+    public MouseListener[] getMouseListeners() {
+        return mouseListeners.getUserListeners(new MouseListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse listener.
+     * 
+     * @param l the MouseListener.
+     */
+    public void addMouseListener(MouseListener l) {
+        mouseListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt mouse listener.
+     * 
+     * @param l the l
+     */
+    void addAWTMouseListener(MouseListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_EVENT_MASK);
+        mouseListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt mouse motion listener.
+     * 
+     * @param l the l
+     */
+    void addAWTMouseMotionListener(MouseMotionListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
+        mouseMotionListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt component listener.
+     * 
+     * @param l the l
+     */
+    void addAWTComponentListener(ComponentListener l) {
+        enableAWTEvents(AWTEvent.COMPONENT_EVENT_MASK);
+        componentListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt input method listener.
+     * 
+     * @param l the l
+     */
+    void addAWTInputMethodListener(InputMethodListener l) {
+        enableAWTEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
+        inputMethodListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt mouse wheel listener.
+     * 
+     * @param l the l
+     */
+    void addAWTMouseWheelListener(MouseWheelListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
+        mouseWheelListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the mouse listener registered for this Component.
+     * 
+     * @param l the MouseListener.
+     */
+    public void removeMouseListener(MouseListener l) {
+        mouseListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the MouseEvent.
+     */
+    protected void processMouseEvent(MouseEvent e) {
+        processMouseEventImpl(e, mouseListeners.getUserListeners());
+    }
+
+    /**
+     * Process mouse event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processMouseEventImpl(MouseEvent e, Collection<MouseListener> c) {
+        for (MouseListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_CLICKED:
+                    listener.mouseClicked(e);
+                    break;
+                case MouseEvent.MOUSE_ENTERED:
+                    listener.mouseEntered(e);
+                    break;
+                case MouseEvent.MOUSE_EXITED:
+                    listener.mouseExited(e);
+                    break;
+                case MouseEvent.MOUSE_PRESSED:
+                    listener.mousePressed(e);
+                    break;
+                case MouseEvent.MOUSE_RELEASED:
+                    listener.mouseReleased(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Process mouse motion event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processMouseMotionEventImpl(MouseEvent e, Collection<MouseMotionListener> c) {
+        for (MouseMotionListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_DRAGGED:
+                    listener.mouseDragged(e);
+                    break;
+                case MouseEvent.MOUSE_MOVED:
+                    listener.mouseMoved(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the mouse motion listeners registered to
+     * the Component.
+     * 
+     * @return an array of the MouseMotionListeners registered to
+     * the Component.
+     */
+    public MouseMotionListener[] getMouseMotionListeners() {
+        return mouseMotionListeners.getUserListeners(new MouseMotionListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse motion listener.
+     * 
+     * @param l the MouseMotionListener.
+     */
+    public void addMouseMotionListener(MouseMotionListener l) {
+        mouseMotionListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the mouse motion listener registered for this component.
+     * 
+     * @param l the MouseMotionListener.
+     */
+    public void removeMouseMotionListener(MouseMotionListener l) {
+        mouseMotionListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse motion event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the MouseEvent.
+     */
+    protected void processMouseMotionEvent(MouseEvent e) {
+        processMouseMotionEventImpl(e, mouseMotionListeners.getUserListeners());
+    }
+
+    /**
+     * Gets an array of the mouse wheel listeners registered to
+     * the Component.
+     * 
+     * @return an array of the MouseWheelListeners registered to
+     * the Component.
+     */
+    public MouseWheelListener[] getMouseWheelListeners() {
+        return mouseWheelListeners.getUserListeners(new MouseWheelListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse wheel listener.
+     * 
+     * @param l the MouseWheelListener.
+     */
+    public void addMouseWheelListener(MouseWheelListener l) {
+        mouseWheelListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the mouse wheel listener registered for this component.
+     * 
+     * @param l the MouseWheelListener.
+     */
+    public void removeMouseWheelListener(MouseWheelListener l) {
+        mouseWheelListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse wheel event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the MouseWheelEvent.
+     */
+    protected void processMouseWheelEvent(MouseWheelEvent e) {
+        processMouseWheelEventImpl(e, mouseWheelListeners.getUserListeners());
+    }
+
+    /**
+     * Gets an array of the InputMethodListener listeners 
+     * registered to the Component.
+     * 
+     * @return an array of the InputMethodListener listeners 
+     * registered to the Component.
+     */
+    public InputMethodListener[] getInputMethodListeners() {
+        return inputMethodListeners.getUserListeners(new InputMethodListener[0]);
+    }
+
+    /**
+     * Adds the specified input method listener.
+     * 
+     * @param l the InputMethodListener.
+     */
+    public void addInputMethodListener(InputMethodListener l) {
+        inputMethodListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the input method listener registered for this component.
+     * 
+     * @param l the InputMethodListener.
+     */
+    public void removeInputMethodListener(InputMethodListener l) {
+        inputMethodListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes an input method event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the InputMethodEvent.
+     */
+    protected void processInputMethodEvent(InputMethodEvent e) {
+        processInputMethodEventImpl(e, inputMethodListeners.getUserListeners());
+    }
+
+    /**
+     * Process input method event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processInputMethodEventImpl(InputMethodEvent e,
+            Collection<InputMethodListener> c) {
+        for (InputMethodListener listener : c) {
+            switch (e.getID()) {
+                case InputMethodEvent.CARET_POSITION_CHANGED:
+                    listener.caretPositionChanged(e);
+                    break;
+                case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
+                    listener.inputMethodTextChanged(e);
+                    break;
+            }
+        }
+    }
+
+    //???AWT
+    /*
+    public Point getMousePosition() throws HeadlessException {
+        Point absPointerPos = MouseInfo.getPointerInfo().getLocation();
+        Window winUnderPtr = toolkit.dispatcher.mouseDispatcher.findWindowAt(absPointerPos);
+        Point pointerPos = MouseDispatcher.convertPoint(null, absPointerPos, winUnderPtr);
+        boolean isUnderPointer = false;
+        if (winUnderPtr == null) {
+            return null;
+        }
+        isUnderPointer = winUnderPtr.isComponentAt(this, pointerPos);
+        if (isUnderPointer) {
+            return MouseDispatcher.convertPoint(null, absPointerPos, this);
+        }
+        return null;
+    }
+    */
+
+    /**
+     * Set native caret at the given position <br>
+     * Note: this method takes AWT lock inside because it walks through the
+     * component hierarchy.
+     * 
+     * @param x the x
+     * @param y the y
+     */
+    void setCaretPos(final int x, final int y) {
+        Runnable r = new Runnable() {
+            public void run() {
+                toolkit.lockAWT();
+                try {
+                    setCaretPosImpl(x, y);
+                } finally {
+                    toolkit.unlockAWT();
+                }
+            }
+        };
+        if (Thread.currentThread() instanceof EventDispatchThread) {
+            r.run();
+        } else {
+            toolkit.getSystemEventQueueImpl().postEvent(new InvocationEvent(this, r));
+        }
+    }
+
+    /**
+     * This method should be called only at event dispatch thread.
+     * 
+     * @param x the x
+     * @param y the y
+     */
+    void setCaretPosImpl(int x, int y) {
+        Component c = this;
+        while ((c != null) && c.behaviour.isLightweight()) {
+            x += c.x;
+            y += c.y;
+            //???AWT: c = c.getParent();
+        }
+        if (c == null) {
+            return;
+        }
+        //???AWT
+        /*
+        if (c instanceof Window) {
+            Insets insets = c.getNativeInsets();
+            x -= insets.left;
+            y -= insets.top;
+        }
+        toolkit.getWindowFactory().setCaretPosition(x, y);
+        */
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Gets the default minimum size.
+     * 
+     * @return the default minimum size
+     */
+    Dimension getDefaultMinimumSize() {
+        return null;
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Gets the default preferred size.
+     * 
+     * @return the default preferred size
+     */
+    Dimension getDefaultPreferredSize() {
+        return null;
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Reset default size.
+     */
+    void resetDefaultSize() {
+    }
+
+    //???AWT
+    /*
+    ComponentBehavior createBehavior() {
+        return new LWBehavior(this);
+    }
+    */
+
+    /**
+     * Gets the default background.
+     * 
+     * @return the default background
+     */
+    Color getDefaultBackground() {
+        //???AWT: return getWindowAncestor().getDefaultBackground();
+        return getBackground();
+    }
+
+    /**
+     * Gets the default foreground.
+     * 
+     * @return the default foreground
+     */
+    Color getDefaultForeground() {
+        //???AWT return getWindowAncestor().getDefaultForeground();
+        return getForeground();
+    }
+
+    /**
+     * Called when native resource for this component is created (for
+     * heavyweights only).
+     * 
+     * @param win the win
+     */
+    void nativeWindowCreated(NativeWindow win) {
+        // to be overridden
+    }
+
+    /**
+     * Determine the component's area hidden behind the windows that have higher
+     * Z-order, including windows of other applications.
+     * 
+     * @param image the image
+     * @param destLocation the dest location
+     * @param destSize the dest size
+     * @param source the source
+     * 
+     * @return the calculated region, or null if it cannot be determined
+     */
+    //???AWT
+    /*
+    MultiRectArea getObscuredRegion(Rectangle part) {
+        if (!visible || parent == null || !parent.visible) {
+            return null;
+        }
+        Rectangle r = new Rectangle(0, 0, w, h);
+        if (part != null) {
+            r = r.intersection(part);
+        }
+        if (r.isEmpty()) {
+            return null;
+        }
+        r.translate(x, y);
+        MultiRectArea ret = parent.getObscuredRegion(r);
+        if (ret != null) {
+            parent.addObscuredRegions(ret, this);
+            ret.translate(-x, -y);
+            ret.intersect(new Rectangle(0, 0, w, h));
+        }
+        return ret;
+    }
+    */
+
+    //???AWT
+    /*
+    private void readObject(ObjectInputStream stream) throws IOException,
+            ClassNotFoundException {
+        stream.defaultReadObject();
+        FieldsAccessor accessor = new FieldsAccessor(Component.class, this);
+        accessor.set("toolkit", Toolkit.getDefaultToolkit()); //$NON-NLS-1$
+        accessor.set("behaviour", createBehavior()); //$NON-NLS-1$
+        accessor.set("componentLock", new Object()); // $NON-LOCK-1$ //$NON-NLS-1$
+    }
+    */
+
+    final void onDrawImage(Image image, Point destLocation, Dimension destSize, Rectangle source) {
+        ImageParameters imageParams;
+        if (updatedImages == null) {
+            updatedImages = new HashMap<Image, ImageParameters>();
+        }
+        imageParams = updatedImages.get(image);
+        if (imageParams == null) {
+            imageParams = new ImageParameters();
+            updatedImages.put(image, imageParams);
+        }
+        imageParams.addDrawing(destLocation, destSize, source);
+    }
+
+    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            boolean done = false;
+            if ((infoflags & (ALLBITS | FRAMEBITS)) != 0) {
+                done = true;
+            } else if ((infoflags & SOMEBITS) != 0 && incrementalImageUpdate) {
+                done = true;
+            }
+            if (done) {
+                repaint();
+            }
+            return (infoflags & (ABORT | ALLBITS)) == 0;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    private void invalidateRealParent() {
+        Container realParent = getRealParent();
+        if ((realParent != null) && realParent.isValid()) {
+            realParent.invalidate();
+        }
+    }
+    */
+
+    /**
+     * The Class ImageParameters.
+     */
+    private class ImageParameters {
+        
+        /** The drawing params. */
+        private final LinkedList<DrawingParameters> drawingParams = new LinkedList<DrawingParameters>();
+
+        /** The size. */
+        Dimension size = new Dimension(Component.this.w, Component.this.h);
+
+        /**
+         * Adds the drawing.
+         * 
+         * @param destLocation the dest location
+         * @param destSize the dest size
+         * @param source the source
+         */
+        void addDrawing(Point destLocation, Dimension destSize, Rectangle source) {
+            drawingParams.add(new DrawingParameters(destLocation, destSize, source));
+        }
+
+        /**
+         * Drawing parameters iterator.
+         * 
+         * @return the iterator< drawing parameters>
+         */
+        Iterator<DrawingParameters> drawingParametersIterator() {
+            return drawingParams.iterator();
+        }
+
+        /**
+         * The Class DrawingParameters.
+         */
+        class DrawingParameters {
+            
+            /** The dest location. */
+            Point destLocation;
+
+            /** The dest size. */
+            Dimension destSize;
+
+            /** The source. */
+            Rectangle source;
+
+            /**
+             * Instantiates a new drawing parameters.
+             * 
+             * @param destLocation the dest location
+             * @param destSize the dest size
+             * @param source the source
+             */
+            DrawingParameters(Point destLocation, Dimension destSize, Rectangle source) {
+                this.destLocation = new Point(destLocation);
+                if (destSize != null) {
+                    this.destSize = new Dimension(destSize);
+                } else {
+                    this.destSize = null;
+                }
+                if (source != null) {
+                    this.source = new Rectangle(source);
+                } else {
+                    this.source = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * TextComponent support.
+     * 
+     * @param e the e
+     * 
+     * @return true, if dispatch event to im
+     */
+    //???AWT
+    /*
+    private TextKit textKit = null;
+
+    TextKit getTextKit() {
+        return textKit;
+    }
+
+    void setTextKit(TextKit kit) {
+        textKit = kit;
+    }
+    */
+
+    /**
+     * TextField support
+     */
+    //???AWT
+    /*
+    private TextFieldKit textFieldKit = null;
+
+    TextFieldKit getTextFieldKit() {
+        return textFieldKit;
+    }
+
+    void setTextFieldKit(TextFieldKit kit) {
+        textFieldKit = kit;
+    }
+    */
+
+    /**
+     * Dispatches input & focus events to input method
+     * context.
+     * @param e event to pass to InputContext.dispatchEvent()
+     * @return true if event was consumed by IM, false otherwise
+     */
+    private boolean dispatchEventToIM(AWTEvent e) {
+        InputContext ic = getInputContext();
+        if (ic == null) {
+            return false;
+        }
+        int id = e.getID();
+        boolean isInputEvent = ((id >= KeyEvent.KEY_FIRST) && (id <= KeyEvent.KEY_LAST))
+                || ((id >= MouseEvent.MOUSE_FIRST) && (id <= MouseEvent.MOUSE_LAST));
+        if (((id >= FocusEvent.FOCUS_FIRST) && (id <= FocusEvent.FOCUS_LAST)) || isInputEvent) {
+            ic.dispatchEvent(e);
+        }
+        return e.isConsumed();
+    }
+}
diff --git a/awt/java/awt/ComponentBehavior.java b/awt/java/awt/ComponentBehavior.java
new file mode 100644
index 0000000..89c9999
--- /dev/null
+++ b/awt/java/awt/ComponentBehavior.java
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+/**
+ * The interface of the helper object that encapsulates the difference
+ * between lightweight and heavyweight components. 
+ */
+interface ComponentBehavior {
+
+    void addNotify();
+
+    void setBounds(int x, int y, int w, int h, int bMask);
+
+    void setVisible(boolean b);
+
+    Graphics getGraphics(int translationX, int translationY, int width, int height);
+
+    NativeWindow getNativeWindow();
+
+    boolean isLightweight();
+
+    void onMove(int x, int y);
+
+    boolean isOpaque();
+
+    boolean isDisplayable();
+
+    void setEnabled(boolean value);
+
+    void removeNotify();
+
+    void setZOrder(int newIndex, int oldIndex);
+
+    boolean setFocus(boolean focus, Component opposite);
+}
diff --git a/awt/java/awt/ComponentOrientation.java b/awt/java/awt/ComponentOrientation.java
new file mode 100644
index 0000000..ddb118d
--- /dev/null
+++ b/awt/java/awt/ComponentOrientation.java
@@ -0,0 +1,140 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * The ComponentOrientation class specifies the language-sensitive orientation 
+ * of component's elements or text. It is used to reflect the differences in this 
+ * ordering between different writting systems. The ComponentOrientation class 
+ * indicates the orientation of the elements/text in the horizontal direction
+ * ("left to right" or "right to left") and in the vertical direction
+ * ("top to bottom" or "bottom to top").
+ */
+public final class ComponentOrientation implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4113291392143563828L;
+
+    /** 
+     * The Constant LEFT_TO_RIGHT indicates that items run left to right.
+     */
+    public static final ComponentOrientation LEFT_TO_RIGHT = new ComponentOrientation(true, true);
+
+    /** 
+     * The Constant RIGHT_TO_LEFT indicates that items run right to left.
+     */
+    public static final ComponentOrientation RIGHT_TO_LEFT = new ComponentOrientation(true, false);
+
+    /** The Constant UNKNOWN indicates that a component's orientation is not set. */
+    public static final ComponentOrientation UNKNOWN = new ComponentOrientation(true, true);
+
+    /** The Constant rlLangs. */
+    private static final Set<String> rlLangs = new HashSet<String>(); //RIGHT_TO_LEFT languages
+
+    /** The horizontal. */
+    private final boolean horizontal;
+
+    /** The left2right. */
+    private final boolean left2right;
+
+    static {
+        rlLangs.add("ar"); //$NON-NLS-1$
+        rlLangs.add("fa"); //$NON-NLS-1$
+        rlLangs.add("iw"); //$NON-NLS-1$
+        rlLangs.add("ur"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the orientation for the given ResourceBundle's localization.
+     * 
+     * @param bdl the ResourceBundle.
+     * 
+     * @return the ComponentOrientation.
+     * 
+     * @deprecated Use getOrientation(java.util.Locale) method.
+     */
+    @Deprecated
+    public static ComponentOrientation getOrientation(ResourceBundle bdl) {
+        Object obj = null;
+        try {
+            obj = bdl.getObject("Orientation"); //$NON-NLS-1$
+        }
+        catch (MissingResourceException mre) {
+            obj = null;
+        }
+        if (obj instanceof ComponentOrientation) {
+            return (ComponentOrientation) obj;
+        }
+        Locale locale = bdl.getLocale();
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        return getOrientation(locale);
+    }
+
+    /**
+     * Gets the orientation for the specified locale.
+     * 
+     * @param locale the specified Locale.
+     * 
+     * @return the ComponentOrientation.
+     */
+    public static ComponentOrientation getOrientation(Locale locale) {
+        String lang = locale.getLanguage();
+        return rlLangs.contains(lang) ? RIGHT_TO_LEFT : LEFT_TO_RIGHT;
+    }
+
+    /**
+     * Instantiates a new component orientation.
+     * 
+     * @param hor whether the items should be arranged horizontally
+     * @param l2r whether this orientation specifies a left-to-right flow
+     */
+    private ComponentOrientation(boolean hor, boolean l2r) {
+        horizontal = hor;
+        left2right = l2r;
+    }
+
+    /**
+     * Returns true if the text of the of writing systems arranged
+     * horizontally.
+     * 
+     * @return true, if the text is written horizontally, false 
+     * for a vertical arrangement. 
+     */
+    public boolean isHorizontal() {
+        return horizontal;
+    }
+
+    /**
+     * Returns true if the text is arranged from left to right.
+     * 
+     * @return true, for writing systems written from left to right; 
+     * false for right-to-left.
+     */
+    public boolean isLeftToRight() {
+        return left2right;
+    }
+
+}
diff --git a/awt/java/awt/Composite.java b/awt/java/awt/Composite.java
new file mode 100644
index 0000000..8e5b90a
--- /dev/null
+++ b/awt/java/awt/Composite.java
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.ColorModel;
+
+/**
+ * The Composite interface allows the methods to compose a draw primitive 
+ * on the graphics area. The classes implementing this interface provides 
+ * the rules and a method to create the context for a particular operation.
+ */
+public interface Composite {
+
+    /**
+     * Creates a CompositeContext which defines the encapsulated and 
+     * optimized environment for a compositing operation. Several contexts 
+     * can exist for a single Composite object.
+     * 
+     * @param srcColorModel the source's ColorModel.
+     * @param dstColorModel the destination's ColorModel.
+     * @param hints the RenderingHints.
+     * 
+     * @return the CompositeContext object.
+     */
+    public CompositeContext createContext(ColorModel srcColorModel,
+            ColorModel dstColorModel, RenderingHints hints);
+
+}
+
diff --git a/awt/java/awt/CompositeContext.java b/awt/java/awt/CompositeContext.java
new file mode 100644
index 0000000..c676032
--- /dev/null
+++ b/awt/java/awt/CompositeContext.java
@@ -0,0 +1,49 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+/**
+ * The CompositeContext interface specifies the encapsulated and optimized 
+ * environment for a compositing operation. 
+ */
+public interface CompositeContext {
+
+    /**
+     * Composes the two source Raster objects and places the result in the 
+     * destination WritableRaster. 
+     * 
+     * @param src the source Raster.
+     * @param dstIn the destination Raster.
+     * @param dstOut the WritableRaster object where the result of
+     * composing operation is stored.
+     */
+    public void compose(Raster src, Raster dstIn, WritableRaster dstOut);
+
+    /**
+     * Releases resources allocated for a context.
+     */
+    public void dispose();
+
+}
+
diff --git a/awt/java/awt/Cursor.java b/awt/java/awt/Cursor.java
new file mode 100644
index 0000000..625686c
--- /dev/null
+++ b/awt/java/awt/Cursor.java
@@ -0,0 +1,372 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.NativeCursor;
+
+/**
+ * The Cursor class represents the bitmap of the mouse cursor.
+ */
+public class Cursor implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8028237497568985504L;
+    
+    /** The Constant DEFAULT_CURSOR indicates the default cursor type. */
+    public static final int DEFAULT_CURSOR = 0;
+
+    /** The Constant CROSSHAIR_CURSOR cursor type. */
+    public static final int CROSSHAIR_CURSOR = 1;
+
+    /** The Constant TEXT_CURSOR cursor type. */
+    public static final int TEXT_CURSOR = 2;
+
+    /** The Constant WAIT_CURSOR cursor type. */
+    public static final int WAIT_CURSOR = 3;
+
+    /** The Constant SW_RESIZE_CURSOR cursor type. */
+    public static final int SW_RESIZE_CURSOR = 4;
+
+    /** The Constant SE_RESIZE_CURSOR cursor type. */
+    public static final int SE_RESIZE_CURSOR = 5;
+
+    /** The Constant NW_RESIZE_CURSOR cursor type. */
+    public static final int NW_RESIZE_CURSOR = 6;
+
+    /** The Constant NE_RESIZE_CURSOR cursor type. */
+    public static final int NE_RESIZE_CURSOR = 7;
+
+    /** The Constant N_RESIZE_CURSOR cursor type. */
+    public static final int N_RESIZE_CURSOR = 8;
+
+    /** The Constant S_RESIZE_CURSOR cursor type. */
+    public static final int S_RESIZE_CURSOR = 9;
+
+    /** The Constant W_RESIZE_CURSOR cursor type. */
+    public static final int W_RESIZE_CURSOR = 10;
+
+    /** The Constant E_RESIZE_CURSOR cursor type. */
+    public static final int E_RESIZE_CURSOR = 11;
+
+    /** The Constant HAND_CURSOR cursor type. */
+    public static final int HAND_CURSOR = 12;
+
+    /** The Constant MOVE_CURSOR cursor type. */
+    public static final int MOVE_CURSOR = 13;
+
+    /** A mapping from names to system custom cursors. */
+    static Map<String, Cursor> systemCustomCursors;
+    
+    /** The cursor props. */
+    static Properties cursorProps;
+
+    /** The Constant predefinedNames. */
+    static final String[] predefinedNames = {
+            "Default", "Crosshair", "Text", "Wait", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            "Southwest Resize", "Southeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
+            "Northwest Resize", "Northeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
+            "North Resize", "South Resize", "West Resize", "East Resize", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            "Hand", "Move" //$NON-NLS-1$ //$NON-NLS-2$
+
+    };
+
+    /** The predefined set of cursors. */
+    protected static Cursor[] predefined = {
+            new Cursor(DEFAULT_CURSOR), null, null, null,
+            null, null, null, null,
+            null, null, null, null,
+            null, null
+    };
+
+    /** The Constant CUSTOM_CURSOR is associated with all custom cursor types. 
+     * (Those which are not predefined)
+     */
+    public static final int CUSTOM_CURSOR = -1;
+
+    /** The name of the cursor. */
+    protected String name;
+
+    /** The type of the cursor, chosen from the list of cursor type constants. */
+    private final int type;
+    
+    /** The native cursor. */
+    private transient NativeCursor nativeCursor;
+    
+    /** The exact point on the cursor image that indicates which point 
+     * the cursor is selecting (pointing to). The coordinates are given 
+     * with respect the origin of the Image (its upper left corner).
+     */
+    private Point hotSpot;
+    
+    /** The image to draw on the screen representing the cursor. */
+    private Image image;
+
+    /**
+     * Instantiates a new cursor with the specified name.
+     * 
+     * @param name the name of cursor.
+     */
+    protected Cursor(String name) {
+        this(name, null, new Point());
+    }
+
+    /**
+     * Instantiates a new cursor of the specified type.
+     * 
+     * @param type the type of cursor.
+     */
+    public Cursor(int type) {
+        checkType(type);
+        this.type = type;
+        if ((type >= 0) && (type < predefinedNames.length)) {
+            name = predefinedNames[type] + " Cursor"; //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Instantiates a new cursor.
+     * 
+     * @param name the name
+     * @param img the img
+     * @param hotSpot the hot spot
+     */
+    Cursor(String name, Image img, Point hotSpot) {
+        this.name = name;
+        type = CUSTOM_CURSOR;
+        this.hotSpot = hotSpot;
+        image = img;
+    }
+
+    /**
+     * Finalize method overrided finalize method from Object class.
+     * 
+     * @throws Throwable if the native cursor is not null and throws
+     * a throwable when destroyed.
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        if (nativeCursor != null) {
+            nativeCursor.destroyCursor();
+        }
+    }
+
+    /**
+     * Gets the name of the cursor.
+     * 
+     * @return the name of the cursor.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the String representation of the cursor.
+     * 
+     * @return the String representation of the cursor.
+     */
+    @Override
+    public String toString() {
+        return getClass().getName() + "[" + name + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets the cursor type.
+     * 
+     * @return the cursor type
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the predefined cursor with the specified type.
+     * 
+     * @param type the type of cursor.
+     * 
+     * @return the predefined cursor with the specified type.
+     */
+    public static Cursor getPredefinedCursor(int type) {
+        checkType(type);
+        Cursor cursor = predefined[type];
+        if (cursor == null) {
+            cursor = new Cursor(type);
+            predefined[type] = cursor;
+        }
+        return cursor;
+    }
+
+    /**
+     * Gets the default cursor.
+     * 
+     * @return the default cursor.
+     */
+    public static Cursor getDefaultCursor() {
+        return getPredefinedCursor(DEFAULT_CURSOR);
+    }
+
+    /**
+     * Gets the specified system custom cursor.
+     * 
+     * @param name the name of the desired system cursor.
+     * 
+     * @return the specific system cursor with the specified name.
+     * 
+     * @throws AWTException if the desired cursor has malformed data
+     * such as an incorrectly defined hot spot.
+     * @throws HeadlessException if the isHeadless method of the GraphicsEnvironment
+     * returns true.
+     */
+    public static Cursor getSystemCustomCursor(String name)
+    throws AWTException, HeadlessException {
+        Toolkit.checkHeadless();
+        return getSystemCustomCursorFromMap(name);
+    }
+
+    /**
+     * Gets the specified system custom cursor from the map of system custom cursors.
+     * 
+     * @param name the name of the desired cursor.
+     * 
+     * @return the desired system custom cursor from the 
+     * map of system custom cursors.
+     * 
+     * @throws AWTException the AWT exception
+     */
+    private static Cursor getSystemCustomCursorFromMap (String name)
+    throws AWTException {
+        loadCursorProps();
+        if (systemCustomCursors == null) {
+            systemCustomCursors = new HashMap<String, Cursor>();
+        }
+        Cursor cursor = systemCustomCursors.get(name);
+        if (cursor != null) {
+            return cursor;
+        }
+        // awt.141=failed to parse hotspot property for cursor:
+        String exMsg = Messages.getString("awt.141") + name; //$NON-NLS-1$
+        String nm = "Cursor." + name; //$NON-NLS-1$
+        String nameStr = cursorProps.getProperty(nm + ".Name"); //$NON-NLS-1$
+        String hotSpotStr = cursorProps.getProperty(nm + ".HotSpot"); //$NON-NLS-1$
+        String fileStr = cursorProps.getProperty(nm + ".File"); //$NON-NLS-1$
+        int idx = hotSpotStr.indexOf(',');
+        if (idx < 0) {
+            throw new AWTException(exMsg);
+        }
+        int x, y;
+        try {
+            x = new Integer(hotSpotStr.substring(0, idx)).intValue();
+            y = new Integer(hotSpotStr.substring(idx + 1,
+                                                 hotSpotStr.length())).intValue();
+        } catch (NumberFormatException nfe) {
+            throw new AWTException(exMsg);
+        }
+        Image img = Toolkit.getDefaultToolkit().createImage(fileStr);
+        cursor = new Cursor(nameStr, img, new Point(x, y));
+        systemCustomCursors.put(name, cursor);
+
+        return cursor;
+    }
+
+    /**
+     * Load cursor props.
+     * 
+     * @throws AWTException the AWT exception
+     */
+    private static void loadCursorProps() throws AWTException {
+        if (cursorProps != null) {
+            return;
+        }
+        String sep = File.separator;
+        String cursorsDir = "lib" + sep + "images" + sep + "cursors"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        String cursorsAbsDir = System.getProperty("java.home") + sep + //$NON-NLS-1$
+                                cursorsDir;
+        String cursorPropsFileName = "cursors.properties"; //$NON-NLS-1$
+        String cursorPropsFullFileName = (cursorsAbsDir + sep +
+                                          cursorPropsFileName);
+        cursorProps = new Properties();
+        try {
+            cursorProps.load(new FileInputStream(new File(
+                    cursorPropsFullFileName)));
+        } catch (FileNotFoundException e) {
+            // awt.142=Exception: class {0} {1} occurred while loading: {2}
+            throw new AWTException(Messages.getString("awt.142",//$NON-NLS-1$
+                      new Object[]{e.getClass(), e.getMessage(), cursorPropsFullFileName}));
+        } catch (IOException e) {
+            throw new AWTException(e.getMessage());
+        }
+
+    }
+
+    /**
+     * Check type.
+     * 
+     * @param type the type
+     */
+    static void checkType(int type) {
+        // can't use predefined array here because it may not have been
+        // initialized yet
+        if ((type < 0) || (type >= predefinedNames.length)) {
+            // awt.143=illegal cursor type
+            throw new IllegalArgumentException(Messages.getString("awt.143")); //$NON-NLS-1$
+        }
+    }
+
+    // "lazily" create native cursors:
+    /**
+     * Gets the native cursor.
+     * 
+     * @return the native cursor
+     */
+    NativeCursor getNativeCursor() {
+        if (nativeCursor != null) {
+            return nativeCursor;
+        }
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        if (type != CUSTOM_CURSOR) {
+            nativeCursor = toolkit.createNativeCursor(type);
+        } else {
+            nativeCursor = toolkit.createCustomNativeCursor(image, hotSpot,
+                                                            name);
+        }
+        return nativeCursor;
+    }
+
+    /**
+     * Sets the native cursor.
+     * 
+     * @param nativeCursor the new native cursor
+     */
+    void setNativeCursor(NativeCursor nativeCursor) {
+        this.nativeCursor = nativeCursor;
+    }
+}
+
diff --git a/awt/java/awt/Dimension.java b/awt/java/awt/Dimension.java
new file mode 100644
index 0000000..8137846
--- /dev/null
+++ b/awt/java/awt/Dimension.java
@@ -0,0 +1,185 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.Dimension2D;
+import java.io.Serializable;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Dimension represents the size (width and height) of a component.
+ * The width and height values can be negative, but in that case the 
+ * behavior of some methods is unexpected. 
+ */
+public class Dimension extends Dimension2D implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 4723952579491349524L;
+
+    /** The width dimension. */
+    public int width;
+    
+    /** The height dimension. */
+    public int height;
+
+    /**
+     * Instantiates a new Dimension with the same data as the specified Dimension.
+     * 
+     * @param d the Dimension to copy the data from when creating the 
+     * new Dimension object.
+     */
+    public Dimension(Dimension d) {
+        this(d.width, d.height);
+    }
+
+    /**
+     * Instantiates a new Dimension with zero width and height.
+     */
+    public Dimension() {
+        this(0, 0);
+    }
+
+    /**
+     * Instantiates a new Dimension with the specified width and height.
+     * 
+     * @param width the width of the new Dimension.
+     * @param height the height of the new Dimension.
+     */
+    public Dimension(int width, int height) {
+        setSize(width, height);
+    }
+
+    /**
+     * Returns the hash code of the Dimension.
+     * 
+     * @return the hash code of the Dimension.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(width);
+        hash.append(height);
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this Dimension object with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is a Dimension with 
+     * the same width and height data as this Dimension. 
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Dimension) {
+            Dimension d = (Dimension)obj;
+            return (d.width == width && d.height == height);
+        }
+        return false;
+    }
+
+    /**
+     * Returns the String associated to this Dimension object.
+     * 
+     * @return the String associated to this Dimension object.
+     */
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. It could be obtained in the following way
+        // System.out.println(new Dimension().toString())
+        return getClass().getName() + "[width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Sets the size of this Dimension object with the specified width and height.
+     * 
+     * @param width the width of the Dimension.
+     * @param height the height of the Dimension.
+     */
+    public void setSize(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+
+    /**
+     * Sets the size of this Dimension object by copying the 
+     * data from the specified Dimension object.
+     * 
+     * @param d the Dimension that gives the new size values.
+     */
+    public void setSize(Dimension d) {
+        setSize(d.width, d.height);
+    }
+
+    /**
+     * Sets the size of this Dimension object with the specified double width 
+     * and height.
+     * 
+     * @param width the width of the Dimension.
+     * @param height the height of the Dimension.
+     * 
+     * @see java.awt.geom.Dimension2D#setSize(double, double)
+     */
+    @Override
+    public void setSize(double width, double height) {
+        setSize((int)Math.ceil(width), (int)Math.ceil(height));
+    }
+
+    /**
+     * Gets the size of the Dimension.
+     * 
+     * @return the size of the Dimension.
+     */
+    public Dimension getSize() {
+        return new Dimension(width, height);
+    }
+
+    /**
+     * Gets the height of the Dimension.
+     * 
+     * @return the height of the Dimension.
+     * 
+     * @see java.awt.geom.Dimension2D#getHeight()
+     */
+    @Override
+    public double getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the width of the Dimension.
+     * 
+     * @return the width of the Dimension.
+     * 
+     * @see java.awt.geom.Dimension2D#getWidth()
+     */
+    @Override
+    public double getWidth() {
+        return width;
+    }
+
+}
+
diff --git a/awt/java/awt/Dispatcher.java b/awt/java/awt/Dispatcher.java
new file mode 100644
index 0000000..d457af4
--- /dev/null
+++ b/awt/java/awt/Dispatcher.java
@@ -0,0 +1,723 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+
+/**
+ * Helper package-private class for managing lightweight components &
+ * dispatching events from heavyweight source
+ */
+class Dispatcher {
+
+    //???AWT: final PopupDispatcher popupDispatcher = new PopupDispatcher();
+
+    //???AWT: final FocusDispatcher focusDispatcher;
+
+    final MouseGrabManager mouseGrabManager = new MouseGrabManager();
+
+    final MouseDispatcher mouseDispatcher;
+
+    private final ComponentDispatcher componentDispatcher = new ComponentDispatcher();
+
+    private final KeyDispatcher keyDispatcher = new KeyDispatcher();
+
+    private final Toolkit toolkit;
+
+    int clickInterval = 250;
+
+    /**
+     * @param toolkit - AWT toolkit
+     */
+    Dispatcher(Toolkit toolkit) {
+        this.toolkit = toolkit;
+
+        //???AWT: focusDispatcher = new FocusDispatcher(toolkit);
+        mouseDispatcher = new MouseDispatcher(mouseGrabManager, toolkit);
+    }
+
+    /**
+     * Dispatch native event: produce appropriate AWT events, 
+     * update component's fields when needed
+     * @param event - native event to dispatch
+     * @return - true means default processing by OS is not needed
+     */
+    public boolean onEvent(NativeEvent event) {
+        int eventId = event.getEventId();
+
+        if (eventId == NativeEvent.ID_CREATED) {
+            return toolkit.onWindowCreated(event.getWindowId());
+        } else if (eventId == NativeEvent.ID_MOUSE_GRAB_CANCELED) {
+            return mouseGrabManager.onGrabCanceled();
+        //???AWT
+//        } else if (popupDispatcher.onEvent(event)) {
+//            return false;
+        } else {
+            Component src = toolkit.getComponentById(event.getWindowId());
+
+            if (src != null) {
+                if (((eventId >= ComponentEvent.COMPONENT_FIRST) && (eventId <= ComponentEvent.COMPONENT_LAST))
+                        || ((eventId >= WindowEvent.WINDOW_FIRST) && (eventId <= WindowEvent.WINDOW_LAST))
+                        || (eventId == NativeEvent.ID_INSETS_CHANGED)
+                        || (eventId == NativeEvent.ID_BOUNDS_CHANGED)
+                        || (eventId == NativeEvent.ID_THEME_CHANGED)) {
+                    return componentDispatcher.dispatch(src, event);
+                } else if ((eventId >= MouseEvent.MOUSE_FIRST)
+                        && (eventId <= MouseEvent.MOUSE_LAST)) {
+                    return mouseDispatcher.dispatch(src, event);
+                } else if (eventId == PaintEvent.PAINT) {
+                    //???AWT: src.redrawManager.addPaintRegion(src, event.getClipRects());
+                    return true;
+                }
+            }
+            if ((eventId >= FocusEvent.FOCUS_FIRST)
+                    && (eventId <= FocusEvent.FOCUS_LAST)) {
+
+                //???AWT: return focusDispatcher.dispatch(src, event);
+                return false;
+            } else if ((eventId >= KeyEvent.KEY_FIRST)
+                    && (eventId <= KeyEvent.KEY_LAST)) {
+                return keyDispatcher.dispatch(src, event);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * The dispatcher of native events that affect 
+     * component's state or bounds
+     */
+    final class ComponentDispatcher {
+
+        /**
+         * Handle native event that affects component's state or bounds
+         * @param src - the component updated by the event
+         * @param event - the native event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatch(Component src, NativeEvent event) {
+            int id = event.getEventId();
+
+            if ((id == NativeEvent.ID_INSETS_CHANGED)
+                    || (id == NativeEvent.ID_THEME_CHANGED)) {
+                return dispatchInsets(event, src);
+            } else if ((id >= WindowEvent.WINDOW_FIRST)
+                    && (id <= WindowEvent.WINDOW_LAST)) {
+                return dispatchWindow(event, src);
+            } else {
+                return dispatchPureComponent(event, src);
+            }
+        }
+
+        /**
+         * Handle the change of top-level window's native decorations 
+         * @param event - the native event
+         * @param src - the component updated by the event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatchInsets(NativeEvent event, Component src) {
+            //???AWT
+            /*
+            if (src instanceof Window) {
+                ((Window) src).setNativeInsets(event.getInsets());
+            }
+            */
+            return false;
+        }
+
+        /**
+         * Handle the change of top-level window's state
+         * @param event - the native event
+         * @param src - the component updated by the event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatchWindow(NativeEvent event, Component src) {
+            //???AWT
+            /*
+            Window window = (Window) src;
+            int id = event.getEventId();
+
+            if (id == WindowEvent.WINDOW_CLOSING) {
+                toolkit.getSystemEventQueueImpl().postEvent(
+                          new WindowEvent(window, WindowEvent.WINDOW_CLOSING));
+
+                return true;
+            } else if (id == WindowEvent.WINDOW_STATE_CHANGED) {
+                if (window instanceof Frame) {
+                    ((Frame) window)
+                            .updateExtendedState(event.getWindowState());
+                }
+            }
+            */
+
+            return false;
+        }
+
+        /**
+         * Handle the change of component's size and/or position
+         * @param event - the native event
+         * @param src - the component updated by the event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        private boolean dispatchPureComponent(NativeEvent event, Component src) {
+            Rectangle rect = event.getWindowRect();
+            Point loc = rect.getLocation();
+            int mask;
+
+            switch (event.getEventId()) {
+            case NativeEvent.ID_BOUNDS_CHANGED:
+                mask = 0;
+                break;
+            case ComponentEvent.COMPONENT_MOVED:
+                mask = NativeWindow.BOUNDS_NOSIZE;
+                break;
+            case ComponentEvent.COMPONENT_RESIZED:
+                mask = NativeWindow.BOUNDS_NOMOVE;
+                break;
+            default:
+                // awt.12E=Unknown component event id.
+                throw new RuntimeException(Messages.getString("awt.12E")); //$NON-NLS-1$
+            }
+
+            //???AWT
+            /*
+            if (!(src instanceof Window)) {
+                Component compTo = src.getParent();
+                Component compFrom = src.getHWAncestor();
+
+                if ((compTo != null) && (compFrom != null)) {
+                    loc = MouseDispatcher.convertPoint(compFrom, loc, compTo);
+                }
+            } else {
+                int windowState = event.getWindowState();
+
+                if ((windowState >= 0) && (src instanceof Frame)) {
+                    ((Frame) src).updateExtendedState(windowState);
+                }
+            }
+            src.setBounds(loc.x, loc.y, rect.width, rect.height, mask, false);
+            */
+            
+            return false;
+        }
+
+    }
+
+    /**
+     * The dispatcher of the keyboard events
+     */
+    final class KeyDispatcher {
+
+        /**
+         * Handle the keyboard event using the KeyboardFocusManager
+         * @param src - the component receiving the event
+         * @param event - the native event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatch(Component src, NativeEvent event) {
+            int id = event.getEventId();
+            int modifiers = event.getInputModifiers();
+            int location = event.getKeyLocation();
+            int code = event.getVKey();
+            StringBuffer chars = event.getKeyChars();
+            int charsLength = chars.length();
+            long time = event.getTime();
+            char keyChar = event.getLastChar();
+
+            //???AWT
+            /*
+            if (src == null) {
+                //retarget focus proxy key events to focusOwner:
+                Window focusProxyOwner = toolkit.getFocusProxyOwnerById(event
+                        .getWindowId());
+                if (focusProxyOwner == null) {
+                    return false;
+                }
+                src = KeyboardFocusManager.actualFocusOwner;
+            }
+            */
+
+            EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
+            
+            if (src != null) {
+                eventQueue.postEvent(new KeyEvent(src, id, time, modifiers,
+                        code, keyChar, location));
+                // KEY_TYPED goes after KEY_PRESSED
+                if (id == KeyEvent.KEY_PRESSED) {
+                    for (int i = 0; i < charsLength; i++) {
+                        keyChar = chars.charAt(i);
+                        if (keyChar != KeyEvent.CHAR_UNDEFINED) {
+                            eventQueue.postEvent(new KeyEvent(src,
+                                    KeyEvent.KEY_TYPED, time, modifiers,
+                                    KeyEvent.VK_UNDEFINED, keyChar,
+                                    KeyEvent.KEY_LOCATION_UNKNOWN));
+                        }
+                    }
+                }
+            }
+
+            return false;
+        }
+
+    }
+
+    /**
+     * Retargets the mouse events to the grab owner when mouse is grabbed,
+     * grab and ungrab mouse when mouse buttons are pressed and released
+     */
+
+    static final class MouseGrabManager {
+
+        /** 
+         * The top-level window holding the mouse grab 
+         * that was explicitly started by startGrab() method
+         */
+        //???AWT: private Window nativeGrabOwner = null;
+        /** 
+         * The component that owns the synthetic 
+         * mouse grab while at least one of the
+         * mouse buttons is pressed
+         */
+        private Component syntheticGrabOwner = null;
+
+        /**
+         * Previous value of syntheticGrabOwner
+         */
+        private Component lastSyntheticGrabOwner = null;
+
+        /**
+         * Number of mouse buttons currently pressed
+         */
+        private int syntheticGrabDepth = 0;
+
+        /**
+         * The callback to be called when the explicit mouse grab ends
+         */
+        private Runnable whenCanceled;
+
+        /**
+         * Explicitly start the mouse grab
+         * @param grabWindow - the window that will own the grab
+         * @param whenCanceled - the callback to call when the grab ends. 
+         * This parameter can be null
+         */
+        //???AWT
+        /*
+        void startGrab(Window grabWindow, Runnable whenCanceled) {
+
+            if (nativeGrabOwner != null) {
+                // awt.12F=Attempt to start nested mouse grab
+                throw new RuntimeException(Messages.getString("awt.12F")); //$NON-NLS-1$
+            }
+
+            NativeWindow win = grabWindow.getNativeWindow();
+            if (win == null) {
+                // awt.130=Attempt to grab mouse in not displayable window
+                throw new RuntimeException(Messages.getString("awt.130")); //$NON-NLS-1$
+            }
+
+            nativeGrabOwner = grabWindow;
+            this.whenCanceled = whenCanceled;
+            win.grabMouse();
+        }
+        */
+
+        /**
+         * Ends the explicit mouse grab. If the non-null callback was provided
+         * in the startGrab() method, this callback is called 
+         */
+        void endGrab() {
+            //???AWT
+            /*
+            if (nativeGrabOwner == null) {
+                return;
+            }
+
+            Window grabWindow = nativeGrabOwner;
+            nativeGrabOwner = null;
+            NativeWindow win = grabWindow.getNativeWindow();
+
+            if (win != null) {
+                win.ungrabMouse();
+                if (whenCanceled != null) {
+                    whenCanceled.run();
+                    whenCanceled = null;
+                }
+            }
+            */
+        }
+
+        /**
+         * Ends both explicit and synthetic grans 
+         * @return - always returns false
+         */
+        boolean onGrabCanceled() {
+            endGrab();
+            resetSyntheticGrab();
+
+            return false;
+        }
+
+        /**
+         * Starts the synthetic mouse grab, increases the counter 
+         * of currently pressed mouse buttons
+         * @param source - the component where mouse press event occured
+         * @return - the component that owns the synthetic grab
+         */
+        Component onMousePressed(Component source) {
+            if (syntheticGrabDepth == 0) {
+                syntheticGrabOwner = source;
+                lastSyntheticGrabOwner = source;
+            }
+            syntheticGrabDepth++;
+
+            return syntheticGrabOwner;
+        }
+
+        /**
+         * Decreases the counter of currently pressed mouse buttons,
+         * ends the synthetic mouse grab, when this counter becomes zero
+         * @param source - the component where mouse press event occured
+         * @return - the component that owns the synthetic grab, 
+         * or source parameter if mouse grab was released
+         */
+        Component onMouseReleased(Component source) {
+            Component ret = source;
+
+            //???AWT
+            /*
+            if (syntheticGrabOwner != null && nativeGrabOwner == null) {
+                ret = syntheticGrabOwner;
+            }
+            */
+            syntheticGrabDepth--;
+            if (syntheticGrabDepth <= 0) {
+                resetSyntheticGrab();
+                lastSyntheticGrabOwner = null;
+            }
+
+            return ret;
+        }
+
+        /**
+         * Update the state of synthetic ouse gram 
+         * when the mouse is moved/dragged
+         * @param event - the native event
+         */
+        void preprocessEvent(NativeEvent event) {
+            int id = event.getEventId();
+            switch (id) {
+            case MouseEvent.MOUSE_MOVED:
+                if (syntheticGrabOwner != null) {
+                    syntheticGrabOwner = null;
+                    syntheticGrabDepth = 0;
+                }
+                if (lastSyntheticGrabOwner != null) {
+                    lastSyntheticGrabOwner = null;
+                }
+            case MouseEvent.MOUSE_DRAGGED:
+                if (syntheticGrabOwner == null
+                        && lastSyntheticGrabOwner != null) {
+                    syntheticGrabOwner = lastSyntheticGrabOwner;
+                    syntheticGrabDepth = 0;
+                    int mask = event.getInputModifiers();
+                    syntheticGrabDepth += (mask & InputEvent.BUTTON1_DOWN_MASK) != 0 ? 1
+                            : 0;
+                    syntheticGrabDepth += (mask & InputEvent.BUTTON2_DOWN_MASK) != 0 ? 1
+                            : 0;
+                    syntheticGrabDepth += (mask & InputEvent.BUTTON3_DOWN_MASK) != 0 ? 1
+                            : 0;
+                }
+            }
+        }
+
+        /**
+         * @return the component that currently owns the synthetic grab 
+         */
+        Component getSyntheticGrabOwner() {
+            return syntheticGrabOwner;
+        }
+
+        /**
+         * ends synthetic grab
+         */
+        private void resetSyntheticGrab() {
+            syntheticGrabOwner = null;
+            syntheticGrabDepth = 0;
+        }
+
+    }
+    
+    /**
+     * Dispatches native events related to the pop-up boxes 
+     * (the non-component windows such as menus and drop lists)
+     */
+//    final class PopupDispatcher {
+//
+//        private PopupBox activePopup;
+//
+//        private PopupBox underCursor;
+//
+//        private final MouseGrab grab = new MouseGrab();
+//
+//        /**
+//         * Handles the mouse grab for pop-up boxes
+//         */
+//        private final class MouseGrab {
+//            private int depth;
+//
+//            private PopupBox owner;
+//
+//            private final Point start = new Point();
+//
+//            /**
+//             * Starts the grab when mouse is pressed
+//             * @param src - the pop-up box where mouse event has occured
+//             * @param where - the mouse pointer location
+//             * @return - the grab owner
+//             */
+//            PopupBox mousePressed(PopupBox src, Point where) {
+//                if (depth == 0) {
+//                    owner = src;
+//                    start.setLocation(where);
+//                }
+//                depth++;
+//                return owner;
+//            }
+//
+//            /**
+//             * Ends the grab when all mousebuttons are released
+//             * @param src - the pop-up box where mouse event has occured
+//             * @param where - the mouse pointer location
+//             * @return - the grab owner, or src parameter if the grab has ended
+//             */
+//            PopupBox mouseReleased(PopupBox src, Point where) {
+//                PopupBox ret = (owner != null) ? owner : src;
+//                if (depth == 0) {
+//                    return ret;
+//                }
+//                depth--;
+//                if (depth == 0) {
+//                    PopupBox tgt = owner;
+//                    owner = null;
+//                    if (tgt != null && src == null) {
+//                        Point a = new Point(start);
+//                        Point b = new Point(where);
+//                        Point pos = tgt.getScreenLocation();
+//                        a.translate(-pos.x, -pos.y);
+//                        b.translate(-pos.x, -pos.y);
+//                        if (tgt.closeOnUngrab(a, b)) {
+//                            return null;
+//                        }
+//                    }
+//                }
+//                return ret;
+//            }
+//
+//            /**
+//             * Set the grab owner to null
+//             */
+//            void reset() {
+//                depth = 0;
+//                owner = null;
+//                start.setLocation(0, 0);
+//            }
+//
+//            /**
+//             * @return - the pop-up box currently owning the grab
+//             */
+//            public PopupBox getOwner() {
+//                return owner;
+//            }
+//        }
+//
+//        /**
+//         * Call the mouse event handler of the pop-up box
+//         * @param src - the pop-up box where the mouse event occured
+//         * @param eventId - the event ID, one of MouseEvent.MOUSE_* constants
+//         * @param where - the mouse pointer location
+//         * @param event - native event
+//         */
+//        private void mouseEvent(PopupBox src, int eventId, Point where,
+//                NativeEvent event) {
+//            Point pos = src.getScreenLocation();
+//            pos.setLocation(where.x - pos.x, where.y - pos.y);
+//
+//            src.onMouseEvent(eventId, pos, event.getMouseButton(), event
+//                    .getTime(), event.getInputModifiers(), event
+//                    .getWheelRotation());
+//        }
+//
+//        /**
+//         * Handle the native event targeted by a pop-up box. This could be 
+//         * paint event, mouse or keyboard event.
+//         * @param event - the native event
+//         * @return - false if the event was handled and doesn't 
+//         * need the further processing; true when the further 
+//         * processing is needed
+//         */
+//        boolean onEvent(NativeEvent event) {
+//            PopupBox src = toolkit.getPopupBoxById(event.getWindowId());
+//            int id = event.getEventId();
+//
+//            if ((id == PaintEvent.PAINT)) {
+//                if (src != null) {
+//                    src.paint(event.getClipRects());
+//                    return true;
+//                }
+//                Component c = toolkit.getComponentById(event.getWindowId());
+//                if ((c != null) && (c instanceof Frame)) {
+//                    ((Frame) c).paintMenuBar(event.getClipRects());
+//                }
+//                return false;
+//            }
+//
+//            if ((id >= MouseEvent.MOUSE_FIRST) && (id <= MouseEvent.MOUSE_LAST)) {
+//                Point where = event.getScreenPos();
+//
+//                if (src != underCursor) {
+//                    if (underCursor != null) {
+//                        mouseEvent(underCursor, MouseEvent.MOUSE_EXITED, where,
+//                                event);
+//                    }
+//                    underCursor = src;
+//                    if (underCursor != null) {
+//                        mouseEvent(underCursor, MouseEvent.MOUSE_ENTERED,
+//                                where, event);
+//                        underCursor.setDefaultCursor();
+//                    }
+//                }
+//                if (id == MouseEvent.MOUSE_EXITED) {
+//                    underCursor = null;
+//                }
+//
+//                if ((activePopup == null) && (src == null || !src.isMenuBar())) {
+//                    return false;
+//                }
+//
+//                if (id == MouseEvent.MOUSE_PRESSED) {
+//                    src = grab.mousePressed(src, where);
+//                } else if (id == MouseEvent.MOUSE_RELEASED) {
+//                    src = grab.mouseReleased(src, where);
+//                } else if (src == null) {
+//                    src = grab.getOwner();
+//                }
+//
+//                PopupBox wasActive = activePopup;
+//
+//                if (src != null) {
+//                    mouseEvent(src, id, where, event);
+//                    return src.isMenu() || src.contains(where);
+//                }
+//
+//                if (wasActive != null && activePopup == null) {
+//                    return wasActive.isMenu();
+//                }
+//
+//                if ((id == MouseEvent.MOUSE_PRESSED)
+//                        || (id == MouseEvent.MOUSE_RELEASED)) {
+//                    boolean isMenu = activePopup.isMenu();
+//                    deactivateAll();
+//                    return !isMenu;
+//                }
+//                return true;
+//            }
+//
+//            if (activePopup == null) {
+//                return false;
+//            }
+//
+//            if ((id >= KeyEvent.KEY_FIRST) && (id <= KeyEvent.KEY_LAST)) {
+//                boolean isMenu = activePopup.isMenu();
+//                activePopup.dispatchKeyEvent(id, event.getVKey(), event
+//                        .getTime(), event.getInputModifiers());
+//
+//                return isMenu;
+//            }
+//
+//            return false;
+//        }
+//
+//        /**
+//         * Remember the pop-up as active and grab the mouse on it
+//         * @param popup - the pop-up box to activate
+//         */
+//        void activate(final PopupBox popup) {
+//            if (activePopup == null) {
+//
+//                activePopup = popup;
+//                mouseGrabManager.startGrab(popup.getOwner(), new Runnable() {
+//                    public void run() {
+//                        deactivate(popup);
+//                    }
+//                });
+//            }
+//        }
+//
+//        /**
+//         * Deactivate the currently active pop-up box
+//         */
+//        void deactivateAll() {
+//            deactivate(activePopup);
+//        }
+//
+//        /**
+//         * Deactivate the pop-up box, end the mouse grab
+//         */
+//        void deactivate(PopupBox popup) {
+//            grab.reset();
+//
+//            if (activePopup != null && activePopup == popup) {
+//                activePopup = null;
+//                mouseGrabManager.endGrab();
+//                popup.hide();
+//                underCursor = null;
+//            }
+//        }
+//
+//        /**
+//         * Check that the pop-up box is currently active
+//         * @param popup - the pop-up box to check
+//         * @return - true if active
+//         */
+//        boolean isActive(PopupBox popup) {
+//            return (popup == activePopup) && (popup != null);
+//        }
+//    }
+
+}
\ No newline at end of file
diff --git a/awt/java/awt/DisplayMode.java b/awt/java/awt/DisplayMode.java
new file mode 100644
index 0000000..082c7b8
--- /dev/null
+++ b/awt/java/awt/DisplayMode.java
@@ -0,0 +1,147 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The DisplayMode class containes the bit depth, height, width and 
+ * refresh rate of a GraphicsDevice.
+ */
+public final class DisplayMode {
+    
+    /** The width. */
+    private final int width;
+
+    /** The height. */
+    private final int height;
+
+    /** The bit depth. */
+    private final int bitDepth;
+
+    /** The refresh rate. */
+    private final int refreshRate;
+
+   /** The Constant Value BIT_DEPTH_MULTI indicates the bit depth */
+
+    public static final int BIT_DEPTH_MULTI = -1;
+
+    /** The Constant REFRESH_RATE_UNKNOWN indicates the refresh rate. */
+    public static final int REFRESH_RATE_UNKNOWN = 0;
+
+   /**
+    * Creates a new DisplayMode object with the specified parameters.
+    *  
+    * @param width the width of the display.
+    * @param height the height of the display.
+    * @param bitDepth the bit depth of the display.
+    * @param refreshRate the refresh rate of the display.
+    */
+
+    public DisplayMode(int width, int height, int bitDepth, int refreshRate) {
+        this.width = width;
+        this.height = height;
+        this.bitDepth = bitDepth;
+        this.refreshRate = refreshRate;
+    }
+
+
+   /**
+    * Compares if this DisplayMode is equal to the specified object or not.
+    * 
+    * @param dm the Object to be compared.
+    * 
+    * @return true, if the specified object is a DisplayMode with the same
+    * data values as this DisplayMode, false otherwise.
+    */
+
+    @Override
+    public boolean equals(Object dm) {
+        if (dm instanceof DisplayMode) {
+            return equals((DisplayMode)dm);
+        }
+        return false;
+    }
+
+    /**
+    * Compares if this DisplayMode is equal to the specified DisplayMode object
+    * or not.
+    * 
+    * @param dm the DisplayMode to be compared.
+    * 
+    * @return true, if all of the data values of this DisplayMode are equal 
+    * to the values of the specified DisplayMode object, false otherwise.
+     */
+    public boolean equals(DisplayMode dm) {
+        if (dm == null) {
+            return false;
+        }
+        if (dm.bitDepth != bitDepth) {
+            return false;
+        }
+        if (dm.refreshRate != refreshRate) {
+            return false;
+        }
+        if (dm.width != width) {
+            return false;
+        }
+        if (dm.height != height) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Gets the bit depth of the DisplayMode, returns BIT_DEPTH_MULTI value
+     * if multiple bit depths are supported in this display mode.
+     * 
+     * @return the bit depth of the DisplayMode.
+     */
+    public int getBitDepth() {
+        return bitDepth;
+    }
+
+    /**
+     * Gets the height of the DisplayMode.
+     * 
+     * @return the height of the DisplayMode.
+     */
+    public int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the refresh rate of the DisplayMode, returns REFRESH_RATE_UNKNOWN
+     * value if the information is not available.
+     * 
+     * @return the refresh rate of the DisplayMode.
+     */
+    public int getRefreshRate() {
+        return refreshRate;
+    }
+
+    /**
+     * Gets the width of the DisplayMode.
+     * 
+     * @return the width of the DisplayMode.
+     */
+    public int getWidth() {
+        return width;
+    }
+}
diff --git a/awt/java/awt/Event.java b/awt/java/awt/Event.java
new file mode 100644
index 0000000..f074258
--- /dev/null
+++ b/awt/java/awt/Event.java
@@ -0,0 +1,479 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.Serializable;
+
+/**
+ * The Event Class is obsolete and has been replaced by AWTEvent class.
+ * 
+ */
+public class Event implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 5488922509400504703L;
+    
+    /** 
+     * The Constant SHIFT_MASK indicates that the Shift key is down when 
+     * the event occurred.
+     */
+    public static final int SHIFT_MASK = 1;
+
+    /** 
+     * The Constant CTRL_MASK indicates that the Control key is down when 
+     * the event occurred.
+     */
+    public static final int CTRL_MASK = 2;
+
+    /** The Constant META_MASK indicates that the Meta key is down when t
+     * he event occurred (or the right mouse button). */
+    public static final int META_MASK = 4;
+
+    /** 
+     * The Constant ALT_MASK indicates that the Alt key is down when 
+     * the event occurred (or the middle mouse button). 
+     */
+    public static final int ALT_MASK = 8;
+
+    /** The Constant HOME indicates Home key. */
+    public static final int HOME = 1000;
+
+    /** The Constant END indicates End key. */
+    public static final int END = 1001;
+
+    /** The Constant PGUP indicates Page Up key. */
+    public static final int PGUP = 1002;
+
+    /** The Constant PGDN indicates Page Down key. */
+    public static final int PGDN = 1003;
+
+    /** The Constant UP indicates Up key. */
+    public static final int UP = 1004;
+
+    /** The Constant DOWN indicates Down key. */
+    public static final int DOWN = 1005;
+
+    /** The Constant LEFT indicates Left key. */
+    public static final int LEFT = 1006;
+
+    /** The Constant RIGHT indicates Right key. */
+    public static final int RIGHT = 1007;
+
+    /** The Constant F1 indicates F1 key. */
+    public static final int F1 = 1008;
+
+    /** The Constant F2 indicates F2 key. */
+    public static final int F2 = 1009;
+
+    /** The Constant F3 indicates F3 key. */
+    public static final int F3 = 1010;
+
+    /** The Constant F4 indicates F4 key. */
+    public static final int F4 = 1011;
+
+    /** The Constant F5 indicates F5 key. */
+    public static final int F5 = 1012;
+
+    /** The Constant F6 indicates F6 key. */
+    public static final int F6 = 1013;
+
+    /** The Constant F7 indicates F7 key. */
+    public static final int F7 = 1014;
+
+    /** The Constant F8 indicates F8 key. */
+    public static final int F8 = 1015;
+
+    /** The Constant F9 indicates F9 key. */
+    public static final int F9 = 1016;
+
+    /** The Constant F10 indicates F10 key. */
+    public static final int F10 = 1017;
+
+    /** The Constant F11 indicates F11 key. */
+    public static final int F11 = 1018;
+
+    /** The Constant F12 indicates F12 key. */
+    public static final int F12 = 1019;
+
+    /** The Constant PRINT_SCREEN  indicates Print Screen key. */
+    public static final int PRINT_SCREEN = 1020;
+
+    /** The Constant SCROLL_LOCK indicates Scroll Lock key. */
+    public static final int SCROLL_LOCK = 1021;
+
+    /** The Constant CAPS_LOCK indicates Caps Lock key. */
+    public static final int CAPS_LOCK = 1022;
+
+    /** The Constant NUM_LOCK indicates Num Lock key. */
+    public static final int NUM_LOCK = 1023;
+
+    /** The Constant PAUSE indicates Pause key. */
+    public static final int PAUSE = 1024;
+
+    /** The Constant INSERT indicates Insert key. */
+    public static final int INSERT = 1025;
+
+    /** The Constant ENTER indicates Enter key. */
+    public static final int ENTER = 10;
+
+    /** The Constant BACK_SPACE indicates Back Space key. */
+    public static final int BACK_SPACE = 8;
+
+    /** The Constant TAB indicates TAb key. */
+    public static final int TAB = 9;
+
+    /** The Constant ESCAPE indicates Escape key. */
+    public static final int ESCAPE = 27;
+
+    /** The Constant DELETE indicates Delete key. */
+    public static final int DELETE = 127;
+
+    /** 
+     * The Constant WINDOW_DESTROY indicates an event when the user has asked the
+     * window manager to kill the window.
+     */
+    public static final int WINDOW_DESTROY = 201;
+
+    /** 
+     * The Constant WINDOW_EXPOSE indicates an event when the user has asked the
+     * window manager to expose the window.
+     */
+    public static final int WINDOW_EXPOSE = 202;
+
+    /** 
+     * The Constant WINDOW_ICONIFY indicates an event when the user has asked the
+     * window manager to inconify the window.
+     */
+    public static final int WINDOW_ICONIFY = 203;
+
+    /** 
+     * The Constant WINDOW_DEICONIFY indicates an event when the user has asked the
+     * window manager to deinconify the window. 
+     */
+    public static final int WINDOW_DEICONIFY = 204;
+
+    /** 
+     * The Constant WINDOW_MOVED indicates an event when the user has asked the
+     * window manager to move the window. 
+     */
+    public static final int WINDOW_MOVED = 205;
+
+    /** 
+     * The Constant KEY_PRESS indicates an event when the user presses 
+     * a normal key. 
+     */
+    public static final int KEY_PRESS = 401;
+
+    /** 
+     * The Constant KEY_RELEASE indicates an event when the user releases 
+     * a normal key.
+     */
+    public static final int KEY_RELEASE = 402;
+
+    /** 
+     * The Constant KEY_ACTION indicates an event when the user pressed 
+     * a non-ASCII action key. 
+     */
+    public static final int KEY_ACTION = 403;
+
+    /**
+     * The Constant KEY_ACTION_RELEASE indicates an event when the user released 
+     * a non-ASCII action key. 
+     */
+    public static final int KEY_ACTION_RELEASE = 404;
+
+    /** 
+     * The Constant MOUSE_DOWN indicates an event when the user has pressed 
+     * the mouse button. 
+     */
+    public static final int MOUSE_DOWN = 501;
+
+    /** 
+     * The Constant MOUSE_UP indicates an event when the user has released 
+     * the mouse button. 
+     */
+    public static final int MOUSE_UP = 502;
+
+    /** 
+     * The Constant MOUSE_MOVE indicates an event when the user has moved
+     * the mouse with no button pressed.
+     */
+    public static final int MOUSE_MOVE = 503;
+
+    /** 
+     * The Constant MOUSE_ENTER indicates an event when the mouse
+     * has entered a component.
+     */
+    public static final int MOUSE_ENTER = 504;
+
+    /** 
+     * The Constant MOUSE_EXIT indicates an event when the mouse
+     * has exited a component. 
+     */
+    public static final int MOUSE_EXIT = 505;
+
+    /** The Constant MOUSE_DRAG indicates an event when the user
+     * has moved a mouse with the pressed button. 
+     */
+    public static final int MOUSE_DRAG = 506;
+
+    /** 
+     * The Constant SCROLL_LINE_UP indicates an event when the user has
+     * activated line-up area of scrollbar.
+     */
+    public static final int SCROLL_LINE_UP = 601;
+
+    /**
+     * The Constant SCROLL_LINE_DOWN indicates an event when the user has
+     * activated line-down area of scrollbar. 
+     */
+    public static final int SCROLL_LINE_DOWN = 602;
+
+    /**
+     * The Constant SCROLL_PAGE_UP indicates an event when the user has
+     * activated page up area of scrollbar. 
+     */
+    public static final int SCROLL_PAGE_UP = 603;
+
+    /**
+     * The Constant SCROLL_PAGE_DOWN indicates an event when the user has
+     * activated page down area of scrollbar. 
+     */
+    public static final int SCROLL_PAGE_DOWN = 604;
+
+    /**
+     * The Constant SCROLL_ABSOLUTE indicates an event when the user 
+     * has moved the bubble in a scroll bar. 
+     */
+    public static final int SCROLL_ABSOLUTE = 605;
+
+    /** The Constant SCROLL_BEGIN indicates a scroll begin event. */
+    public static final int SCROLL_BEGIN = 606;
+
+    /** The Constant SCROLL_END indicates a scroll end event. */
+    public static final int SCROLL_END = 607;
+
+    /** 
+     * The Constant LIST_SELECT indicates that an item in a list 
+     * has been selected.
+     */
+    public static final int LIST_SELECT = 701;
+
+    /** 
+     * The Constant LIST_DESELECT indicates that an item in a list 
+     * has been deselected. 
+     */
+    public static final int LIST_DESELECT = 702;
+
+    /** 
+     * The Constant ACTION_EVENT indicates that the user wants some 
+     * action to occur.
+     */
+    public static final int ACTION_EVENT = 1001;
+
+    /** The Constant LOAD_FILE indicates a file loading event. */
+    public static final int LOAD_FILE = 1002;
+
+    /** The Constant SAVE_FILE indicates a file saving event. */
+    public static final int SAVE_FILE = 1003;
+
+    /** The Constant GOT_FOCUS indicates that a component got the focus. */
+    public static final int GOT_FOCUS = 1004;
+
+    /** The Constant LOST_FOCUS indicates that the component lost the focus. */
+    public static final int LOST_FOCUS = 1005;
+
+    /** The target is the component with which the event is associated. */
+    public Object target;
+
+    /** The when is timestamp when event has occured. */
+    public long when;
+
+    /** The id indicates the type of the event. */
+    public int id;
+
+    /** The x coordinate of event. */
+    public int x;
+
+    /** The y coordinate of event. */
+    public int y;
+
+    /** The key code of key event. */
+    public int key;
+
+    /** The state of the modifier keys (given by a bitmask). */
+    public int modifiers;
+
+    /** The click count indicates the number of consecutive clicks. */
+    public int clickCount;
+
+    /** The argument of the event. */
+    public Object arg;
+
+    /** The next event. */
+    public Event evt;
+
+    /**
+     * Instantiates a new event with the specified target component, 
+     * event type, and argument.
+     * 
+     * @param target the target component.
+     * @param id the event type.
+     * @param arg the argument.
+     */
+    public Event(Object target, int id, Object arg) {
+        this(target, 0l, id, 0, 0, 0, 0, arg);
+    }
+
+    /**
+     * Instantiates a new event with the specified target component, time stamp,
+     * event type, x and y coordinates, keyboard key, state of the modifier
+     * keys, and an argument set to null.
+     * 
+     * @param target the target component.
+     * @param when the time stamp.
+     * @param id the event type.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param key the key.
+     * @param modifiers the modifier keys state.
+     */
+    public Event(Object target, long when, int id, int x, int y, int key, int modifiers) {
+        this(target, when, id, x, y, key, modifiers, null);
+    }
+
+    /**
+     * Instantiates a new event with the specified target component, time stamp,
+     * event type, x and y coordinates, keyboard key, state of the modifier
+     * keys, and an argument.
+     * 
+     * @param target the target component.
+     * @param when the time stamp.
+     * @param id the event type.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param key the key.
+     * @param modifiers the modifier keys state.
+     * @param arg the specified argument.
+     */
+    public Event(Object target, long when, int id, int x, int y, int key, int modifiers, Object arg) {
+        this.target = target;
+        this.when = when;
+        this.id = id;
+        this.x = x;
+        this.y = y;
+        this.key = key;
+        this.modifiers = modifiers;
+        this.arg = arg;
+    }
+
+    /**
+     * Returns a string representation of this Event.
+     * 
+     * @return a string representation of this Event.
+     */
+    @Override
+    public String toString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * Event e = new Event(new Button(), 0l, Event.KEY_PRESS, 
+         *                     0, 0, Event.TAB, Event.SHIFT_MASK, "arg");
+         * System.out.println(e);
+         */
+
+        return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Returns a string representing the state of this Event.
+     * 
+     * @return a string representing the state of this Event.
+     */
+    protected String paramString() {
+        return "id=" + id + ",x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        (key != 0 ? ",key=" + key  + getModifiersString() : "") + //$NON-NLS-1$ //$NON-NLS-2$
+        ",target=" + target + //$NON-NLS-1$
+        (arg != null ? ",arg=" + arg : ""); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets a string representation of the modifiers.
+     * 
+     * @return a string representation of the modifiers
+     */
+    private String getModifiersString() {
+        String strMod = ""; //$NON-NLS-1$
+        if (shiftDown()) {
+            strMod += ",shift"; //$NON-NLS-1$
+        }
+        if (controlDown()) {
+            strMod += ",control"; //$NON-NLS-1$
+        }
+        if (metaDown()) {
+            strMod += ",meta"; //$NON-NLS-1$
+        }
+        return strMod;
+    }
+
+    /**
+     * Translates x and y coordinates of his event to the x+dx and x+dy 
+     * coordinates.
+     * 
+     * @param dx the dx - the distance by which the event's x coordinate
+     * is increased 
+     * @param dy the dy - the distance by which the event's y coordinate
+     * is increased 
+     */
+    public void translate(int dx, int dy) {
+        x += dx;
+        y += dy;
+    }
+
+    /**
+     * Checks if Control key is down or not.
+     * 
+     * @return true, if Control key is down; false otherwise.
+     */
+    public boolean controlDown() {
+        return (modifiers & CTRL_MASK) != 0;
+    }
+
+    /**
+     * Checks if Meta key is down or not.
+     * 
+     * @return true, if Meta key is down; false otherwise.
+     */
+    public boolean metaDown() {
+        return (modifiers & META_MASK) != 0;
+    }
+
+    /**
+     * Checks if Shift key is down or not.
+     * 
+     * @return true, if Shift key is down; false otherwise.
+     */
+    public boolean shiftDown() {
+        return (modifiers & SHIFT_MASK) != 0;
+    }
+
+}
+
diff --git a/awt/java/awt/EventDispatchThread.java b/awt/java/awt/EventDispatchThread.java
new file mode 100644
index 0000000..442c8a2
--- /dev/null
+++ b/awt/java/awt/EventDispatchThread.java
@@ -0,0 +1,118 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+
+class EventDispatchThread extends Thread  {
+    
+    private static final class MarkerEvent extends AWTEvent {
+        MarkerEvent(Object source, int id) {
+            super(source, id);
+        }
+    }
+
+    final Dispatcher dispatcher;
+    final Toolkit toolkit;
+    private NativeEventQueue nativeQueue;
+
+    protected volatile boolean shutdownPending = false;
+
+    /**
+     * Initialise and run the main event loop
+     */
+    @Override
+    public void run() {
+        nativeQueue = toolkit.getNativeEventQueue();
+
+        try {
+            runModalLoop(null);
+        } finally {
+            toolkit.shutdownWatchdog.forceShutdown();
+        }
+    }
+
+    void runModalLoop(ModalContext context) {
+        long lastPaintTime = System.currentTimeMillis();
+        while (!shutdownPending && (context == null || context.isModalLoopRunning())) {
+            try {
+            EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
+
+            NativeEvent ne = nativeQueue.getNextEvent();
+            if (ne != null) {
+                dispatcher.onEvent(ne);
+                MarkerEvent marker = new MarkerEvent(this, 0);
+                eventQueue.postEvent(marker);
+                for (AWTEvent ae = eventQueue.getNextEventNoWait(); 
+                        (ae != null) && (ae != marker); 
+                        ae = eventQueue.getNextEventNoWait()) {
+                    eventQueue.dispatchEvent(ae);
+                }
+            } else {
+                toolkit.shutdownWatchdog.setNativeQueueEmpty(true);
+                AWTEvent ae = eventQueue.getNextEventNoWait();
+                if (ae != null) {
+                    eventQueue.dispatchEvent(ae);
+                    long curTime = System.currentTimeMillis();
+                    if (curTime - lastPaintTime > 10) {
+                        toolkit.onQueueEmpty();
+                        lastPaintTime = System.currentTimeMillis();
+                    }
+                } else {
+                    toolkit.shutdownWatchdog.setAwtQueueEmpty(true);
+                    toolkit.onQueueEmpty();
+                    lastPaintTime = System.currentTimeMillis();
+                    waitForAnyEvent();
+                }
+            }
+            } catch (Throwable t) {
+                // TODO: Exception handler should be implemented
+                // t.printStackTrace();
+            }
+        }
+    }
+    
+    private void waitForAnyEvent() {
+        EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
+        if (!eventQueue.isEmpty() || !nativeQueue.isEmpty()) {
+            return;
+        }
+        Object eventMonitor = nativeQueue.getEventMonitor();
+        synchronized(eventMonitor) {
+            try {
+                eventMonitor.wait();
+            } catch (InterruptedException e) {}
+        }
+    }
+
+    void shutdown() {
+        shutdownPending = true;
+    }
+
+    EventDispatchThread(Toolkit toolkit, Dispatcher dispatcher ) {
+        this.toolkit = toolkit;
+        this.dispatcher = dispatcher;
+        setName("AWT-EventDispatchThread"); //$NON-NLS-1$
+        setDaemon(true);
+    }
+
+}
diff --git a/awt/java/awt/EventQueue.java b/awt/java/awt/EventQueue.java
new file mode 100644
index 0000000..3997546
--- /dev/null
+++ b/awt/java/awt/EventQueue.java
@@ -0,0 +1,310 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.InvocationEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.EmptyStackException;
+
+/**
+ * The EventQueue class manages events. It is a platform-independent class 
+ * that queues events both from the underlying peer classes and from trusted 
+ * application classes.
+ */
+public class EventQueue {
+    
+    /** The core ref. */
+    private final EventQueueCoreAtomicReference coreRef = 
+            new EventQueueCoreAtomicReference();
+    
+    /**
+     * The Class EventQueueCoreAtomicReference.
+     */
+    private static final class EventQueueCoreAtomicReference {
+        
+        /** The core. */
+        private EventQueueCore core;
+
+        /*synchronized*/ /**
+         * Gets the.
+         * 
+         * @return the event queue core
+         */
+        EventQueueCore get() { 
+            return core;
+        }
+
+        /*synchronized*/ /**
+         * Sets the.
+         * 
+         * @param newCore the new core
+         */
+        void set(EventQueueCore newCore) { 
+            core = newCore;
+        }
+    }
+
+    /**
+     * Returns true if the calling thread is the current 
+     * AWT EventQueue's dispatch thread. 
+     * 
+     * @return true, if the calling thread is the current 
+     * AWT EventQueue's dispatch thread; false otherwise.
+     */
+    public static boolean isDispatchThread() {
+        return Thread.currentThread() instanceof EventDispatchThread;
+    }
+
+    /**
+     * Posts an InvocationEvent which executes the run() method on a Runnable 
+     * when dispatched by the AWT event dispatcher thread.
+     * 
+     * @param runnable the Runnable whose run method should be executed 
+     * synchronously on the EventQueue.
+     */
+    public static void invokeLater(Runnable runnable) {
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        InvocationEvent event = new InvocationEvent(toolkit, runnable);
+        toolkit.getSystemEventQueueImpl().postEvent(event);
+    }
+
+    /**
+     * Posts an InvocationEvent which executes the run() method on a Runnable 
+     * when dispatched by the AWT event dispatcher thread and the 
+     * notifyAll method is called on it immediately after run returns.
+     * 
+     * @param runnable the Runnable whose run method should be executed 
+     * synchronously on the EventQueue.
+     * 
+     * @throws InterruptedException if another thread has interrupted 
+     * this thread.
+     * @throws InvocationTargetException if a throwable is thrown 
+     * when running the runnable. 
+     */
+    public static void invokeAndWait(Runnable runnable)
+            throws InterruptedException, InvocationTargetException {
+
+        if (isDispatchThread()) {
+            throw new Error();
+        }
+
+        final Toolkit toolkit = Toolkit.getDefaultToolkit();
+        final Object notifier = new Object();  //$NON-LOCK-1$
+        InvocationEvent event = new InvocationEvent(
+                toolkit, runnable, notifier, true);
+
+        synchronized (notifier) {
+            toolkit.getSystemEventQueueImpl().postEvent(event);
+            notifier.wait();
+        }
+
+        Exception exception = event.getException();
+
+        if (exception != null) {
+            throw new InvocationTargetException(exception);
+        }
+    }
+
+    /**
+     * Gets the system event queue.
+     * 
+     * @return the system event queue
+     */
+    private static EventQueue getSystemEventQueue() {
+        Thread th = Thread.currentThread();
+        if (th instanceof EventDispatchThread) {
+            return ((EventDispatchThread)th).toolkit.getSystemEventQueueImpl();
+        }
+        return null;
+    }
+    
+    /**
+     * Gets the most recent event's timestamp.
+     * This event was dispatched from the EventQueue associated with the 
+     * calling thread.
+     * 
+     * @return the timestamp of the last Event to be dispatched, 
+     * or System.currentTimeMillis() if this method is invoked from 
+     * a thread other than an event-dispatching thread.
+     */
+    public static long getMostRecentEventTime() {
+        EventQueue eq = getSystemEventQueue();
+        return (eq != null) ? 
+                eq.getMostRecentEventTimeImpl() : System.currentTimeMillis();
+    }
+    
+    /**
+     * Gets the most recent event time impl.
+     * 
+     * @return the most recent event time impl
+     */
+    private long getMostRecentEventTimeImpl() {
+        return getCore().getMostRecentEventTime();
+    }
+
+    /**
+     * Returns the the currently dispatched event by the EventQueue 
+     * associated with the calling thread.
+     * 
+     * @return the currently dispatched event or null if this method 
+     * is invoked from a thread other than an event-dispatching thread.
+     */
+    public static AWTEvent getCurrentEvent() {
+        EventQueue eq = getSystemEventQueue();
+        return (eq != null) ? 
+                eq.getCurrentEventImpl() : null;
+    }
+
+    /**
+     * Gets the current event impl.
+     * 
+     * @return the current event impl
+     */
+    private AWTEvent getCurrentEventImpl() {
+        return getCore().getCurrentEvent();
+    }
+
+    /**
+     * Instantiates a new event queue.
+     */
+    public EventQueue() {
+        setCore(new EventQueueCore(this));
+    }
+
+    /**
+     * Instantiates a new event queue.
+     * 
+     * @param t the t
+     */
+    EventQueue(Toolkit t) {
+        setCore(new EventQueueCore(this, t));
+    }
+
+    /**
+     * Posts a event to the EventQueue.
+     * 
+     * @param event AWTEvent.
+     */
+    public void postEvent(AWTEvent event) {
+        event.isPosted = true;
+        getCore().postEvent(event);
+    }
+
+    /**
+     * Returns an event from the EventQueue and removes it from this queue. 
+     *  
+     * @return the next AWTEvent.
+     * 
+     * @throws InterruptedException is thrown if another thread 
+     * interrupts this thread.
+     */
+    public AWTEvent getNextEvent() throws InterruptedException {
+        return getCore().getNextEvent();
+    }
+    
+    /**
+     * Gets the next event no wait.
+     * 
+     * @return the next event no wait
+     */
+    AWTEvent getNextEventNoWait() {
+        return getCore().getNextEventNoWait();
+    }
+
+    /**
+     * Returns the first event of the EventQueue (without removing it 
+     * from the queue).
+     * 
+     * @return the the first AWT event of the EventQueue.
+     */
+    public AWTEvent peekEvent() {
+        return getCore().peekEvent();
+    }
+
+    /**
+     * Returns the first event of the EventQueue with the specified ID
+     * (without removing it from the queue).
+     * 
+     * @param id the type ID of event.
+     * 
+     * @return the first event of the EventQueue with the specified ID.
+     */
+    public AWTEvent peekEvent(int id) {
+        return getCore().peekEvent(id);
+    }
+
+    /**
+     * Replaces the existing EventQueue with the specified EventQueue. 
+     * Any pending events are transferred to the new EventQueue. 
+     * 
+     * @param newEventQueue the new event queue.
+     */
+    public void push(EventQueue newEventQueue) {
+        getCore().push(newEventQueue);
+    }
+    
+    /**
+     * Stops dispatching events using this EventQueue. 
+     * Any pending events are transferred to the previous EventQueue.
+     * 
+     * @throws EmptyStackException is thrown if no previous push 
+     * was made on this EventQueue.
+     */
+    protected void pop() throws EmptyStackException {
+        getCore().pop();
+    }
+
+    /**
+     * Dispatches the specified event.
+     * 
+     * @param event the AWTEvent.
+     */
+    protected void dispatchEvent(AWTEvent event) {
+        getCore().dispatchEventImpl(event);
+    }
+
+    /**
+     * Checks if the queue is empty.
+     * 
+     * @return true, if is empty
+     */
+    boolean isEmpty() {
+        return getCore().isEmpty();
+    }
+
+    /**
+     * Gets the core.
+     * 
+     * @return the core
+     */
+    EventQueueCore getCore() {
+        return coreRef.get();
+    }
+    
+    /**
+     * Sets the core.
+     * 
+     * @param newCore the new core
+     */
+    void setCore(EventQueueCore newCore) {
+        coreRef.set((newCore != null) ? newCore : new EventQueueCore(this));
+    }
+}
diff --git a/awt/java/awt/EventQueueCore.java b/awt/java/awt/EventQueueCore.java
new file mode 100644
index 0000000..ffc7c46
--- /dev/null
+++ b/awt/java/awt/EventQueueCore.java
@@ -0,0 +1,253 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InvocationEvent;
+import java.awt.event.MouseEvent;
+import java.util.LinkedList;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The events storage for EventQueue
+ */
+final class EventQueueCore {
+    
+    private final LinkedList<EventQueue> queueStack = new LinkedList<EventQueue>();
+    private final LinkedList<AWTEvent> events = new LinkedList<AWTEvent>();
+    
+    private Toolkit toolkit;
+    private EventQueue activeQueue;
+    private Thread dispatchThread;
+    
+    AWTEvent currentEvent;
+    long mostRecentEventTime = System.currentTimeMillis();
+    
+    EventQueueCore(EventQueue eq) {
+        synchronized (this) {
+            queueStack.addLast(eq);
+            activeQueue = eq;
+        }
+    }
+
+    EventQueueCore(EventQueue eq, Toolkit t) {
+        synchronized (this) {
+            queueStack.addLast(eq);
+            activeQueue = eq;
+            setToolkit(t);
+        }
+    }
+
+    synchronized long getMostRecentEventTime() {
+        return mostRecentEventTime;
+    }
+    
+    synchronized AWTEvent getCurrentEvent() {
+        return currentEvent;
+    }
+    
+    synchronized boolean isSystemEventQueue() {
+        return toolkit != null;
+    }
+    
+    private void setToolkit(Toolkit t) {
+        toolkit = t;
+        if (toolkit != null) {
+            toolkit.setSystemEventQueueCore(this);
+            dispatchThread = toolkit.dispatchThread;
+        }
+    }
+
+    synchronized void postEvent(AWTEvent event) {
+        //???AWT
+        /*
+        events.addLast(event);
+        if ((toolkit == null) && (dispatchThread == null)) {
+            dispatchThread = new EventQueueThread(this);
+            dispatchThread.start();
+        }
+        // TODO: add event coalescing
+        if (toolkit != null) {
+            toolkit.shutdownWatchdog.setAwtQueueEmpty(false);
+            if (!GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance()) {
+                notifyEventMonitor(toolkit);
+            }
+        }
+        notifyAll();
+        */
+    }
+    
+    void notifyEventMonitor(Toolkit t) {
+        Object em = t.getNativeEventQueue().getEventMonitor();
+        synchronized (em) {
+            em.notifyAll();
+        }
+    }
+    
+    synchronized AWTEvent getNextEvent() throws InterruptedException {
+        while (events.isEmpty()) {
+            wait();
+        }
+        AWTEvent event = events.removeFirst();
+        // TODO: add event coalescing
+        return event;
+    }    
+    
+    synchronized AWTEvent peekEvent() {
+        return events.isEmpty() ? null : events.getFirst();
+    }
+    
+    synchronized AWTEvent peekEvent(int id) {
+        for (AWTEvent event : events) {
+            if (event.getID() == id) {
+                return event;
+            }
+        }
+        return null;
+    }
+    
+    synchronized void dispatchEvent(AWTEvent event) {
+        updateCurrentEventAndTime(event);
+        try {
+            activeQueue.dispatchEvent(event);
+        } finally {
+            currentEvent = null;
+        }
+    }
+    
+    void dispatchEventImpl(AWTEvent event) {
+        if (event instanceof ActiveEvent) {
+            updateCurrentEventAndTime(event);
+            try {
+                ((ActiveEvent) event).dispatch();
+            } finally {
+                currentEvent = null;
+            }
+            return;
+        }
+
+        Object src = event.getSource();
+
+        if (src instanceof Component) {
+            if (preprocessComponentEvent(event)) {
+                ((Component) src).dispatchEvent(event);
+            }
+        } else {
+            if (toolkit != null) {
+                toolkit.dispatchAWTEvent(event);
+            }
+            if (src instanceof MenuComponent) {
+                ((MenuComponent) src).dispatchEvent(event);
+            }
+        }
+    }
+
+    private final boolean preprocessComponentEvent(AWTEvent event) {
+      if (event instanceof MouseEvent) {
+          return preprocessMouseEvent((MouseEvent)event);
+      }
+      return true;
+    }
+
+    private final boolean preprocessMouseEvent(MouseEvent event) {
+        //???AWT
+        /*
+      if (toolkit != null && toolkit.mouseEventPreprocessor != null) {
+          toolkit.lockAWT();
+          try {
+              return toolkit.mouseEventPreprocessor.preprocess(event);
+          } finally {
+              toolkit.unlockAWT();
+          }
+      }
+      return true;
+        */
+        return true;
+    }
+    
+    private void updateCurrentEventAndTime(AWTEvent event) {
+        currentEvent = event;
+        long when = 0;
+        if (event instanceof ActionEvent) {
+            when = ((ActionEvent) event).getWhen();
+        } else if (event instanceof InputEvent) {
+            when = ((InputEvent) event).getWhen();
+        } else if (event instanceof InputMethodEvent) {
+            when = ((InputMethodEvent) event).getWhen();
+        } else if (event instanceof InvocationEvent) {
+            when = ((InvocationEvent) event).getWhen();
+        }
+        if (when != 0) {
+            mostRecentEventTime = when;
+        }
+    }
+    
+    synchronized void push(EventQueue newEventQueue) {
+        // TODO: handle incorrect situations
+        if (queueStack.isEmpty()) {
+            // awt.6B=Queue stack is empty
+            throw new IllegalStateException(Messages.getString("awt.6B")); //$NON-NLS-1$
+        }
+        
+        queueStack.addLast(newEventQueue);
+        activeQueue = newEventQueue;
+        activeQueue.setCore(this);
+    }
+    
+    synchronized void pop() {
+        EventQueue removed = queueStack.removeLast();
+        if (removed != activeQueue) {
+            // awt.6C=Event queue stack is broken
+            throw new IllegalStateException(Messages.getString("awt.6C")); //$NON-NLS-1$
+        }
+        activeQueue = queueStack.getLast();
+        removed.setCore(null);
+    }
+
+    synchronized AWTEvent getNextEventNoWait() {
+        try {
+            return events.isEmpty() ? null : activeQueue.getNextEvent();
+        } catch (InterruptedException e) {
+            return null;
+        }
+    }
+
+    synchronized boolean isEmpty() {
+        return (currentEvent == null) && events.isEmpty();
+    }
+    
+    synchronized boolean isEmpty(long timeout) {
+        if (!isEmpty()) {
+            return false;
+        }
+        try {
+            wait(timeout);
+        } catch (InterruptedException e) {}
+        return isEmpty();
+    }
+    
+    synchronized EventQueue getActiveEventQueue() {
+        return activeQueue;
+    }
+}
diff --git a/awt/java/awt/Font.java b/awt/java/awt/Font.java
new file mode 100644
index 0000000..139ae68
--- /dev/null
+++ b/awt/java/awt/Font.java
@@ -0,0 +1,1500 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineMetrics;
+import java.awt.font.TextAttribute;
+import java.awt.font.TransformAttribute;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.text.CharacterIterator;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.gl.font.AndroidGlyphVector;
+import org.apache.harmony.awt.gl.font.CommonGlyphVector;
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.gl.font.LineMetricsImpl;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The Font class represents fonts for rendering text. 
+ * This class allow to map characters to glyphs.
+ * <p> 
+ * A glyph is a shape used to render a character or a sequence of 
+ * characters. For example one character of Latin writing system 
+ * represented by one glyth, but in complex writing system such as 
+ * South and South-East Asian there is more complicated correspondence 
+ * between characters and glyphs.
+ * <p>
+ * The Font object is identified by two types of names. The logical font name 
+ * is the name that is used to construct the font. The font name
+ * is the name of a particular font face (for example, Arial Bold). 
+ * The family name is the font's family name that specifies 
+ * the typographic design across several faces (for example, Arial). In 
+ * all the Font is identified by three attributes: the family name, 
+ * the style (such as bold or italic), and the size.
+ */
+public class Font implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4206021311591459213L;
+
+    // Identity Transform attribute
+    /** The Constant IDENTITY_TRANSFORM. */
+    private static final TransformAttribute IDENTITY_TRANSFORM = new TransformAttribute(
+            new AffineTransform());
+
+    /** The Constant PLAIN indicates font's plain style. */
+    public static final int PLAIN = 0;
+
+    /** The Constant BOLD indicates font's bold style. */
+    public static final int BOLD = 1;
+
+    /** The Constant ITALIC indicates font's italic style. */
+    public static final int ITALIC = 2;
+
+    /** The Constant ROMAN_BASELINE indicated roman baseline. */
+    public static final int ROMAN_BASELINE = 0;
+
+    /** The Constant CENTER_BASELINE indicates center baseline. */
+    public static final int CENTER_BASELINE = 1;
+
+    /** The Constant HANGING_BASELINE indicates hanging baseline. */
+    public static final int HANGING_BASELINE = 2;
+
+    /** 
+     * The Constant TRUETYPE_FONT indicates a font resource of 
+     * type TRUETYPE. 
+     */
+    public static final int TRUETYPE_FONT = 0;
+
+    /** 
+     * The Constant TYPE1_FONT indicates a font resource of
+     * type TYPE1. 
+     */
+    public static final int TYPE1_FONT = 1;
+
+    /** 
+     * The Constant LAYOUT_LEFT_TO_RIGHT indicates that text is
+     * left to right. 
+     */
+    public static final int LAYOUT_LEFT_TO_RIGHT = 0;
+
+    /** 
+     * The Constant LAYOUT_RIGHT_TO_LEFT indicates that text is
+     * right to left. 
+     */
+    public static final int LAYOUT_RIGHT_TO_LEFT = 1;
+
+    /** 
+     * The Constant LAYOUT_NO_START_CONTEXT indicates that the text
+     * in the char array before the indicated start should not be examined. 
+     */
+    public static final int LAYOUT_NO_START_CONTEXT = 2;
+
+    /** The Constant LAYOUT_NO_LIMIT_CONTEXT indicates that text in 
+     * the char array after the indicated limit should not be examined. */
+    public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
+
+    /** The Constant DEFAULT_FONT. */
+    static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 12); //$NON-NLS-1$
+
+    /** The name of the Font. */
+    protected String name;
+
+    /** The style of the Font. */
+    protected int style;
+
+    /** The size of the Font. */
+    protected int size;
+
+    /** The point size of the Font. */
+    protected float pointSize;
+
+    // Flag if the Font object transformed
+    /** The transformed. */
+    private boolean transformed;
+
+    // Set of font attributes
+    /** The requested attributes. */
+    private Hashtable<Attribute, Object> fRequestedAttributes;
+
+    // font peer object corresponding to this Font
+    /** The font peer. */
+    private transient FontPeerImpl fontPeer;
+
+    // number of glyphs in this Font
+    /** The num glyphs. */
+    private transient int numGlyphs = -1;
+
+    // code for missing glyph for this Font
+    /** The missing glyph code. */
+    private transient int missingGlyphCode = -1;
+
+    /**
+     * Writes object to ObjectOutputStream.
+     * 
+     * @param out ObjectOutputStream
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+    }
+
+    /**
+     * Reads object from ObjectInputStream object and set native platform
+     * dependent fields to default values.
+     * 
+     * @param in ObjectInputStream object
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void readObject(java.io.ObjectInputStream in) throws IOException,
+            ClassNotFoundException {
+        in.defaultReadObject();
+
+        numGlyphs = -1;
+        missingGlyphCode = -1;
+
+    }
+
+    /**
+     * Instantiates a new Font with the specified attributes. 
+     * The Font will be created with default attributes 
+     * if the attribute's parameter is null. 
+     * 
+     * @param attributes the attributes to be assigned to the new Font, or null.
+     */
+    public Font(Map<? extends Attribute, ?> attributes) {
+        Object currAttr;
+
+        // Default values are taken from the documentation of the Font class.
+        // See Font constructor, decode and getFont sections.
+
+        this.name = "default"; //$NON-NLS-1$
+        this.size = 12;
+        this.pointSize = 12;
+        this.style = Font.PLAIN;
+
+        if (attributes != null) {
+
+            fRequestedAttributes = new Hashtable<Attribute, Object>(attributes);
+
+            currAttr = attributes.get(TextAttribute.SIZE);
+            if (currAttr != null) {
+                this.pointSize = ((Float) currAttr).floatValue();
+                this.size = (int) Math.ceil(this.pointSize);
+            }
+
+            currAttr = attributes.get(TextAttribute.POSTURE);
+            if (currAttr != null
+                    && currAttr.equals(TextAttribute.POSTURE_OBLIQUE)) {
+                this.style |= Font.ITALIC;
+            }
+
+            currAttr = attributes.get(TextAttribute.WEIGHT);
+            if ((currAttr != null)
+                    && (((Float) currAttr).floatValue() >= (TextAttribute.WEIGHT_BOLD)
+                            .floatValue())) {
+                this.style |= Font.BOLD;
+            }
+
+            currAttr = attributes.get(TextAttribute.FAMILY);
+            if (currAttr != null) {
+                this.name = (String) currAttr;
+            }
+
+            currAttr = attributes.get(TextAttribute.TRANSFORM);
+            if (currAttr != null) {
+                if (currAttr instanceof TransformAttribute) {
+                    this.transformed = !((TransformAttribute) currAttr)
+                            .getTransform().isIdentity();
+                } else if (currAttr instanceof AffineTransform) {
+                    this.transformed = !((AffineTransform) currAttr)
+                            .isIdentity();
+                }
+            }
+
+        } else {
+            fRequestedAttributes = new Hashtable<Attribute, Object>(5);
+            fRequestedAttributes.put(TextAttribute.TRANSFORM,
+                    IDENTITY_TRANSFORM);
+
+            this.transformed = false;
+
+            fRequestedAttributes.put(TextAttribute.FAMILY, name);
+
+            fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
+
+            if ((this.style & Font.BOLD) != 0) {
+                fRequestedAttributes.put(TextAttribute.WEIGHT,
+                        TextAttribute.WEIGHT_BOLD);
+            } else {
+                fRequestedAttributes.put(TextAttribute.WEIGHT,
+                        TextAttribute.WEIGHT_REGULAR);
+            }
+            if ((this.style & Font.ITALIC) != 0) {
+                fRequestedAttributes.put(TextAttribute.POSTURE,
+                        TextAttribute.POSTURE_OBLIQUE);
+            } else {
+                fRequestedAttributes.put(TextAttribute.POSTURE,
+                        TextAttribute.POSTURE_REGULAR);
+            }
+
+        }
+    }
+
+    /**
+     * Instantiates a new Font with the specified name, style and size.
+     * 
+     * @param name the name of font.
+     * @param style the style of font.
+     * @param size the size of font.
+     */
+    public Font(String name, int style, int size) {
+
+        this.name = (name != null) ? name : "Default"; //$NON-NLS-1$
+        this.size = (size >= 0) ? size : 0;
+        this.style = (style & ~0x03) == 0 ? style : Font.PLAIN;
+        this.pointSize = this.size;
+
+        fRequestedAttributes = new Hashtable<Attribute, Object>(5);
+
+        fRequestedAttributes.put(TextAttribute.TRANSFORM, IDENTITY_TRANSFORM);
+
+        this.transformed = false;
+
+        fRequestedAttributes.put(TextAttribute.FAMILY, this.name);
+        fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
+
+        if ((this.style & Font.BOLD) != 0) {
+            fRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else {
+            fRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_REGULAR);
+        }
+        if ((this.style & Font.ITALIC) != 0) {
+            fRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else {
+            fRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_REGULAR);
+        }
+    }
+
+    /**
+     * Returns true if this Font has a glyph for the specified character.
+     * 
+     * @param c the character.
+     * 
+     * @return true if this Font has a glyph for the specified character,
+     * false otherwise.
+     */
+    public boolean canDisplay(char c) {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.canDisplay(c);
+    }
+
+    /**
+     * Returns true if the Font can display the characters of the 
+     * the specified text from the specified start position 
+     * to the specified limit position. 
+     * 
+     * @param text the text.
+     * @param start the start offset (in the character array).
+     * @param limit the limit offset (in the character array).
+     * 
+     * @return the a character's position in the text that this Font 
+     * can not display, or -1 if this Font can display all characters 
+     * in this text.
+     */
+    public int canDisplayUpTo(char[] text, int start, int limit) {
+        int st = start;
+        int result;
+        while ((st < limit) && canDisplay(text[st])) {
+            st++;
+        }
+
+        if (st == limit) {
+            result = -1;
+        } else {
+            result = st;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns true if the Font can display the characters of the 
+     * the specified CharacterIterator from the specified start position 
+     * and the specified limit position. 
+     * 
+     * @param iter the CharacterIterator.
+     * @param start the start offset.
+     * @param limit the limit offset.
+     * 
+     * @return the a character's position in the CharacterIterator
+     * that this Font can not display, or -1 if this Font can display 
+     * all characters in this text.
+     */
+    public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
+        int st = start;
+        char c = iter.setIndex(start);
+        int result;
+
+        while ((st < limit) && (canDisplay(c))) {
+            st++;
+            c = iter.next();
+        }
+        if (st == limit) {
+            result = -1;
+        } else {
+            result = st;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns true if this Font can display a specified String.
+     * 
+     * @param str the String.
+     * 
+     * @return the a character's position in the String that 
+     * this Font can not display, or -1 if this Font can display 
+     * all characters in this text.
+     */
+    public int canDisplayUpTo(String str) {
+        char[] chars = str.toCharArray();
+        return canDisplayUpTo(chars, 0, chars.length);
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param chars the characters array.
+     * 
+     * @return the GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, char[] chars) {
+        return new AndroidGlyphVector(chars, frc, this, 0);
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters contained
+     * in the specified CharacterIterator to glyphs based on 
+     * the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param iter the CharacterIterator.
+     * 
+     * @return the GlyphVector of associating characters contained
+     * in the specified CharacterIterator to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc,
+            CharacterIterator iter) {
+    	throw new RuntimeException("Not implemented!"); //$NON-NLS-1$    
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs based on 
+     * the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param glyphCodes the specified integer array of glyph codes.
+     * 
+     * @return the GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, int[] glyphCodes)
+            throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented!"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs based on 
+     * the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param str the specified String.
+     * 
+     * @return the GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, String str) {
+        return new AndroidGlyphVector(str.toCharArray(), frc, this, 0);
+
+    }
+
+    /**
+     * Returns the font style constant value corresponding to one of the font style
+     * names ("BOLD", "ITALIC", "BOLDITALIC"). This method returns Font.PLAIN if
+     * the argument is not one of the predefined style names.
+     * 
+     * @param fontStyleName font style name
+     * 
+     * @return font style constant value corresponding to the font style name
+     * specified.
+     */
+    private static int getFontStyle(String fontStyleName) {
+        int result = Font.PLAIN;
+
+        if (fontStyleName.toUpperCase().equals("BOLDITALIC")) { //$NON-NLS-1$
+            result = Font.BOLD | Font.ITALIC;
+        } else if (fontStyleName.toUpperCase().equals("BOLD")) { //$NON-NLS-1$
+            result = Font.BOLD;
+        } else if (fontStyleName.toUpperCase().equals("ITALIC")) { //$NON-NLS-1$
+            result = Font.ITALIC;
+        }
+
+        return result;
+    }
+
+    /**
+     * Decodes the specified string which described the Font. The string 
+     * should have the following format: fontname-style-pointsize. 
+     * The style can be PLAIN, BOLD, BOLDITALIC, or ITALIC.
+     * 
+     * @param str the string which describes the font.
+     * 
+     * @return the Font from the specified string.
+     */
+    public static Font decode(String str) {
+        // XXX: Documentation doesn't describe all cases, e.g. fonts face names
+        // with
+        // symbols that are suggested as delimiters in the documentation.
+        // In this decode implementation only ***-***-*** format is used with
+        // '-'
+        // as the delimiter to avoid unexpected parse results of font face names
+        // with spaces.
+
+        if (str == null) {
+            return DEFAULT_FONT;
+        }
+
+        StringTokenizer strTokens;
+        String delim = "-"; //$NON-NLS-1$
+        String substr;
+
+        int fontSize = DEFAULT_FONT.size;
+        int fontStyle = DEFAULT_FONT.style;
+        String fontName = DEFAULT_FONT.name;
+
+        strTokens = new StringTokenizer(str.trim(), delim);
+
+        // Font Name
+        if (strTokens.hasMoreTokens()) {
+            fontName = strTokens.nextToken(); // first token is the font name
+        }
+
+        // Font Style or Size (if the style is undefined)
+        if (strTokens.hasMoreTokens()) {
+            substr = strTokens.nextToken();
+
+            try {
+                // if second token is the font size
+                fontSize = Integer.parseInt(substr);
+            } catch (NumberFormatException e) {
+                // then second token is the font style
+                fontStyle = getFontStyle(substr);
+            }
+
+        }
+
+        // Font Size
+        if (strTokens.hasMoreTokens()) {
+            try {
+                fontSize = Integer.parseInt(strTokens.nextToken());
+            } catch (NumberFormatException e) {
+            }
+        }
+
+        return new Font(fontName, fontStyle, fontSize);
+    }
+
+    /**
+     * Perfoms the specified affine transform to the Font and returns 
+     * a new Font.
+     * 
+     * @param trans the AffineTransform.
+     * 
+     * @return the Font object.
+     * 
+     * @throws IllegalArgumentException if affine transform parameter
+     * is null.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(AffineTransform trans) {
+
+        if (trans == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        derivefRequestedAttributes.put(TextAttribute.TRANSFORM,
+                new TransformAttribute(trans));
+
+        return new Font(derivefRequestedAttributes);
+
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font 
+     * modified so that the size is the specified size.
+     * 
+     * @param size the size of font.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(float size) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font 
+     * modified so that the style is the specified style.
+     * 
+     * @param style the style of font.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        if ((style & Font.BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & Font.ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font
+     * modified to match the specified style and with the specified
+     * affine transform applied to its glyphs.
+     * 
+     * @param style the style of font.
+     * @param trans the AffineTransform.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style, AffineTransform trans) {
+
+        if (trans == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        if ((style & BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+        derivefRequestedAttributes.put(TextAttribute.TRANSFORM,
+                new TransformAttribute(trans));
+
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font 
+     * modified so that the size and style are the specified 
+     * size and style.
+     * 
+     * @param style the style of font.
+     * @param size the size of font.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style, float size) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        if ((style & BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+
+        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
+        return new Font(derivefRequestedAttributes);
+
+    }
+
+    /**
+     * Returns a new Font object with a new set of font attributes.
+     * 
+     * @param attributes the map of attributes.
+     * 
+     * @return the Font.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(Map<? extends Attribute, ?> attributes) {
+        Attribute[] avalAttributes = this.getAvailableAttributes();
+
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+        Object currAttribute;
+        for (Attribute element : avalAttributes) {
+            currAttribute = attributes.get(element);
+            if (currAttribute != null) {
+                derivefRequestedAttributes.put(element, currAttribute);
+            }
+        }
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Compares the specified Object with the current Font.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is an instance of Font
+     * with the same family, size, and style as this Font, false otherwise. 
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+            try {
+                Font font = (Font) obj;
+
+                return ((this.style == font.style) && (this.size == font.size)
+                        && this.name.equals(font.name)
+                        && (this.pointSize == font.pointSize) && (this
+                        .getTransform()).equals(font.getTransform()));
+            } catch (ClassCastException e) {
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Gets the map of font's attributes.
+     * 
+     * @return the map of font's attributes.
+     */
+    @SuppressWarnings("unchecked")
+    public Map<TextAttribute, ?> getAttributes() {
+        return (Map<TextAttribute, ?>) fRequestedAttributes.clone();
+    }
+
+    /**
+     * Gets the keys of all available attributes.
+     * 
+     * @return the keys array of all available attributes.
+     */
+    public Attribute[] getAvailableAttributes() {
+        Attribute[] attrs = { TextAttribute.FAMILY, TextAttribute.POSTURE,
+                TextAttribute.SIZE, TextAttribute.TRANSFORM,
+                TextAttribute.WEIGHT, TextAttribute.SUPERSCRIPT,
+                TextAttribute.WIDTH };
+        return attrs;
+    }
+
+    /**
+     * Gets the baseline for this character.
+     * 
+     * @param c the character.
+     * 
+     * @return the baseline for this character.
+     */
+    public byte getBaselineFor(char c) {
+        // TODO: implement using TT BASE table data
+        return 0;
+    }
+
+    /**
+     * Gets the family name of the Font.
+     * 
+     * @return the family name of the Font.
+     */
+    public String getFamily() {
+        if (fRequestedAttributes != null) {
+            fRequestedAttributes.get(TextAttribute.FAMILY);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the family name of this Font associated with 
+     * the specified locale.
+     * 
+     * @param l the locale.
+     * 
+     * @return the family name of this Font associated with 
+     * the specified locale.
+     */
+    public String getFamily(Locale l) {
+        if (l == null) {
+            // awt.01='{0}' parameter is null
+            throw new NullPointerException(Messages.getString(
+                    "awt.01", "Locale")); //$NON-NLS-1$ //$NON-NLS-2$ 
+        }
+        return getFamily();
+    }
+
+    /**
+     * Gets a Font with the specified attribute set.
+     * 
+     * @param attributes the attributes to be assigned to the new Font.
+     * 
+     * @return the Font.
+     */
+    public static Font getFont(Map<? extends Attribute, ?> attributes) {
+        Font fnt = (Font) attributes.get(TextAttribute.FONT);
+        if (fnt != null) {
+            return fnt;
+        }
+        return new Font(attributes);
+    }
+
+    /**
+     * Gets a Font object from the system properties list with the specified name
+     * or returns the specified Font if there is no such property.
+     * 
+     * @param sp the specified property name.
+     * @param f the Font.
+     * 
+     * @return the Font object from the system properties list  with the specified name
+     * or the specified Font if there is no such property.
+     */
+    public static Font getFont(String sp, Font f) {
+        String pr = System.getProperty(sp);
+        if (pr == null) {
+            return f;
+        }
+        return decode(pr);
+    }
+
+    /**
+     * Gets a Font object from the system properties list with the specified name.
+     * 
+     * @param sp the system property name.
+     * 
+     * @return the Font, or null if there is no shuch property
+     * with the specified name. 
+     */
+    public static Font getFont(String sp) {
+        return getFont(sp, null);
+    }
+
+    /**
+     * Gets the font name.
+     * 
+     * @return the font name.
+     */
+    public String getFontName() {
+        if (fRequestedAttributes != null) {
+            fRequestedAttributes.get(TextAttribute.FAMILY);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the font name associated with the specified locale.
+     * 
+     * @param l the locale.
+     * 
+     * @return the font name associated with the specified locale.
+     */
+    public String getFontName(Locale l) {
+        return getFamily();
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param chars the chars array.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(char[] chars, int start, int end,
+            FontRenderContext frc) {
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        //FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
+        FontMetrics fm = new FontMetricsImpl(this);
+        float[] fmet = {fm.getAscent(), fm.getDescent(), fm.getLeading()}; 
+        return new LineMetricsImpl(chars.length, fmet, null);
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param iter the CharacterIterator.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(CharacterIterator iter, int start,
+            int end, FontRenderContext frc) {
+
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        String resultString;
+        int iterCount;
+
+        iterCount = end - start;
+        if (iterCount < 0) {
+            resultString = ""; //$NON-NLS-1$
+        } else {
+            char[] chars = new char[iterCount];
+            int i = 0;
+            for (char c = iter.setIndex(start); c != CharacterIterator.DONE
+                    && (i < iterCount); c = iter.next()) {
+                chars[i] = c;
+                i++;
+            }
+            resultString = new String(chars);
+        }
+        return this.getLineMetrics(resultString, frc);
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param str the String.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(String str, FontRenderContext frc) {
+        //FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
+        FontMetrics fm = new FontMetricsImpl(this);
+        float[] fmet = {fm.getAscent(), fm.getDescent(), fm.getLeading()};
+        //Log.i("FONT FMET", fmet.toString());
+        return new LineMetricsImpl(str.length(), fmet, null);
+
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param str the String.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(String str, int start, int end,
+            FontRenderContext frc) {
+        return this.getLineMetrics(str.substring(start, end), frc);
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param ci the specified CharacterIterator.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(CharacterIterator ci, int start,
+            int end, FontRenderContext frc) {
+        int first = ci.getBeginIndex();
+        int finish = ci.getEndIndex();
+        char[] chars;
+
+        if (start < first) {
+            // awt.95=Wrong start index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.95", start)); //$NON-NLS-1$
+        }
+        if (end > finish) {
+            // awt.96=Wrong finish index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.96", end)); //$NON-NLS-1$
+        }
+        if (start > end) {
+            // awt.97=Wrong range length: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
+                    (end - start)));
+        }
+
+        if (frc == null) {
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        chars = new char[end - start];
+
+        ci.setIndex(start);
+        for (int i = 0; i < chars.length; i++) {
+            chars[i] = ci.current();
+            ci.next();
+        }
+
+        return this.getStringBounds(chars, 0, chars.length, frc);
+
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param str the specified String.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(String str, FontRenderContext frc) {
+        char[] chars = str.toCharArray();
+        return this.getStringBounds(chars, 0, chars.length, frc);
+
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param str the specified String.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(String str, int start, int end,
+            FontRenderContext frc) {
+
+        return this.getStringBounds((str.substring(start, end)), frc);
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param chars the specified character array.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(char[] chars, int start, int end,
+            FontRenderContext frc) {
+        if (start < 0) {
+            // awt.95=Wrong start index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.95", start)); //$NON-NLS-1$
+        }
+        if (end > chars.length) {
+            // awt.96=Wrong finish index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.96", end)); //$NON-NLS-1$
+        }
+        if (start > end) {
+            // awt.97=Wrong range length: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
+                    (end - start)));
+        }
+
+        if (frc == null) {
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+
+        final int TRANSFORM_MASK = AffineTransform.TYPE_GENERAL_ROTATION
+                | AffineTransform.TYPE_GENERAL_TRANSFORM;
+        Rectangle2D bounds;
+
+        AffineTransform transform = getTransform();
+
+        // XXX: for transforms where an angle between basis vectors is not 90
+        // degrees Rectanlge2D class doesn't fit as Logical bounds.
+        if ((transform.getType() & TRANSFORM_MASK) == 0) {
+            int width = 0;
+            for (int i = start; i < end; i++) {
+                width += peer.charWidth(chars[i]);
+            }
+            //LineMetrics nlm = peer.getLineMetrics();
+            
+            LineMetrics nlm = getLineMetrics(chars, start, end, frc);
+            
+            bounds = transform.createTransformedShape(
+                    new Rectangle2D.Float(0, -nlm.getAscent(), width, nlm
+                            .getHeight())).getBounds2D();
+        } else {
+            int len = end - start;
+            char[] subChars = new char[len];
+            System.arraycopy(chars, start, subChars, 0, len);
+            bounds = createGlyphVector(frc, subChars).getLogicalBounds();
+        }
+        return bounds;
+    }
+
+    /**
+     * Gets the character's maximum bounds as defined in 
+     * the specified FontRenderContext.
+     * 
+     * @param frc the FontRenderContext.
+     * 
+     * @return the character's maximum bounds.
+     */
+    public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$ 
+        }
+
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+
+        Rectangle2D bounds = peer.getMaxCharBounds(frc);
+        AffineTransform transform = getTransform();
+        // !! Documentation doesn't describe meaning of max char bounds
+        // for the fonts that have rotate transforms. For all transforms
+        // returned bounds are the bounds of transformed maxCharBounds
+        // Rectangle2D that corresponds to the font with identity transform.
+        // TODO: resolve this issue to return correct bounds
+        bounds = transform.createTransformedShape(bounds).getBounds2D();
+
+        return bounds;
+    }
+
+    /**
+     * Returns a new GlyphVector object performing full layout of
+     * the text.
+     * 
+     * @param frc the FontRenderContext.
+     * @param chars the character array to be layout.
+     * @param start the start offset of the text to use for 
+     * the GlyphVector.
+     * @param count the count of characters to use for 
+     * the GlyphVector.
+     * @param flags the flag indicating text direction: 
+     * LAYOUT_RIGHT_TO_LEFT, LAYOUT_LEFT_TO_RIGHT.
+     * 
+     * @return the GlyphVector.
+     */
+    public GlyphVector layoutGlyphVector(FontRenderContext frc, char[] chars,
+            int start, int count, int flags) {
+        // TODO: implement method for bidirectional text.
+        // At the moment only LTR and RTL texts supported.
+        if (start < 0) {
+            // awt.95=Wrong start index: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString(
+                    "awt.95", //$NON-NLS-1$
+                    start));
+        }
+
+        if (count < 0) {
+            // awt.98=Wrong count value, can not be negative: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString(
+                    "awt.98", //$NON-NLS-1$
+                    count));
+        }
+
+        if (start + count > chars.length) {
+            // awt.99=Wrong [start + count] is out of range: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString(
+                    "awt.99", //$NON-NLS-1$
+                    (start + count)));
+        }
+
+        char[] out = new char[count];
+        System.arraycopy(chars, start, out, 0, count);
+
+        return new CommonGlyphVector(out, frc, this, flags);
+    }
+
+    /**
+     * Returns the String representation of this Font.
+     * 
+     * @return the String representation of this Font.
+     */
+    @Override
+    public String toString() {
+        String stl = "plain"; //$NON-NLS-1$
+        String result;
+
+        if (this.isBold() && this.isItalic()) {
+            stl = "bolditalic"; //$NON-NLS-1$
+        }
+        if (this.isBold() && !this.isItalic()) {
+            stl = "bold"; //$NON-NLS-1$
+        }
+
+        if (!this.isBold() && this.isItalic()) {
+            stl = "italic"; //$NON-NLS-1$
+        }
+
+        result = this.getClass().getName() + "[family=" + this.getFamily() + //$NON-NLS-1$
+                ",name=" + this.name + //$NON-NLS-1$
+                ",style=" + stl + //$NON-NLS-1$
+                ",size=" + this.size + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        return result;
+    }
+
+    /**
+     * Gets the postscript name of this Font.
+     * 
+     * @return the postscript name of this Font.
+     */
+    public String getPSName() {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.getPSName();
+    }
+
+    /**
+     * Gets the logical name of this Font.
+     * 
+     * @return the logical name of this Font.
+     */
+    public String getName() {
+        return (this.name);
+    }
+
+    /**
+     * Gets the peer of this Font.
+     * 
+     * @return the peer of this Font.
+     * 
+     * @deprecated Font rendering is platform independent now.
+     */
+    @Deprecated
+    public java.awt.peer.FontPeer getPeer() {
+        if (fontPeer == null) {
+            fontPeer = (FontPeerImpl) Toolkit.getDefaultToolkit()
+                    .getGraphicsFactory().getFontPeer(this);
+        }
+        return fontPeer;
+
+    }
+
+    /**
+     * Gets the transform acting on this Font (from the Font's 
+     * attributes).
+     * 
+     * @return the transformation of this Font. 
+     */
+    public AffineTransform getTransform() {
+        Object transform = fRequestedAttributes.get(TextAttribute.TRANSFORM);
+
+        if (transform != null) {
+            if (transform instanceof TransformAttribute) {
+                return ((TransformAttribute) transform).getTransform();
+            }
+            if (transform instanceof AffineTransform) {
+                return new AffineTransform((AffineTransform) transform);
+            }
+        } else {
+            transform = new AffineTransform();
+        }
+        return (AffineTransform) transform;
+
+    }
+
+    /**
+     * Checks if this font is transformed or not.
+     * 
+     * @return true, if this font is transformed, false otherwise.
+     */
+    public boolean isTransformed() {
+        return this.transformed;
+    }
+
+    /**
+     * Checks if this font has plain style or not.
+     * 
+     * @return true, if this font has plain style, false otherwise.
+     */
+    public boolean isPlain() {
+        return (this.style == PLAIN);
+    }
+
+    /**
+     * Checks if this font has italic style or not.
+     * 
+     * @return true, if this font has italic style, false otherwise.
+     */
+    public boolean isItalic() {
+        return (this.style & ITALIC) != 0;
+    }
+
+    /**
+     * Checks if this font has bold style or not.
+     * 
+     * @return true, if this font has bold style, false otherwise.
+     */
+    public boolean isBold() {
+        return (this.style & BOLD) != 0;
+    }
+
+    /**
+     * Returns true if this Font has uniform line metrics. 
+     * 
+     * @return true if this Font has uniform line metrics, 
+     * false otherwise.
+     */
+    public boolean hasUniformLineMetrics() {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.hasUniformLineMetrics();
+    }
+
+    /**
+     * Returns hash code of this Font object.
+     * 
+     * @return the hash code of this Font object.
+
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(this.name);
+        hash.append(this.style);
+        hash.append(this.size);
+
+        return hash.hashCode();
+    }
+
+    /**
+     * Gets the style of this Font.
+     * 
+     * @return the style of this Font.
+     */
+    public int getStyle() {
+        return this.style;
+    }
+
+    /**
+     * Gets the size of this Font.
+     * 
+     * @return the size of this Font.
+     */
+    public int getSize() {
+        return this.size;
+    }
+
+    /**
+     * Gets the number of glyphs for this Font.
+     * 
+     * @return the number of glyphs for this Font.
+     */
+    public int getNumGlyphs() {
+        if (numGlyphs == -1) {
+            FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+            this.numGlyphs = peer.getNumGlyphs();
+        }
+        return this.numGlyphs;
+    }
+
+    /**
+     * Gets the glyphCode which is used as default glyph when this Font
+     * does not have a glyph for a specified unicode.
+     * 
+     * @return the missing glyph code.
+     */
+    public int getMissingGlyphCode() {
+        if (missingGlyphCode == -1) {
+            FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+            this.missingGlyphCode = peer.getMissingGlyphCode();
+        }
+        return this.missingGlyphCode;
+    }
+
+    /**
+     * Gets the float value of font's size.
+     * 
+     * @return the float value of font's size.
+     */
+    public float getSize2D() {
+        return this.pointSize;
+    }
+
+    /**
+     * Gets the italic angle of this Font.
+      * 
+     * @return the italic angle of this Font.
+     */
+    public float getItalicAngle() {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.getItalicAngle();
+    }
+
+    /**
+     * Creates the font with the specified font format and font file.
+     * 
+     * @param fontFormat the font format.
+     * @param fontFile the file object represented the input data 
+     * for the font.
+     * 
+     * @return the Font.
+     * 
+     * @throws FontFormatException is thrown if fontFile does not contain 
+     * the required font tables for the specified format.
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static Font createFont(int fontFormat, File fontFile)
+            throws FontFormatException, IOException {
+        // ???AWT not supported
+        InputStream is = new FileInputStream(fontFile);
+        try {
+            return createFont(fontFormat, is);
+        } finally {
+            is.close();
+        }
+    }
+
+    /**
+     * Creates the font with the specified font format and input stream.
+     * 
+     * @param fontFormat the font format.
+     * @param fontStream the input stream represented input data for 
+     * the font.
+     * 
+     * @return the Font.
+     * 
+     * @throws FontFormatException is thrown if fontFile does not contain 
+     * the required font tables for the specified format.
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static Font createFont(int fontFormat, InputStream fontStream)
+            throws FontFormatException, IOException {
+
+        // ???AWT not supported
+
+        BufferedInputStream buffStream;
+        int bRead = 0;
+        int size = 8192;
+        // memory page size, for the faster reading
+        byte buf[] = new byte[size];
+
+        if (fontFormat != TRUETYPE_FONT) { // awt.9A=Unsupported font format
+            throw new IllegalArgumentException(Messages.getString("awt.9A")); //$NON-NLS-1$ 
+        }
+        
+        /* Get font file in system-specific directory */
+
+        File fontFile = Toolkit.getDefaultToolkit().getGraphicsFactory()
+                .getFontManager().getTempFontFile();
+
+                // BEGIN android-modified
+        buffStream = new BufferedInputStream(fontStream, 8192);
+                // END android-modified
+        FileOutputStream fOutStream = new FileOutputStream(fontFile);
+
+        bRead = buffStream.read(buf, 0, size);
+
+        while (bRead != -1) {
+            fOutStream.write(buf, 0, bRead);
+            bRead = buffStream.read(buf, 0, size);
+        }
+
+        buffStream.close();
+        fOutStream.close();
+
+        Font font = null;
+
+        font = Toolkit.getDefaultToolkit().getGraphicsFactory().embedFont(
+                fontFile.getAbsolutePath());
+        if (font == null) { // awt.9B=Can't create font - bad font data
+            throw new FontFormatException(Messages.getString("awt.9B")); //$NON-NLS-1$
+        }
+        return font;
+    }
+
+}
diff --git a/awt/java/awt/FontFormatException.java b/awt/java/awt/FontFormatException.java
new file mode 100644
index 0000000..c017fd2
--- /dev/null
+++ b/awt/java/awt/FontFormatException.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The FontFormatException class is used to provide notification
+ * and information that font can't be created.
+ */
+public class FontFormatException extends Exception {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4481290147811361272L;
+
+    /**
+     * Instantiates a new font format exception with detailed message.
+     * 
+     * @param reason the detailed message.
+     */
+    public FontFormatException(String reason) {
+        super(reason);
+    }
+
+}
diff --git a/awt/java/awt/FontMetrics.java b/awt/java/awt/FontMetrics.java
new file mode 100644
index 0000000..3948d73
--- /dev/null
+++ b/awt/java/awt/FontMetrics.java
@@ -0,0 +1,456 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+import java.text.CharacterIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The FontMetrics class contains information about the rendering 
+ * of a particular font on a particular screen.
+ * <p>
+ * Each character in the Font has three values that help define where 
+ * to place it: an ascent, a descent, and an advance. The ascent is the 
+ * distance the character extends above the baseline. The descent is
+ * the distance the character extends below the baseline. 
+ * The advance width defines the position at which the next character
+ * should be placed.
+ * <p>
+ * An array of characters or a string has an ascent, a descent,
+ *  and an advance width too. The ascent or descent of the array 
+ *  is specified by the maximum ascent or descent of the characters 
+ *  in the array. The advance width is the sum of the advance widths 
+ *  of each of the characters in the character array.
+ */
+public abstract class FontMetrics implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 1681126225205050147L;
+
+    /** The font from which the FontMetrics is created. */
+    protected Font font;
+
+    /**
+     * Instantiates a new font metrics from the specified Font.
+     * 
+     * @param fnt the Font.
+     */
+    protected FontMetrics(Font fnt) {
+        this.font = fnt;
+    }
+
+    /**
+     * Returns the String representation of this FontMetrics.
+     * 
+     * @return the string
+     */
+    @Override
+    public String toString() {
+        return this.getClass().getName() +
+                "[font=" + this.getFont() + //$NON-NLS-1$
+                "ascent=" + this.getAscent() + //$NON-NLS-1$
+                ", descent=" + this.getDescent() + //$NON-NLS-1$
+                ", height=" + this.getHeight() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets the font associated with this FontMetrics.
+     * 
+     * @return the font associated with this FontMetrics.
+     */
+    public Font getFont() {
+        return font;
+    }
+
+    /**
+     * Gets the height of the text line in this Font.
+     * 
+     * @return the height of the text line in this Font.
+     */
+    public int getHeight() {
+        return this.getAscent() + this.getDescent() + this.getLeading();
+    }
+
+    /**
+     * Gets the font ascent of the Font associated with this FontMetrics.
+     * The font ascent is the distance from the font's baseline to 
+     * the top of most alphanumeric characters.
+     * 
+     * @return the ascent of the Font associated with this FontMetrics.
+     */
+    public int getAscent() {
+        return 0;
+    }
+
+    /**
+     * Gets the font descent of the Font associated with this FontMetrics.
+     * The font descent is the distance from the font's baseline to 
+     * the bottom of most alphanumeric characters with descenders.
+     * 
+     * @return the descent of the Font associated with this FontMetrics.
+     */
+    public int getDescent() {
+        return 0;
+    }
+
+    /**
+     * Gets the leading of the Font associated with this FontMetrics.
+     * 
+     * @return the leading of the Font associated with this FontMetrics.
+     */
+    public int getLeading() {
+        return 0;
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified CharacterIterator
+     * in the specified Graphics.
+     * 
+     * @param ci the CharacterIterator.
+     * @param beginIndex the offset.
+     * @param limit the number of characters to be used.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified CharacterIterator
+     * in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(CharacterIterator ci, int beginIndex,
+                                        int limit, Graphics context) {
+        return font.getLineMetrics(ci, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified String
+     * in the specified Graphics.
+     * 
+     * @param str the String.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified String
+     * in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(String str, Graphics context) {
+        return font.getLineMetrics(str, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified character 
+     * array in the specified Graphics.
+     * 
+     * @param chars the character array.
+     * @param beginIndex the offset of array.
+     * @param limit the number of characters to be used.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified character 
+     * array in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(char[] chars, int beginIndex, int limit,
+                                        Graphics context) {
+        return font.getLineMetrics(chars, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified String
+     * in the specified Graphics.
+     * 
+     * @param str the String.
+     * @param beginIndex the offset.
+     * @param limit the number of characters to be used.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified String
+     * in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(String str, int beginIndex, int limit,
+                                        Graphics context) {
+        return font.getLineMetrics(str, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Returns the character's maximum bounds in the specified 
+     * Graphics context.
+     * 
+     * @param context the Graphics context.
+     * 
+     * @return the character's maximum bounds in the specified 
+     * Graphics context.
+     */
+    public Rectangle2D getMaxCharBounds(Graphics context) {
+        return this.font.getMaxCharBounds(this.getFRCFromGraphics(context));
+    }
+    
+    /**
+     * Gets the bounds of the specified CharacterIterator 
+     * in the specified Graphics context.
+     * 
+     * @param ci the CharacterIterator.
+     * @param beginIndex the begin offset of the array.
+     * @param limit the number of characters.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified CharacterIterator 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(CharacterIterator ci, int beginIndex,
+            int limit, Graphics context) {
+        return font.getStringBounds(ci, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified String 
+     * in the specified Graphics context.
+     * 
+     * @param str the String.
+     * @param beginIndex the begin offset of the array.
+     * @param limit the number of characters.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified String 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(String str, int beginIndex, int limit,
+            Graphics context) {
+        return font.getStringBounds(str, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+
+    /**
+     * Gets the bounds of the specified characters array 
+     * in the specified Graphics context.
+     * 
+     * @param chars the characters array.
+     * @param beginIndex the begin offset of the array.
+     * @param limit the number of characters.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified characters array 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(char[] chars, int beginIndex, int limit,
+            Graphics context) {
+        return font.getStringBounds(chars, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified String 
+     * in the specified Graphics context.
+     * 
+     * @param str the String.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified String 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(String str, Graphics context) {
+        return font.getStringBounds(str, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Checks if the Font has uniform line metrics or not. 
+     * The Font can contain characters of other fonts for 
+     * covering character set. In this case the Font isn't
+     * uniform. 
+     *  
+     * @return true, if the Font has uniform line metrics, 
+     * false otherwise.
+     */
+    public boolean hasUniformLineMetrics() {
+        return this.font.hasUniformLineMetrics();
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point on the string's baseline showing the specified array 
+     * of bytes in this Font.   
+     * 
+     * @param data the array of bytes to be measured.
+     * @param off the start offset.
+     * @param len the number of bytes to be measured.
+     * 
+     * @return the advance width of the array.
+     */
+    public int bytesWidth(byte[] data, int off, int len) {
+        int width = 0;
+        if ((off >= data.length) || (off < 0)){
+            // awt.13B=offset off is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
+        }
+
+        if ((off+len > data.length)){
+            // awt.13C=number of elemets len is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
+        }
+
+        for (int i = off; i < off+len; i++){
+            width += charWidth(data[i]);
+        }
+
+        return width;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point on the string's baseline showing the specified array 
+     * of characters in this Font.   
+     * 
+     * @param data the array of characters to be measured.
+     * @param off the start offset.
+     * @param len the number of bytes to be measured.
+     * 
+     * @return the advance width of the array.
+     */
+    public int charsWidth(char[] data, int off , int len){
+        int width = 0;
+        if ((off >= data.length) || (off < 0)){
+            // awt.13B=offset off is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
+        }
+
+        if ((off+len > data.length)){
+            // awt.13C=number of elemets len is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
+        }
+
+        for (int i = off; i < off+len; i++){
+            width += charWidth(data[i]);
+        }
+
+        return width;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point of the specified character in this Font.   
+     * 
+     * @param ch the specified unicode point code of 
+     * character to be measured.
+     * 
+     * @return the advance width of the character.
+     */
+    public int charWidth(int ch) {
+        return 0;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point of the specified character in this Font.   
+     * 
+     * @param ch the specified character to be measured.
+     * 
+     * @return the advance width of the character.
+     */
+    public int charWidth(char ch) {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum advance width of character in this Font.
+     * 
+     * @return the maximum advance width of character in this Font.
+     */
+    public int getMaxAdvance() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font ascent of the Font associated with 
+     * this FontMetrics.
+     * 
+     * @return the maximum font ascent of the Font associated with 
+     * this FontMetrics.
+     */
+    public int getMaxAscent() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font descent of character in this Font.
+     * 
+     * @return the maximum font descent of character in this Font.
+     * 
+     * @deprecated Replaced by getMaxDescent() method.
+     */
+    @Deprecated
+    public int getMaxDecent() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font descent of character in this Font.
+     * 
+     * @return the maximum font descent of character in this Font.
+     */
+    public int getMaxDescent() {
+        return 0;
+    }
+
+    /**
+     * Gets the advance widths of the characters in the Font.
+     * 
+     * @return the advance widths of the characters in the Font.
+     */
+    public int[] getWidths() {
+        return null;
+    }
+
+    /**
+     * Returns the advance width for the specified String in this Font.
+     * 
+     * @param str String to be measured. 
+     * 
+     * @return the the advance width for the specified String 
+     * in this Font.
+     */
+    public int stringWidth(String str) {
+        return 0;
+    }
+    
+    /**
+     * Returns FontRenderContext instanse of the Graphics context specified.
+     * 
+     * @param context the specified Graphics context
+     * 
+     * @return a FontRenderContext of the specified Graphics context.
+     */
+    private FontRenderContext getFRCFromGraphics(Graphics context){
+        FontRenderContext frc;
+        if (context instanceof Graphics2D) {
+            frc = ((Graphics2D)context).getFontRenderContext();
+        } else {
+            frc = new FontRenderContext(null, false, false);
+        }
+
+        return frc;
+    }
+}
+
diff --git a/awt/java/awt/GradientPaint.java b/awt/java/awt/GradientPaint.java
new file mode 100644
index 0000000..0e06528
--- /dev/null
+++ b/awt/java/awt/GradientPaint.java
@@ -0,0 +1,219 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GradientPaint class defines a way to fill a Shape with a linear color
+ * gradient pattern. 
+ * <p>
+ * The GradientPaint's fill pattern is determined by two points and two colors, 
+ * plus the cyclic mode option.
+ * Each of the two points is painted with its corresponding color, and on 
+ * the line segment connecting the two points, the color is proportionally
+ * changed between the two colors. For points on the same line which are not 
+ * between the two specified points (outside of the connecting segment) their
+ * color is determined by the cyclic mode option. If the mode is cyclic, then
+ * the rest of the line repeats the color pattern of the connecting segment, 
+ * cycling back and forth between the two colors. If not, the mode is acyclic 
+ * which means that all points 
+ * on the line outside the connecting line segment are given the same 
+ * color as the closest of the two specified points.
+ * <p>
+ * The color of points that are not on the line connecting the two 
+ * specified points are given by perpendicular projection: by taking 
+ * the set of lines perpendicular to the connecting line and for each 
+ * one, the whole line is colored with the same color.
+ */
+public class GradientPaint implements Paint {
+    
+    /** The start point color. */
+    Color color1;
+
+    /** The end color point. */
+    Color color2;
+
+    /** The location of the start point. */
+    Point2D point1;
+
+    /** The location of the end point. */
+    Point2D point2;
+
+    /** The indicator of cycle filling. If TRUE filling 
+     * repeated outside points stripe, if FALSE solid color filling outside. */
+    boolean cyclic;
+
+    /**
+     * Instantiates a new GradientPaint with cyclic or acyclic mode.
+     * 
+     * @param point1 the first specified point.
+     * @param color1 the Color of the first specified point. 
+     * @param point2 the second specified point.
+     * @param color2 the Color of the second specified point.
+     * @param cyclic the cyclic mode - true if the gradient pattern should cycle 
+     * repeatedly between the two colors; false otherwise.
+     */
+    public GradientPaint(Point2D point1, Color color1, Point2D point2,
+            Color color2, boolean cyclic) {
+        if (point1 == null || point2 == null) {
+            // awt.6D=Point is null
+            throw new NullPointerException(Messages.getString("awt.6D")); //$NON-NLS-1$
+        }
+        if (color1 == null || color2 == null) {
+            // awt.6E=Color is null
+            throw new NullPointerException(Messages.getString("awt.6E")); //$NON-NLS-1$
+        }
+
+        this.point1 = point1;
+        this.point2 = point2;
+        this.color1 = color1;
+        this.color2 = color2;
+        this.cyclic = cyclic;
+    }
+
+    /**
+     * Instantiates a new GradientPaint with cyclic or acyclic mode;
+     * points are specified by coordinates.
+     * 
+     * @param x1 the X coordinate of the first point.
+     * @param y1 the Y coordinate of the first point.
+     * @param color1 the color of the first point.
+     * @param x2 the X coordinate of the second point.
+     * @param y2 the Y coordinate of the second point.
+     * @param color2 the color of the second point.
+     * @param cyclic the cyclic mode - true if the gradient pattern should cycle 
+     * repeatedly between the two colors; false otherwise.
+     */
+    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2,
+            boolean cyclic) {
+        this(new Point2D.Float(x1, y1), color1, new Point2D.Float(x2, y2), color2, cyclic);
+    }
+
+    /**
+     * Instantiates a new acyclic GradientPaint;
+     * points are specified by coordinates.
+     * 
+     * @param x1 the X coordinate of the first point.
+     * @param y1 the Y coordinate of the first point.
+     * @param color1 the color of the first point.
+     * @param x2 the X coordinate of the second point.
+     * @param y2 the Y coordinate of the second point.
+     * @param color2 the color of the second point.
+     */
+    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2) {
+        this(x1, y1, color1, x2, y2, color2, false);
+    }
+
+    /**
+     * Instantiates a new acyclic GradientPaint.
+     * 
+     * @param point1 the first specified point.
+     * @param color1 the Color of the first specified point. 
+     * @param point2 the second specified point.
+     * @param color2 the Color of the second specified point.
+     */
+    public GradientPaint(Point2D point1, Color color1, Point2D point2, Color color2) {
+        this(point1, color1, point2, color2, false);
+    }
+
+    /**
+     * Creates PaintContext for a color pattern generating. 
+     * 
+     * @param cm the ColorModel of the Paint data.
+     * @param deviceBounds the bounding Rectangle of graphics primitives
+     * being rendered in the device space. 
+     * @param userBounds tthe bounding Rectangle of graphics primitives
+     * being rendered in the user space. 
+     * @param t the AffineTransform from user space into device space.
+     * @param hints the RrenderingHints object.
+     * 
+     * @return the PaintContext for color pattern generating.
+     * 
+     * @see java.awt.Paint#createContext(java.awt.image.ColorModel, java.awt.Rectangle, java.awt.geom.Rectangle2D, java.awt.geom.AffineTransform, java.awt.RenderingHints)
+     */
+    public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+            Rectangle2D userBounds, AffineTransform t, RenderingHints hints) {
+        return new GradientPaintContext(cm, t, point1, color1, point2, color2, cyclic);
+    }
+
+    /**
+     * Gets the color of the first point.
+     * 
+     * @return the color of the first point.
+     */
+    public Color getColor1() {
+        return color1;
+    }
+
+    /**
+     * Gets the color of the second point.
+     * 
+     * @return the color of the second point.
+     */
+    public Color getColor2() {
+        return color2;
+    }
+
+    /**
+     * Gets the first point.
+     * 
+     * @return the Point object - the first point. 
+     */
+    public Point2D getPoint1() {
+        return point1;
+    }
+
+    /**
+     * Gets the second point.
+     * 
+     * @return the Point object - the second point.
+     */
+    public Point2D getPoint2() {
+        return point2;
+    }
+
+    /**
+     * Gets the transparency mode for the GradientPaint.
+     * 
+     * @return the transparency mode for the GradientPaint.
+     * 
+     * @see java.awt.Transparency#getTransparency()
+     */
+    public int getTransparency() {
+        int a1 = color1.getAlpha();
+        int a2 = color2.getAlpha();
+        return (a1 == 0xFF && a2 == 0xFF) ? OPAQUE : TRANSLUCENT;
+    }
+
+    /**
+     * Returns the GradientPaint mode: true for cyclic mode, false for
+     * acyclic mode.
+     * 
+     * @return true if the gradient cycles repeatedly between the two colors; 
+     * false otherwise.
+     */
+    public boolean isCyclic() {
+        return cyclic;
+    }
+}
diff --git a/awt/java/awt/GradientPaintContext.java b/awt/java/awt/GradientPaintContext.java
new file mode 100644
index 0000000..74575f5
--- /dev/null
+++ b/awt/java/awt/GradientPaintContext.java
@@ -0,0 +1,204 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+class GradientPaintContext implements PaintContext {
+
+    /**
+     * The size of noncyclic part of color lookup table
+     */
+    static int LOOKUP_SIZE = 256;
+    
+    /**
+     * The index mask to lookup color in the table
+     */
+    static int LOOKUP_MASK = 0x1FF;
+    
+    /**
+     * The min value equivalent to zero. If absolute value less then ZERO it considered as zero.  
+     */
+    static double ZERO = 1E-10;
+
+    /**
+     * The ColorModel user defined for PaintContext
+     */
+    ColorModel cm;
+    
+    /**
+     * The indicator of cycle filling.
+     */
+    boolean cyclic;
+    
+    /**
+     * The integer color value of the start point
+     */
+    int c1;
+    
+    /**
+     * The integer color value of the end point
+     */
+    int c2;
+    
+    /**
+     * The lookup gradient color table 
+     */
+    int[] table;
+
+    /**
+     * The tempopary pre-calculated value to evalutae color index 
+     */
+    int dx;
+    
+    /**
+     * The tempopary pre-calculated value to evalutae color index 
+     */
+    int dy;
+    
+    /**
+     * The tempopary pre-calculated value to evalutae color index 
+     */
+    int delta;
+    
+    /**
+     * Constructs a new GradientPaintcontext
+     * @param cm - not used
+     * @param t - the fill transformation
+     * @param point1 - the start fill point
+     * @param color1 - color of the start point 
+     * @param point2 - the end fill point
+     * @param color2 - color of the end point
+     * @param cyclic - the indicator of cycle filling
+     */
+    GradientPaintContext(ColorModel cm, AffineTransform t, Point2D point1, Color color1, Point2D point2, Color color2, boolean cyclic) {
+        this.cyclic = cyclic;
+        this.cm = ColorModel.getRGBdefault();
+
+        c1 = color1.getRGB();
+        c2 = color2.getRGB();
+
+        double px = point2.getX() - point1.getX();
+        double py = point2.getY() - point1.getY();
+
+        Point2D p = t.transform(point1, null);
+        Point2D bx = new Point2D.Double(px, py);
+        Point2D by = new Point2D.Double(py, -px);
+
+        t.deltaTransform(bx, bx);
+        t.deltaTransform(by, by);
+
+        double vec = bx.getX() * by.getY() - bx.getY() * by.getX();
+
+        if (Math.abs(vec) < ZERO) {
+            dx = dy = delta = 0;
+            table = new int[1];
+            table[0] = c1;
+        } else {
+            double mult = LOOKUP_SIZE * 256 / vec;
+            dx = (int)(by.getX() * mult);
+            dy = (int)(by.getY() * mult);
+            delta = (int)((p.getX() * by.getY() - p.getY() * by.getX()) * mult);
+            createTable();
+        }
+    }
+
+    /**
+     * Create color index lookup table. Calculate 256 step trasformation from 
+     * the start point color to the end point color. Colors multiplied by 256 to do integer calculations. 
+     */
+    void createTable() {
+        double ca = (c1 >> 24) & 0xFF;
+        double cr = (c1 >> 16) & 0xFF;
+        double cg = (c1 >> 8) & 0xFF;
+        double cb = c1 & 0xFF;
+
+        double k = 1.0 / LOOKUP_SIZE;
+        double da = (((c2 >> 24) & 0xFF) - ca) * k;
+        double dr = (((c2 >> 16) & 0xFF) - cr) * k;
+        double dg = (((c2 >> 8) & 0xFF) - cg) * k;
+        double db = ((c2 & 0xFF) - cb) * k;
+
+        table = new int[cyclic ? LOOKUP_SIZE + LOOKUP_SIZE : LOOKUP_SIZE];
+        for(int i = 0; i < LOOKUP_SIZE; i++) {
+            table[i] =
+                (int)ca << 24 |
+                (int)cr << 16 |
+                (int)cg << 8 |
+                (int)cb;
+            ca += da;
+            cr += dr;
+            cg += dg;
+            cb += db;
+        }
+        if (cyclic) {
+            for(int i = 0; i < LOOKUP_SIZE; i++) {
+                table[LOOKUP_SIZE + LOOKUP_SIZE - 1 - i] = table[i];
+            }
+        }
+    }
+
+    public ColorModel getColorModel() {
+        return cm;
+    }
+
+    public void dispose() {
+    }
+
+    public Raster getRaster(int x, int y, int w, int h) {
+        WritableRaster rast = cm.createCompatibleWritableRaster(w, h);
+
+        int[] buf = ((DataBufferInt)rast.getDataBuffer()).getData();
+
+        int c = x * dy - y * dx - delta;
+        int cx = dy;
+        int cy = - w * dy - dx;
+        int k = 0;
+
+        if (cyclic) {
+            for(int j = 0; j < h; j++) {
+                for(int i = 0; i < w; i++) {
+                    buf[k++] = table[(c >> 8) & LOOKUP_MASK];
+                    c += cx;
+                }
+                c += cy;
+            }
+        } else {
+            for(int j = 0; j < h; j++) {
+                for(int i = 0; i < w; i++) {
+                    int index = c >> 8;
+                    buf[k++] = index < 0 ? c1 : index >= LOOKUP_SIZE ? c2 : table[index];
+                    c += cx;
+                }
+                c += cy;
+            }
+        }
+
+        return rast;
+    }
+
+}
+
diff --git a/awt/java/awt/Graphics.java b/awt/java/awt/Graphics.java
new file mode 100644
index 0000000..c20f6bc
--- /dev/null
+++ b/awt/java/awt/Graphics.java
@@ -0,0 +1,737 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.ImageObserver;
+import java.text.AttributedCharacterIterator;
+
+/**
+ * The abstract Graphics class allows applications to draw on a screen
+ * or other rendering target. There are several properties which 
+ * define rendering options: origin point, clipping area, color, font.
+ * <br><br>
+ * The origin point specifies the beggining of the clipping area coordinate 
+ * system. All coordinates used in rendering operations are computed with 
+ * respect to this point. The clipping area defines the boundaries where 
+ * rendering operations can be performed. Rendering operations can't modify 
+ * pixels outside of the clipping area.
+ * <br><br>
+ * The draw and fill methods allow applications to drawing shapes, text, 
+ * images with specified font and color options in the specified part 
+ * of the screen.
+ *    
+ */
+public abstract class Graphics {
+
+    // Constructors
+
+    /**
+     * Instantiates a new Graphics. This constructor is default for Graphics and
+     * can not be called directly. 
+     */
+    protected Graphics() {
+    }
+
+    // Public methods
+
+    /**
+     * Creates a copy of the Graphics object with a new origin and a new 
+     * specified clip area. The new clip area is the rectangle defined by 
+     * the origin point with coordinates X,Y and the given width and height. 
+     * The coordinates of all subsequent rendering operations will be computed
+     * with respect to the new origin and can be performed only within the 
+     * range of the clipping area dimentions. 
+     *  
+     * @param x the X coordinate of the original point
+     * @param y the Y coordinate of the original point
+     * @param width the width of clipping area
+     * @param height the height of clipping area
+     * 
+     * @return the Graphics object with new origin point and clipping area. 
+     */
+    public Graphics create(int x, int y, int width, int height) {
+        Graphics res = create();
+        res.translate(x, y);
+        res.clipRect(0, 0, width, height);
+        return res;
+    }
+
+    /**
+     * Draws the higlighted outline of a rectangle.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     */
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        // Note: lighter/darker colors should be used to draw 3d rect.
+        // The resulting rect is (width+1)x(height+1). Stroke and paint attributes of
+        // the Graphics2D should be reset to the default values.
+        // fillRect is used instead of drawLine to bypass stroke
+        // reset/set and rasterization.
+
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+        }
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+
+    /**
+     * Draws the text represented by byte array. This method uses the current 
+     * font and color for rendering.
+     * 
+     * @param bytes the byte array which contains the text to be drawn. 
+     * @param off the offset within the byte array of the text to be drawn.
+     * @param len the number of bytes of text to draw. 
+     * @param x the X coordinate where the text is to be drawn.
+     * @param y the Y coordinate where the text is to be drawn.
+     */
+    public void drawBytes(byte[] bytes, int off, int len, int x, int y) {
+        drawString(new String(bytes, off, len), x, y);
+    }
+
+    /**
+     * Draws the text represented by character array. This method uses the 
+     * current font and color for rendering.
+     * 
+     * @param chars the character array. 
+     * @param off the offset within the character array of the text to be drawn.
+     * @param len the number of characters which will be drawn. 
+     * @param x the X coordinate where the text is to be drawn.
+     * @param y the Y coordinate where the text is to be drawn.
+     */
+    public void drawChars(char[] chars, int off, int len, int x, int y) {
+        drawString(new String(chars, off, len), x, y);
+    }
+
+    /**
+     * Draws the outline of a polygon which is defined by Polygon object.
+     * 
+     * @param p the Polygon object.
+     */
+    public void drawPolygon(Polygon p) {
+        drawPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    /**
+     * Draws the rectangle with the specified width and length and top left 
+     * corner coordinates.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     */
+    public void drawRect(int x, int y, int width, int height) {
+        int []xpoints = {x, x, x+width, x+width};
+        int []ypoints = {y, y+height, y+height, y};
+
+        drawPolygon(xpoints, ypoints, 4);
+    }
+
+    /**
+     * Fills the higlighted outline of a rectangle.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     */
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        // Note: lighter/darker colors should be used to draw 3d rect.
+        // The resulting rect is (width)x(height), same as fillRect.
+        // Stroke and paint attributes of the Graphics2D should be reset
+        // to the default values. fillRect is used instead of drawLine to
+        // bypass stroke reset/set and line rasterization.
+        
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+            setColor(color);
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+            setColor(colorUp);
+        }
+
+        width--;
+        height--;
+        fillRect(x+1, y+1, width-1, height-1);
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+
+    /**
+     * Fills the polygon with the current color.
+     * 
+     * @param p the Polygon object.
+     */
+    public void fillPolygon(Polygon p) {
+        fillPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    /**
+     * Disposes of the Graphics.
+     */
+    @Override
+    public void finalize() {
+    }
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle 
+     * and copies it to an existing rectangle.
+     *  
+     * @param r a Rectangle object where the current clipping area 
+     * bounds are to be copied.
+     * 
+     * @return the bounds of the current clipping area.
+     */
+    public Rectangle getClipBounds(Rectangle r) {
+        Shape clip = getClip();
+
+        if (clip != null) {
+            // TODO: Can we get shape bounds without creating Rectangle object?
+            Rectangle b = clip.getBounds();
+            r.x = b.x;
+            r.y = b.y;
+            r.width = b.width;
+            r.height = b.height;
+        }
+
+        return r;
+    }
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle.
+     * 
+     * @return a Rectangle object 
+     * 
+     * @deprecated Use {@link #getClipBounds()}
+     */
+    @Deprecated
+    public Rectangle getClipRect() {
+        return getClipBounds();
+    }
+
+    /**
+     * Gets the font metrics of the current font. 
+     * The font metrics object contains information about the rendering 
+     * of a particular font.
+     * 
+     * @return the font metrics of current font.
+     */
+    public FontMetrics getFontMetrics() {
+        return getFontMetrics(getFont());
+    }
+
+    /**
+     * Determines whether or not the specified rectangle intersects the 
+     * current clipping area.
+     *  
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     * 
+     * @return true, if the specified rectangle intersects the current clipping area, 
+     * overwise false. 
+     */
+    public boolean hitClip(int x, int y, int width, int height) {
+        // TODO: Create package private method Rectangle.intersects(int, int, int, int);
+        return getClipBounds().intersects(new Rectangle(x, y, width, height));
+    }
+
+    /**
+     * Returns string which represents this Graphics object.
+     * 
+     * @return the string which represents this Graphics object.
+     */
+    @Override
+    public String toString() {
+        // TODO: Think about string representation of Graphics.
+        return "Graphics"; //$NON-NLS-1$
+    }
+
+    // Abstract methods
+
+    /**
+     * Clears the specified rectangle. This method fills specified rectangle 
+     * with background color.  
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     */
+    public abstract void clearRect(int x, int y, int width, int height);
+
+    /**
+     * Intersects the current clipping area with a new rectangle. 
+     * If the current clipping area is not defined, the rectangle 
+     * becomes a new clipping area. Rendering operations are only allowed 
+     * within the new the clipping area.    
+     *          
+     * @param x the X coordinate of the rectangle for intersection. 
+     * @param y the Y coordinate of the rectangle for intersection.
+     * @param width the width of the rectangle for intersection.
+     * @param height the height of the rectangle for intersection.
+     */
+    public abstract void clipRect(int x, int y, int width, int height);
+
+    /**
+     * Copies the rectangle area to another area specified by 
+     * a distance (dx, dy) from the original rectangle's location. 
+     * Positive dx and dy values give a new location defined by 
+     * translation to the right and down from the original location, 
+     * negative dx and dy values - to the left and up.
+     * <br><br>
+     * 
+     * @param sx the X coordinate of the rectangle which will be copied. 
+     * @param sy the Y coordinate of the rectangle which will be copied.
+     * @param width the width of the rectangle which will be copied.
+     * @param height the height of the rectangle which will be copied.
+     * @param dx the horizontal distance from the source rectangle's 
+     * location to the copy's location. 
+     * @param dy the vertical distance from the source rectangle's 
+     * location to the copy's location. 
+     */
+    public abstract void copyArea(int sx, int sy, int width, int height, int dx, int dy);
+
+    /**
+     * Creates a new copy of this Graphics.
+     * 
+     * @return a new Graphics context which is a copy of this Graphics.
+     */
+    public abstract Graphics create();
+
+    /**
+     * Disposes of the Graphics. This Graphics object can not be used after 
+     * calling this method.  
+     */
+    public abstract void dispose();
+
+    /**
+     * Draws the arc covering the specified rectangle and using the current color. 
+     * The rectangle is defined by the origin point (X, Y) and dimentions 
+     * (width and height). The arc center is the the center of specified rectangle. 
+     * The angle origin is 3 o'clock position, the positive angle is counted as a 
+     * counter-clockwise rotation, the negotive angle is counted as clockwise rotation.   
+     * 
+     * @param x the X origin coordinate of the rectangle which scales the arc. 
+     * @param y the Y origin coordinate of the rectangle which scales the arc.
+     * @param width the width of the rectangle which scales the arc.
+     * @param height the height of the rectangle which scales the arc.
+     * @param sa start angle - the origin angle of arc.
+     * @param ea arc angle - the angular arc value relative to the start angle. 
+     */
+    public abstract void drawArc(int x, int y, int width, int height, int sa, int ea);
+
+    /**
+     * Draws the specified image with the defined background color. 
+     * The top left corner of image will be drawn at point (x, y) 
+     * in current coordinate system. The image loading process notifies the
+     * specified Image Observer. This method returns true if the image
+     * has loaded, overwise it returns false.       
+     * 
+     * @param img the image which will be drawn. 
+     * @param x the X coordinate of the image top left corner. 
+     * @param y the Y coordinate of the image top left corner. 
+     * @param bgcolor the background color.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Draws the specified image. 
+     * The top left corner of image will be drawn at point (x, y) 
+     * in current coordinate system. The image loading process notifies the
+     * specified Image Observer. This method returns true if the image
+     * has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn. 
+     * @param x the X coordinate of the image top left corner. 
+     * @param y the Y coordinate of the image top left corner. 
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer);
+
+    /**
+     * Scales the specified image to fit in the specified rectangle and 
+     * draws it with the defined background color. The top left corner 
+     * of the image will be drawn at the point (x, y) in current coordinate 
+     * system. The non-opaque pixels will be drawn in the background color. 
+     * The image loading process notifies the specified Image Observer. 
+     * This method returns true if the image has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param x the X coordinate of the image's top left corner.
+     * @param y the Y coordinate of the image's top left corner. 
+     * @param width the width of rectangle which scales the image.
+     * @param height the height of rectangle which scales the image.
+     * @param bgcolor the background color.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Scales the specified image to fit in the specified rectangle and 
+     * draws it. The top left corner of the image will be drawn at the 
+     * point (x, y) in current coordinate system. The image loading process 
+     * notifies the specified Image Observer. 
+     * This method returns true if the image has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param x the X coordinate of the image top left corner.
+     * @param y the Y coordinate of the image top left corner. 
+     * @param width the width of rectangle which scales the image.
+     * @param height the height of rectangle which scales the image.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer);
+
+    /**
+     * Scales the specified area of the specified image to fit in the rectangle area 
+     * defined by its corners coordinates and draws the sub-image with the specified 
+     * background color. The sub-image to be drawn is defined by its top left 
+     * corner coordinates (sx1, sy1) and bottom right corner coordinates (sx2, sy2)
+     * computed with respect to the origin (top left corner) of the source image.
+     * The non opaque pixels will be drawn in the background color. The 
+     * image loading process notifies specified Image Observer. 
+     * This method returns true if the image
+     * has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param dx1 the X top left corner coordinate of the destination rectangle area. 
+     * @param dy1 the Y top left corner coordinate of the destination rectangle area.
+     * @param dx2 the X bottom right corner coordinate of the destination rectangle area.
+     * @param dy2 the Y bottom right corner coordinate of the destination rectangle area.
+     * @param sx1 the X top left corner coordinate of the area to be drawn within the source image.
+     * @param sy1 the Y top left corner coordinate of the area to be drawn within the source image.
+     * @param sx2 the X bottom right corner coordinate of the area to be drawn within the source image.
+     * @param sy2 the Y bottom right corner coordinate of the area to be drawn within the source image.
+     * @param bgcolor the background color.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Scales the specified area of the specified image to fit in the rectangle area 
+     * defined by its corners coordinates and draws the sub-image. The sub-image 
+     * to be drawn is defined by its top left 
+     * corner coordinates (sx1, sy1) and bottom right corner coordinates (sx2, sy2)
+     * computed with respect to the origin (top left corner) of the source image.
+     * The image loading process notifies specified Image Observer. 
+     * This method returns true if the image
+     * has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param dx1 the X top left corner coordinate of the destination rectangle area. 
+     * @param dy1 the Y top left corner coordinate of the destination rectangle area.
+     * @param dx2 the X bottom right corner coordinate of the destination rectangle area.
+     * @param dy2 the Y bottom right corner coordinate of the destination rectangle area.
+     * @param sx1 the X top left corner coordinate of the area to be drawn within the source image.
+     * @param sy1 the Y top left corner coordinate of the area to be drawn within the source image.
+     * @param sx2 the X bottom right corner coordinate of the area to be drawn within the source image.
+     * @param sy2 the Y bottom right corner coordinate of the area to be drawn within the source image.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer);
+    
+    /**
+     * Draws a line from the point (x1, y1) to the point (x2, y2). 
+     * This method draws the line with current color 
+     * which can be changed by setColor(Color c) method.
+     * 
+     * @param x1 the X coordinate of the first point.
+     * @param y1 the Y coordinate of the first point.
+     * @param x2 the X coordinate of the second point.
+     * @param y2 the Y coordinate of the second point.
+     */
+    public abstract void drawLine(int x1, int y1, int x2, int y2);
+
+    /**
+     * Draws the ouline of an oval to fit in the rectangle defined
+     * by the given width, height, and top left corner.
+     * 
+     * @param x the X top left corner oval coordinate
+     * @param y the Y top left corner oval coordinate
+     * @param width the oval width
+     * @param height the oval height
+     */
+    public abstract void drawOval(int x, int y, int width, int height);
+
+    /**
+     * Draws the outline of a polygon. The polygon vertices are defined by points 
+     * with xpoints[i], ypoints[i]  as coordinates. The polygon edges are the
+     * lines from the points with (xpoints[i-1], ypoints[i-1]) coordinates to   
+     * the points with (xpoints[i], ypoints[i]) coordinates, for 0 < i < npoints +1.
+     * 
+     * @param xpoints the array of X coordinates of the polygon vertices.
+     * @param ypoints the array of Y coordinates of the polygon vertices.
+     * @param npoints the number of polygon vertices/points.
+     */
+    public abstract void drawPolygon(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Draws a set of connected lines which are defined by the x and y coordinate arrays.  
+     * The polyline is closed if coordinates of the first point are the same as 
+     * coordinates of the last point.
+     * 
+     * @param xpoints the array of X point coordinates.
+     * @param ypoints the array of Y point coordinates.
+     * @param npoints the number of points.
+     */
+    public abstract void drawPolyline(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Draws the outline of a rectangle with round corners.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     * @param arcWidth the arc width for the corners.
+     * @param arcHeight the arc height for the corners.
+     */
+    public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
+
+    /**
+     * Draws a text defined by an iterator. The iterator should specify the font 
+     * for every character. 
+     *  
+     * @param iterator the iterator.
+     * @param x the X coordinate of the firt character.
+     * @param y the Y coordinate of the first character.
+     */
+    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
+
+    /**
+     * Draws a text defined by a string. This method draws the text with current
+     * font and color.
+     * 
+     * @param str the string. 
+     * @param x the X coordinate of the firt character.
+     * @param y the Y coordinate of the first character.
+     */
+    public abstract void drawString(String str, int x, int y);
+
+    /**
+     * Fills the arc covering the rectangle and using the current color. 
+     * The rectangle is defined by the origin point (X, Y) and dimentions (width and height). 
+     * The arc center is the the center of specified rectangle. 
+     * The angle origin is at the 3 o'clock position, and a positive angle gives  
+     * counter-clockwise rotation, a negative angle gives clockwise rotation.
+     *  
+     * @param x the X origin coordinate of the rectangle which scales the arc. 
+     * @param y the Y origin coordinate of the rectangle which scales the arc.
+     * @param width the width of the rectangle which scales the arc.
+     * @param height the height of the rectangle which scales the arc.
+     * @param sa start angle - the origin angle of arc.
+     * @param ea arc angle - the angular arc value relative to the start angle. 
+     */
+    public abstract void fillArc(int x, int y, int width, int height, int sa, int ea);
+
+    /**
+     * Fills an oval with the current color where the oval is defined by the 
+     * bounding rectangle with the given width, height, and top left corner.
+     * 
+     * @param x the X top left corner oval coordinate.
+     * @param y the Y top left corner oval coordinate.
+     * @param width the oval width.
+     * @param height the oval height.
+     */
+    public abstract void fillOval(int x, int y, int width, int height);
+
+    /**
+     * Fills a polygon with the current color. The polygon vertices are defined by the points 
+     * with xpoints[i], ypoints[i] as coordinates. The polygon edges are the
+     * lines from the points with (xpoints[i-1], ypoints[i-1]) coordinates to   
+     * the points with (xpoints[i], ypoints[i]) coordinates, for 0 < i < npoints +1.
+     * 
+     * @param xpoints the array of X coordinates of the polygon vertices.
+     * @param ypoints the array of Y coordinates of the polygon vertices.
+     * @param npoints the number of polygon vertices/points.
+     */
+    public abstract void fillPolygon(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Fills a rectangle with the current color. 
+     * The rectangle is defined by its width and length and top left corner coordinates.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     */
+    public abstract void fillRect(int x, int y, int width, int height);
+
+    /**
+     * Fills a round cornered rectangle with the current color.
+     * 
+     * @param x the X coordinate of the top left corner of the bounding rectangle.
+     * @param y the Y coordinate of the top left corner of the bounding rectangle.
+     * @param width the width of the bounding rectangle.
+     * @param height the height of the bounding rectangle.
+     * @param arcWidth the arc width at the corners.
+     * @param arcHeight the arc height at the corners.
+     */
+    public abstract void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
+
+    /**
+     * Gets the clipping area.
+     * <br> <br>
+     *  
+     * @return a Shape object of the clipping area or null if it is not set.
+     */
+    public abstract Shape getClip();
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle.
+     *  
+     * @return a Rectangle object which represents the bounds of the current clipping area. 
+     */
+    public abstract Rectangle getClipBounds();
+
+    /**
+     * Gets the current color of Graphics.
+     * 
+     * @return the current color.
+     */
+    public abstract Color getColor();
+
+    /**
+     * Gets the current font of Graphics.
+     * 
+     * @return the current font.
+     */
+    public abstract Font getFont();
+
+    /**
+     * Gets the font metrics of the specified font. 
+     * The font metrics object contains information about the rendering of a particular font.
+     * 
+     * @param font the specified font
+     * 
+     * @return the font metrics for the specified font.
+     */
+    public abstract FontMetrics getFontMetrics(Font font);
+
+    /**
+     * Sets the new clipping area specified by rectangle. The new clipping area 
+     * doesn't depend on the window's visibility. Rendering operations can't be performed 
+     * outside new clipping area.
+     * 
+     * @param x the X coordinate of the new clipping rectangle.
+     * @param y the Y coordinate of the new clipping rectangle.
+     * @param width the width of the new clipping rectangle.
+     * @param height the height of the new clipping rectangle.
+     */
+    public abstract void setClip(int x, int y, int width, int height);
+
+    /**
+     * Sets the new clipping area to be the area specified by Shape object. 
+     * The new clipping area doesn't depend on the window's visibility. 
+     * Rendering operations can't be performed outside new clipping area.
+     * 
+     * @param clip a Shape object which representes new clipping area.
+     */
+    public abstract void setClip(Shape clip);
+
+    /**
+     * Sets the current Graphics color. All rendering operations with this Graphics
+     * will use this color.
+     * 
+     * @param c the new color.
+     */
+    public abstract void setColor(Color c);
+
+    /**
+     * Sets the current Graphics font. All rendering operations with this Graphics
+     * will use this font.
+     * 
+     * @param font the new font.
+     */
+    public abstract void setFont(Font font);
+
+    /**
+     * Sets the paint mode for the Graphics which overwrites all rendering 
+     * operations with the current color.
+     *  
+     */
+    public abstract void setPaintMode();
+
+    /**
+     * Sets the XOR mode for the Graphics which changes a pixel from
+     * the current color to the specified XOR color.
+     * <br> <br>
+     * 
+     * @param color the new XOR mode
+     */
+    public abstract void setXORMode(Color color);
+
+    /**
+     * Translates the origin of Graphics current coordinate system 
+     * to the point with X, Y coordinates in the current coordinate system.
+     * All rendering operation in this Graphics will be related to the new origin.
+     * 
+     * @param x the X coordinate of the origin
+     * @param y the Y coordinate of the origin
+     */
+    public abstract void translate(int x, int y);
+}
diff --git a/awt/java/awt/Graphics2D.java b/awt/java/awt/Graphics2D.java
new file mode 100644
index 0000000..2ff5e0c
--- /dev/null
+++ b/awt/java/awt/Graphics2D.java
@@ -0,0 +1,456 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.font.GlyphVector;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+/**
+ * The Graphics2D class extends Graphics class and provides more capabilities
+ * for rendering text, images, shapes. This provides methods to peform 
+ * transformation of coordinate system, color management, and text layout. 
+ * The following attributes exist for rendering:
+ * <ul>
+ * <li>Color - current Graphics2D color;</li>
+ * <li>Font - current Graphics2D font;</li>
+ * <li>Stroke - pen with a width of 1 pixel;</li>  
+ * <li>Transform - current Graphics2D Transformation;</li>
+ * <li>Composite - alpha compositing rules for combining source and destination colors.</li>
+ * </ul> 
+ */
+public abstract class Graphics2D extends Graphics {
+    
+    /**
+     * Instantiates a new Graphics2D object. This constructor should never be
+     * called directly.
+     */
+    protected Graphics2D() {
+        super();
+    }
+
+    /**
+     * Adds preferences for the rendering algorithms. The preferences
+     * are arbitrary and specified by Map objects. All specified by Map object
+     * preferencies can be modified. 
+     * 
+     * @param hints the rendering hints.
+     */
+    public abstract void addRenderingHints(Map<?, ?> hints);
+
+    /**
+     * Intersects the current clipping area with the specified Shape 
+     * and the result becomes a new clipping area. 
+     * If current clipping area is not defined, the Shape 
+     * becomes the new clipping area. No rendering operations 
+     * are allowed outside the clipping area.  
+     * 
+     * @param s the specified Shape object which will be intersected 
+     * with current clipping area.
+     */
+    public abstract void clip(Shape s);
+
+    /**
+     * Draws the outline of the specified Shape.
+     * 
+     * @param s the Shape which ouline is drawn.
+     */
+    public abstract void draw(Shape s);
+
+    /**
+     * Draws the specified GlyphVector object's text at the point x, y. 
+     * 
+     * @param g the GlyphVector object to be drawn.
+     * @param x the X position where the GlyphVector's text should 
+     * be rendered.  
+     * @param y the Y position where the GlyphVector's text should 
+     * be rendered.
+     */
+    public abstract void drawGlyphVector(GlyphVector g, float x, float y);
+
+    /**
+     * Draws the BufferedImage -- modified according to the operation
+     * BufferedImageOp -- at the point x, y.
+     * 
+     * @param img the BufferedImage to be rendered.
+     * @param op the filter to be applied to the image before rendering. 
+     * @param x the X coordinate of the point where the image's upper left corner
+     * will be placed.
+     * @param y the Y coordinate of the point where the image's upper left corner
+     * will be placed.
+     */
+    public abstract void drawImage(BufferedImage img, BufferedImageOp op, int x, int y);
+
+    /**
+     * Draws BufferedImage transformed from image space into user space 
+     * according to the AffineTransform xform and notifies the ImageObserver.
+     *  
+     * @param img the BufferedImage to be rendered.
+     * @param xform the affine transformation from the image to the user space.
+     * @param obs the ImageObserver to be notified about the image conversion.
+     * 
+     * @return true, if the image is successfully loaded and rendered, 
+     * or it's null, otherwise false.
+     */
+    public abstract boolean drawImage(Image img, AffineTransform xform, ImageObserver obs);
+
+    /**
+     * Draws a RenderableImage which is transformed from image space into user 
+     * according to the AffineTransform xform.
+     *  
+     * @param img the RenderableImage to be rendered.
+     * @param xform the affine transformation from image to user space.
+     */
+    public abstract void drawRenderableImage(RenderableImage img, AffineTransform xform);
+
+    /**
+     * Draws a RenderedImage which is transformed from image space into user 
+     * according to the AffineTransform xform.
+     *  
+     * @param img the RenderedImage to be rendered.
+     * @param xform the affine transformation from image to user space.
+     */
+    public abstract void drawRenderedImage(RenderedImage img, AffineTransform xform);
+
+    /**
+     * Draws the string specified by the AttributedCharacterIterator. 
+     * The first character's position is specified by the X, Y parameters.   
+     * 
+     * @param iterator whose text is drawn.
+     * @param x the X position where the first character is drawn. 
+     * @param y the Y position where the first character is drawn.
+     */
+    public abstract void drawString(AttributedCharacterIterator iterator, float x, float y);
+
+    /**
+     * Draws the string specified by the AttributedCharacterIterator. 
+     * The first character's position is specified by the X, Y parameters.   
+     * 
+     * @param iterator whose text is drawn.
+     * @param x the X position where the first character is drawn. 
+     * @param y the Y position where the first character is drawn.
+     * 
+     * @see java.awt.Graphics#drawString(AttributedCharacterIterator, int, int)
+     */
+    @Override
+    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
+
+    /**
+     * Draws the String whose the first character position is specified 
+     * by the parameters X, Y.   
+     * 
+     * @param s the String to be drawn.
+     * @param x the X position of the first character. 
+     * @param y the Y position of the first character.
+     */
+    public abstract void drawString(String s, float x, float y);
+
+    /**
+     * Draws the String whose the first character coordinates are specified 
+     * by the parameters X, Y.   
+     * 
+     * @param str the String to be drawn.
+     * @param x the X coordinate of the first character. 
+     * @param y the Y coordinate of the first character.
+     * 
+     * @see java.awt.Graphics#drawString(String, int, int)
+     */
+    @Override
+    public abstract void drawString(String str, int x, int y);
+
+    /**
+     * Fills the interior of the specified Shape.
+     * 
+     * @param s the Shape to be filled.
+     */
+    public abstract void fill(Shape s);
+
+    /**
+     * Gets the background color.
+     * 
+     * @return the current background color.
+     */
+    public abstract Color getBackground();
+
+    /**
+     * Gets the current composite of the Graphics2D.
+     * 
+     * @return the current composite which specifies the compositing style.
+     */
+    public abstract Composite getComposite();
+
+    /**
+     * Gets the device configuration.
+     * 
+     * @return the device configuration
+     */
+    public abstract GraphicsConfiguration getDeviceConfiguration();
+
+    /**
+     * Gets the rendering context of the Font.
+     * 
+     * @return the FontRenderContext.
+     */
+    public abstract FontRenderContext getFontRenderContext();
+
+    /**
+     * Gets the current Paint of Graphics2D.
+     * 
+     * @return the current Paint of Graphics2D.
+     */
+    public abstract Paint getPaint();
+
+    /**
+     * Gets the value of single preference for specified key. 
+     * 
+     * @param key the specified key of the rendering hint.
+     * 
+     * @return the value of rendering hint for specified key.
+     */
+    public abstract Object getRenderingHint(RenderingHints.Key key);
+
+    /**
+     * Gets the set of the rendering preferences as a collection of 
+     * key/value pairs.
+     * 
+     * @return the RenderingHints which contains the rendering preferences.
+     */
+    public abstract RenderingHints getRenderingHints();
+
+    /**
+     * Gets current stroke of the Graphics2D.
+     * 
+     * @return current stroke of the Graphics2D.
+     */
+    public abstract Stroke getStroke();
+
+    /**
+     * Gets current affine transform of the Graphics2D.
+     * 
+     * @return current AffineTransform of the Graphics2D.
+     */
+    public abstract AffineTransform getTransform();
+
+    /**
+     * Determines wether or not the specified Shape intersects the specified 
+     * Rectangle. If the onStroke parameter is true, this method 
+     * checks whether or not the specified Shape outline intersects the specified 
+     * Rectangle, otherwise this method checks whether or not the specified 
+     * Shape's interior intersects the specified Rectangle.   
+     * 
+     * @param rect the specified Rectangle.
+     * @param s the Shape to check for intersection.
+     * @param onStroke the parameter determines whether or not this method checks
+     * for intersection of the Shape outline or of the Shape interior with 
+     * the Rectangle. 
+     * 
+     * @return true, if there is a hit, otherwise false.
+     */
+    public abstract boolean hit(Rectangle rect, Shape s, boolean onStroke);
+
+    /**
+     * Performs a rotation transform relative to current Graphics2D Transform.
+     * The coordinate system is rotated by the specified angle in radians relative to 
+     * current origin.
+     * 
+     * @param theta the angle of rotation in radians.
+     */
+    public abstract void rotate(double theta);
+
+    /**
+     * Performs a translated rotation transform relative to current Graphics2D 
+     * Transform. The coordinate system is rotated by the specified angle in radians 
+     * relative to current origin and then moved to point (x, y).
+     * 
+     * Is this right?
+     * 
+     * @param theta the angle of rotation in radians.
+     * @param x the X coordinate.
+     * @param y the Y coordinate. 
+     */
+    public abstract void rotate(double theta, double x, double y);
+
+    /**
+     * Performs a linear scale transform relative to current Graphics2D Transform.
+     * The coordinate system is rescaled vertically and horizontally 
+     * by the specified parameters.
+     * 
+     * @param sx the scaling factor by which the X coordinate is multiplied.   
+     * @param sy the scaling factor by which the Y coordinate is multiplied.   
+     */
+    public abstract void scale(double sx, double sy);
+
+    /**
+     * Sets a new background color for clearing rectangular areas. 
+     * The clearRect method uses the current background color. 
+     * 
+     * @param color the new background color.
+     */
+    public abstract void setBackground(Color color);
+
+    /**
+     * Sets the current composite for Graphics2D. 
+     * 
+     * @param comp the Composite object.
+     */
+    public abstract void setComposite(Composite comp);
+
+    /**
+     * Sets the paint for Graphics2D.
+     * 
+     * @param paint the Paint object.
+     */
+    public abstract void setPaint(Paint paint);
+
+    /**
+     * Sets a key-value pair in the current RenderingHints map.
+     * 
+     * @param key the key of the rendering hint to set.
+     * @param value the value to set for the rendering hint.
+     */
+    public abstract void setRenderingHint(RenderingHints.Key key, Object value);
+
+    /**
+     * Replaces the current rendering hints with the specified rendering preferences.
+     * 
+     * @param hints the new Map of rendering hints.
+     */
+    public abstract void setRenderingHints(Map<?, ?> hints);
+
+    /**
+     * Sets the stroke for the Graphics2D.
+     * 
+     * @param s the Stroke object.
+     */
+    public abstract void setStroke(Stroke s);
+
+    /**
+     * Overwrite the current Transform of the Graphics2D. The specified Transform 
+     * should be received from the getTransform() method and should be used 
+     * only for restoring the original Graphics2D transform after calling
+     * draw or fill methods. 
+     * 
+     * @param Tx the specified Transform.
+     */
+    public abstract void setTransform(AffineTransform Tx);
+
+    /**
+     * Performs a shear transform relative to current Graphics2D Transform.
+     * The coordinate system is shifted by the specified multipliers relative to 
+     * current position.
+     * 
+     * @param shx the multiplier by which the X coordinates shift position
+     * along X axis as a function of Y coordinates.   
+     * @param shy the multiplier by which the Y coordinates shift position
+     * along Y axis as a function of X coordinates.   
+     */
+    public abstract void shear(double shx, double shy);
+
+    /**
+     * Concatenates the AffineTransform object with current Transform 
+     * of this Graphics2D. The transforms are applied in reverse order
+     * with the last specified transform applied first and the next
+     * transformation applied to the result of previous transformation. 
+     * More precisely, if Cx is the current Graphics2D transform, the 
+     * transform method's result with Tx as the parameter
+     * is the transformation Rx, where Rx(p) = Cx(Tx(p)), for p - a point
+     * in current coordinate system. Rx becomes the current Transform   
+     * for this Graphics2D.
+     * 
+     * @param Tx the AffineTransform object to be concatenated with 
+     * current Transform.
+     */
+    public abstract void transform(AffineTransform Tx);
+
+    /**
+     * Performs a translate transform relative to current Graphics2D Transform.
+     * The coordinate system is moved by the specified distance relative 
+     * to current position.
+     * 
+     * @param tx the translation distance along the X axis.
+     * @param ty the translation distance along the Y axis.
+     */
+    public abstract void translate(double tx, double ty);
+
+    /**
+     * Moves the origin Graphics2D Transform to the point with x, y
+     * coordinates in current coordinate system. The new origin of coordinate 
+     * system is moved to the (x, y) point accordingly. All rendering and 
+     * transform operations are performed relative to this new origin.
+     * 
+     * @param x the X coordinate.
+     * @param y the Y coordinate. 
+     * 
+     * @see java.awt.Graphics#translate(int, int)
+     */
+    @Override
+    public abstract void translate(int x, int y);
+
+    /**
+     * Fills a 3D rectangle with the current color. 
+     * The rectangle is specified by its width, height, and top left corner 
+     * coordinates.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     * 
+     * @see java.awt.Graphics#fill3DRect(int, int, int, int, boolean)
+     */
+    @Override
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        // According to the spec, color should be used instead of paint,
+        // so Graphics.fill3DRect resets paint and
+        // it should be restored after the call
+        Paint savedPaint = getPaint();
+        super.fill3DRect(x, y, width, height, raised);
+        setPaint(savedPaint);
+    }
+
+    /**
+     * Draws the higlighted outline of a rectangle.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     *       
+     * @see java.awt.Graphics#draw3DRect(int, int, int, int, boolean)
+     */
+    @Override
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        // According to the spec, color should be used instead of paint,
+        // so Graphics.draw3DRect resets paint and
+        // it should be restored after the call
+        Paint savedPaint = getPaint();
+        super.draw3DRect(x, y, width, height, raised);
+        setPaint(savedPaint);
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/GraphicsConfiguration.java b/awt/java/awt/GraphicsConfiguration.java
new file mode 100644
index 0000000..8bec253
--- /dev/null
+++ b/awt/java/awt/GraphicsConfiguration.java
@@ -0,0 +1,217 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.VolatileImage;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicsConfiguration class contains the characteristics of graphics
+ * devices such as a printer or monitor, and represents device's capabilities
+ * and modes. Many GraphicsConfiguration objects can be associated with
+ * single graphics device.
+ */
+public abstract class GraphicsConfiguration {
+   
+   /**
+     * Constructor could not be used directly and should be obtained in 
+     * extended classes. 
+    */
+
+    protected GraphicsConfiguration() {
+    }
+
+
+   /**
+    * Creates BufferedImage image object with a data layout and color model 
+    * compatible with this GraphicsConfiguration with specified width 
+    * and height parameters.
+    * 
+    * @param width the width of BufferedImage.
+    * @param height the height of BufferedImage.
+    * 
+    * @return the BufferedImage object with specified width and height 
+    * parameters.
+    */
+    public abstract BufferedImage createCompatibleImage(int width, int height);
+
+    /**
+     * Creates a BufferedImage that has the specified width, height,
+     * transparency and has a data layout and color model compatible with this 
+     * GraphicsConfiguration. 
+     * 
+     * @param width the width of image.
+     * @param height the height  of image.
+     * @param transparency the transparency mode.
+     * 
+     * @return the BufferedImage object.
+     */
+    public abstract BufferedImage createCompatibleImage(int width, int height, int transparency);
+
+    /**
+     * Creates a VolatileImage that has the specified width and height 
+     * and has a data layout and color model compatible with this 
+     * GraphicsConfiguration. 
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * 
+     * @return the VolatileImage object.
+     */
+    public abstract VolatileImage createCompatibleVolatileImage(int width, int height);
+
+    /**
+     * Creates a VolatileImage that supports the specified width, height,
+     * transparency and has a data layout and color model compatible with this 
+     * GraphicsConfiguration. 
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * @param transparency the transparency mode.
+     * 
+     * @return the VolatileImage object.
+     */
+    public abstract VolatileImage createCompatibleVolatileImage(int width, int height, int transparency);
+
+    /**
+     * Gets the bounds of area covered by the GraphicsConfiguration in the
+     * device coordinates space.
+     * 
+     * @return the Rectangle of GraphicsConfiguration's bounds.
+     */
+    public abstract Rectangle getBounds();
+
+    /**
+     * Gets the ColorModel of the GraphicsConfiguration.
+     * 
+     * @return the ColorModel object of the GraphicsConfiguration.
+     */
+    public abstract ColorModel getColorModel();
+
+    /**
+     * Gets the ColorModel of the GraphicsConfiguration which 
+     * supports specified Transparency.
+     * 
+     * @param transparency the Transparency mode: OPAQUE, BITMASK, or
+     * TRANSLUCENT.
+     * 
+     * @return the ColorModel of the GraphicsConfiguration which 
+     * supports specified Transparency.
+     */
+    public abstract ColorModel getColorModel(int transparency);
+
+    /**
+     * Gets the default AffineTransform of the GraphicsConfiguration.
+     * This method translates user coordinates to device coordinates.
+     * 
+     * @return the default AffineTransform of the GraphicsConfiguration.
+     */
+    public abstract AffineTransform getDefaultTransform();
+
+    /**
+     * Gets the GraphicsDevice of the GraphicsConfiguration.
+     * 
+     * @return the GraphicsDevice of the GraphicsConfiguration.
+     */
+    public abstract GraphicsDevice getDevice();
+
+    /**
+     * Gets the normalizing AffineTransform of the GraphicsConfiguration.
+     * 
+     * @return the normalizing AffineTransform of the GraphicsConfiguration.
+     */
+    public abstract AffineTransform getNormalizingTransform();
+
+
+    /**
+     * Creates VolatileImage with specified width, height, ImageCapabilities;
+     * a data layout and color model compatible with this GraphicsConfiguration. 
+     *  
+     * @param width the width of image.
+     * @param height the height of image.
+     * @param caps the ImageCapabilities object.
+     * 
+     * @return the VolatileImage which data layout and color model compatible 
+     * with this GraphicsConfiguration. 
+     * 
+     * @throws AWTException if ImageCapabilities is not supported by the
+     * GraphicsConfiguration.
+     */
+    public VolatileImage createCompatibleVolatileImage(int width, int height,
+            ImageCapabilities caps) throws AWTException {
+        VolatileImage res = createCompatibleVolatileImage(width, height);
+        if (!res.getCapabilities().equals(caps)) {
+            // awt.14A=Can not create VolatileImage with specified capabilities
+            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
+        }
+        return res;
+    }
+
+    /**
+     * Creates a VolatileImage with specified width, height, transparency 
+     * and ImageCapabilities; a data layout and color model compatible with 
+     * this GraphicsConfiguration.
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * @param caps the ImageCapabilities object.
+     * @param transparency the Transparency mode: OPAQUE, BITMASK, or
+     * TRANSLUCENT.
+     * 
+     * @return the VolatileImage which data layout and color model compatible 
+     * with this GraphicsConfiguration. 
+     * 
+     * @throws AWTException if ImageCapabilities is not supported by the
+     * GraphicsConfiguration.
+     */
+    public VolatileImage createCompatibleVolatileImage(int width, int height,
+            ImageCapabilities caps, int transparency) throws AWTException {
+        VolatileImage res = createCompatibleVolatileImage(width, height, transparency);
+        if (!res.getCapabilities().equals(caps)) {
+            // awt.14A=Can not create VolatileImage with specified capabilities
+            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
+        }
+        return res;
+    }
+
+    /**
+     * Gets the buffering capabilities of the GraphicsConfiguration.
+     * 
+     * @return the BufferCapabilities object. 
+     */
+    public BufferCapabilities getBufferCapabilities() {
+        return new BufferCapabilities(new ImageCapabilities(false), new ImageCapabilities(false),
+                BufferCapabilities.FlipContents.UNDEFINED);
+    }
+
+    /**
+     * Gets the image capabilities of the GraphicsConfiguration.
+     * 
+     * @return the ImageCapabilities object.
+     */
+    public ImageCapabilities getImageCapabilities() {
+        return new ImageCapabilities(false);
+    }
+}
diff --git a/awt/java/awt/GraphicsDevice.java b/awt/java/awt/GraphicsDevice.java
new file mode 100644
index 0000000..8cf700a
--- /dev/null
+++ b/awt/java/awt/GraphicsDevice.java
@@ -0,0 +1,199 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicsDevice class describes the graphics devices (such as screens 
+ * or printers) which are available in a particular graphics environment. 
+ * Many GraphicsDevice instances can be associated with a single
+ * GraphicsEnvironment. Each GraphicsDevice has one or more GraphicsConfiguration
+ * objects which specify the different configurations and modes of GraphicsDevice.
+ */
+public abstract class GraphicsDevice {
+    
+    /** The display mode. */
+    private DisplayMode displayMode;
+
+    //???AWT
+//    private Window fullScreenWindow = null;
+
+   /** The Constant TYPE_IMAGE_BUFFER indicates a image buffer device. */
+
+    public static final int TYPE_IMAGE_BUFFER = 2;
+
+    /** The Constant TYPE_PRINTER indicates a printer device. */
+    public static final int TYPE_PRINTER = 1;
+
+    /** The Constant TYPE_RASTER_SCREEN indicates a raster screen device. */
+    public static final int TYPE_RASTER_SCREEN = 0;
+
+   /**
+    * Constructor is not to be used directly as this class is abstract. 
+    */
+    protected GraphicsDevice() {
+        displayMode = new DisplayMode(0, 0, DisplayMode.BIT_DEPTH_MULTI, DisplayMode.REFRESH_RATE_UNKNOWN);
+    }
+
+
+   /**
+    * Returns an array of GraphicsConfiguration objects associated
+    * with the GraphicsDevice.  
+    * 
+    * @return an array of GraphicsConfiguration objects associated
+    * with the GraphicsDevice.
+    */
+    public abstract GraphicsConfiguration[] getConfigurations();
+
+    /**
+     * Gets the default configuration for the GraphicsDevice.
+     * 
+     * @return the default GraphicsConfiguration object for the GraphicsDevice.
+     */
+    public abstract GraphicsConfiguration getDefaultConfiguration();
+
+    /**
+     * Gets the String identifier which associated with the GraphicsDevice in 
+     * the GraphicsEnvironment.
+     * 
+     * @return the String identifier of the GraphicsDevice in 
+     * the GraphicsEnvironment.
+     */
+    public abstract String getIDstring();
+
+    /**
+     * Gets the type of this GraphicsDevice: 
+     * TYPE_IMAGE_BUFFER, TYPE_PRINTER or TYPE_RASTER_SCREEN.
+     * 
+     * @return the type of this GraphicsDevice: TYPE_IMAGE_BUFFER, 
+     * TYPE_PRINTER or TYPE_RASTER_SCREEN.
+     */
+    public abstract int getType();
+
+
+
+   /**
+	* Returns the number of bytes available in accelerated 
+	* memory on this device. 
+    * 
+    * @return the number of bytes available accelerated memory.
+    */
+    public int getAvailableAcceleratedMemory() {
+        return 0;
+    }
+
+    /* ???AWT
+    public GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate gct) {
+        return gct.getBestConfiguration(getConfigurations());
+    }
+    */
+    
+    /**
+     * Gets the current display mode of the GraphicsDevice.
+     * 
+     * @return the current display mode of the GraphicsDevice.
+     */
+    public DisplayMode getDisplayMode() {
+        return displayMode;
+    }
+
+    /**
+     * Gets an array of display modes available in this GraphicsDevice.
+     * 
+     * @return an array of display modes available in this GraphicsDevice.
+     */
+    public DisplayMode[] getDisplayModes() {
+        DisplayMode []dms = {displayMode};
+        return  dms;
+    }
+
+    /* ???AWT
+    public Window getFullScreenWindow() {
+        return fullScreenWindow;
+    }
+    */
+    
+    /**
+     * Returns true if this GraphicsDevice supports low-level 
+     * display changes.
+     * 
+     * @return true, if this GraphicsDevice supports low-level 
+     * display changes; false otherwise.
+     */
+    public boolean isDisplayChangeSupported() {
+        return false;
+    }
+
+    /**
+     * Returns true if this GraphicsDevice supports full screen
+     * mode.
+     * 
+     * @return true, if this GraphicsDevice supports full screen
+     * mode; otherwise false.
+     */
+    public boolean isFullScreenSupported() {
+        return false;
+    }
+    //an array of display modes available in this GraphicsDevice.
+    
+    /**
+     * Sets the display mode of this GraphicsDevice.
+     * 
+     * @param dm the new display mode of this GraphicsDevice. 
+     */
+    public void setDisplayMode(DisplayMode dm) {
+        if (!isDisplayChangeSupported()) {
+            // awt.122=Does not support display mode changes
+            throw new UnsupportedOperationException(Messages.getString("awt.122")); //$NON-NLS-1$
+        }
+
+        DisplayMode []dms = getDisplayModes();
+        for (DisplayMode element : dms) {
+            if (element.equals(dm)) {
+                displayMode = dm;
+                return;
+            }
+        }
+        // awt.123=Unsupported display mode: {0}
+        throw new IllegalArgumentException(Messages.getString("awt.123", dm)); //$NON-NLS-1$
+    }
+
+    /* ???AWT
+    public void setFullScreenWindow(Window w) {
+        if (w == null) {
+            fullScreenWindow = null;
+            return;
+        }
+
+        fullScreenWindow = w;
+
+        if (isFullScreenSupported()) {
+            w.enableInputMethods(false);
+        } else {
+            w.setSize(displayMode.getWidth(), displayMode.getHeight());
+            w.setLocation(0, 0);
+        }
+        w.setVisible(true);
+        w.setAlwaysOnTop(true);
+    }
+    */
+}
diff --git a/awt/java/awt/GraphicsEnvironment.java b/awt/java/awt/GraphicsEnvironment.java
new file mode 100644
index 0000000..3b14f55
--- /dev/null
+++ b/awt/java/awt/GraphicsEnvironment.java
@@ -0,0 +1,209 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.image.BufferedImage;
+import java.util.Locale;
+
+import org.apache.harmony.awt.ContextStorage;
+import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
+
+/**
+ * The GraphicsEnvironment class defines a collection of GraphicsDevice 
+ * objects and Font objects which are available for Java application on
+ * current platform.
+ */
+public abstract class GraphicsEnvironment {
+    
+    /**
+     * Constructor could not be used directly and should be obtained in 
+     * extended classes. 
+     */
+    protected GraphicsEnvironment() {}
+
+    /**
+     * Gets the local GraphicsEnvironment.
+     * 
+     * @return the local GraphicsEnvironment.
+     */
+    public static GraphicsEnvironment getLocalGraphicsEnvironment() {
+        synchronized(ContextStorage.getContextLock()) {
+            if (ContextStorage.getGraphicsEnvironment() == null) {
+                if (isHeadless()) {                    
+                    ContextStorage.setGraphicsEnvironment(new HeadlessGraphicsEnvironment());                    
+                } else {
+                    CommonGraphics2DFactory g2df =
+                            (CommonGraphics2DFactory) Toolkit.getDefaultToolkit().getGraphicsFactory();
+                    
+                    ContextStorage.setGraphicsEnvironment( 
+                            g2df.createGraphicsEnvironment(ContextStorage.getWindowFactory())
+                    );
+                }
+            }
+
+            return ContextStorage.getGraphicsEnvironment();
+        }
+    }
+
+    /**
+     * Returns whether or not a display, keyboard, and mouse are supported 
+     * in this graphics environment.
+     * 
+     * @return true, if HeadlessException will be thrown from areas of 
+     * the graphics environment that are dependent on a display, keyboard, 
+     * or mouse; false otherwise.
+     */
+    public boolean isHeadlessInstance() {
+        return false;
+    }
+
+    /**
+     * Checks whether or not a display, keyboard, and mouse are supported 
+     * in this environment. 
+     * 
+     * @return true, if a HeadlessException is thrown from areas of 
+     * the Toolkit and GraphicsEnvironment that are dependent on 
+     * a display, keyboard, or mouse; false otherwise.
+     */
+    public static boolean isHeadless() {
+        return "true".equals(System.getProperty("java.awt.headless"));
+    }
+
+    /**
+     * Gets the maximum bounds of system centered windows.
+     * 
+     * @return the maximum bounds of system centered windows.
+     * 
+     * @throws HeadlessException if isHeadless() method returns true.
+     */
+    public Rectangle getMaximumWindowBounds() throws HeadlessException {
+        return getDefaultScreenDevice().getDefaultConfiguration().getBounds();
+    }
+
+    /**
+     * Gets the Point which should defines the center of system window.
+     * 
+     * @return the Point where the system window should be centered.
+     * 
+     * @throws HeadlessException if isHeadless() method returns true.
+     */
+    public Point getCenterPoint() throws HeadlessException {
+        Rectangle mwb = getMaximumWindowBounds();
+        return new Point(mwb.width >> 1, mwb.height >> 1);
+    }
+
+    /**
+     * Indicates that the primary font should be used. 
+     * Primary font is specified by initial system locale or default encoding).
+     * 
+     */
+    public void preferLocaleFonts() {
+        // Note: API specification says following:
+        // "The actual change in font rendering behavior resulting
+        // from a call to this method is implementation dependent;
+        // it may have no effect at all." So, doing nothing is an
+        // acceptable behavior for this method.
+
+        // For now FontManager uses 1.4 font.properties scheme for font mapping, so
+        // this method doesn't make any sense. The implementation of this method
+        // which will influence font mapping is postponed until
+        // 1.5 mapping scheme not implemented.
+
+        // todo - Implement non-default behavior with 1.5 font mapping scheme
+    }
+
+    /**
+     * Indicates that a proportional preference of the font should be used.
+     */
+    public void preferProportionalFonts() {
+        // Note: API specification says following:
+        // "The actual change in font rendering behavior resulting
+        // from a call to this method is implementation dependent;
+        // it may have no effect at all." So, doing nothing is an
+        // acceptable behavior for this method.
+
+        // For now FontManager uses 1.4 font.properties scheme for font mapping, so
+        // this method doesn't make any sense. The implementation of this method
+        // which will influence font mapping is postponed until
+        // 1.5 mapping scheme not implemented.
+
+        // todo - Implement non-default behavior with 1.5 font mapping scheme
+    }
+
+    /**
+     * Creates the Graphics2D object for rendering to the specified
+     * BufferedImage.
+     * 
+     * @param bufferedImage the BufferedImage object.
+     * 
+     * @return the Graphics2D object which allows to render to the specified 
+     * BufferedImage.
+     */
+    public abstract Graphics2D createGraphics(BufferedImage bufferedImage);
+
+    /**
+     * Gets the array of all available fonts instances in this 
+     * GraphicsEnviroments.
+     * 
+     * @return the array of all available fonts instances in this 
+     * GraphicsEnviroments.
+     */
+    public abstract Font[] getAllFonts();
+
+    /**
+     * Gets the array of all available font family names.
+     * 
+     * @return the array of all available font family names.
+     */
+    public abstract String[] getAvailableFontFamilyNames();
+
+    /**
+     * Gets the array of all available font family names for the specified
+     * locale.
+     * 
+     * @param locale the Locale object which represents geographical
+     * region. The default locale is used if locale is null.
+     * 
+     * @return the array of available font family names for the specified 
+     * locale.
+     */
+    public abstract String[] getAvailableFontFamilyNames(Locale locale);
+
+    /**
+     * Gets the default screen device as GraphicDevice object.
+     * 
+     * @return the GraphicDevice object which represents default screen device.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    public abstract GraphicsDevice getDefaultScreenDevice() throws HeadlessException;
+
+    /**
+     * Gets an array of all available screen devices.
+     * 
+     * @return the array of GraphicsDevice obgects which represents 
+     * all available screen devices.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    public abstract GraphicsDevice[] getScreenDevices() throws HeadlessException;
+}
diff --git a/awt/java/awt/HeadlessException.java b/awt/java/awt/HeadlessException.java
new file mode 100644
index 0000000..28e463b
--- /dev/null
+++ b/awt/java/awt/HeadlessException.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The HeadlessException class provides notifications and error messages 
+ * when code that is dependent on a keyboard, display, or mouse is called 
+ * in an environment that does not support a keyboard, display, or mouse.
+ */
+public class HeadlessException extends UnsupportedOperationException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 167183644944358563L;
+
+    /**
+     * Instantiates a new headless exception.
+     */
+    public HeadlessException() {
+        super();
+    }
+
+    /**
+     * Instantiates a new headless exception with the specified message.
+     * 
+     * @param msg the String which represents error message. 
+     */
+    public HeadlessException(String msg) {
+        super(msg);
+    }
+}
diff --git a/awt/java/awt/HeadlessGraphicsEnvironment.java b/awt/java/awt/HeadlessGraphicsEnvironment.java
new file mode 100644
index 0000000..97f88d1
--- /dev/null
+++ b/awt/java/awt/HeadlessGraphicsEnvironment.java
@@ -0,0 +1,69 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package java.awt;
+
+import java.awt.GraphicsDevice;
+import java.awt.HeadlessException;
+
+import org.apache.harmony.awt.gl.CommonGraphicsEnvironment;
+
+/**
+ * The HeadlessGraphicsEnvironment class is the CommonGraphicsEnvironment
+ * implementation to use in the case where the environment lacks display, 
+ * keyboard, and mouse support.
+ */
+public class HeadlessGraphicsEnvironment extends CommonGraphicsEnvironment {
+    
+    /**
+     * Returns whether or not a display, keyboard, and mouse are supported 
+     * in this graphics environment.
+     * 
+     * @return true, if HeadlessException will be thrown from areas of 
+     * the graphics environment that are dependent on a display, keyboard, 
+     * or mouse; false otherwise.
+     */
+    @Override
+    public boolean isHeadlessInstance() {
+        return true;
+    }
+    
+    /**
+     * Gets the default screen device as GraphicDevice object.
+     * 
+     * @return the GraphicDevice object which represents default screen device.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    @Override
+    public GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    /**
+     * Gets an array of all available screen devices.
+     * 
+     * @return the array of GraphicsDevice objects which represents 
+     * all available screen devices.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    @Override
+    public GraphicsDevice[] getScreenDevices() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+}
diff --git a/awt/java/awt/HeadlessToolkit.java b/awt/java/awt/HeadlessToolkit.java
new file mode 100644
index 0000000..a7dd557
--- /dev/null
+++ b/awt/java/awt/HeadlessToolkit.java
@@ -0,0 +1,301 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+//???AWT
+//import java.awt.datatransfer.Clipboard;
+//import java.awt.dnd.DragGestureEvent;
+//import java.awt.dnd.DragGestureListener;
+//import java.awt.dnd.DragGestureRecognizer;
+//import java.awt.dnd.DragSource;
+//import java.awt.dnd.InvalidDnDOperationException;
+//import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+//import java.awt.peer.*;
+//import java.beans.PropertyChangeSupport;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.harmony.awt.ComponentInternals;
+//import org.apache.harmony.awt.datatransfer.DTK;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.WindowFactory;
+
+/**
+ * The HeadlessToolkit class is a subclass of ToolkitImpl to 
+ * be used for graphical environments that lack keyboard and 
+ * mouse capabilities.
+ */
+public final class HeadlessToolkit extends ToolkitImpl {
+    
+    //???AWT
+    /*
+    @Override
+    protected ButtonPeer createButton(Button a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    protected CheckboxPeer createCheckbox(Checkbox a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    protected ChoicePeer createChoice(Choice a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    public Cursor createCustomCursor(Image img, Point hotSpot, String name)
+    throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected DialogPeer createDialog(Dialog a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
+            Class<T> recognizerAbstractClass, DragSource ds, Component c, int srcActions,
+            DragGestureListener dgl) {
+        return null;
+    }
+
+    @Override
+    public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge)
+    throws InvalidDnDOperationException {
+        throw new InvalidDnDOperationException();
+    }
+
+    @Override
+    protected FileDialogPeer createFileDialog(FileDialog a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected FramePeer createFrame(Frame a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected LabelPeer createLabel(Label a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected ListPeer createList(List a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected MenuPeer createMenu(Menu a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected MenuBarPeer createMenuBar(MenuBar a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected MenuItemPeer createMenuItem(MenuItem a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected PopupMenuPeer createPopupMenu(PopupMenu a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected ScrollbarPeer createScrollbar(Scrollbar a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected ScrollPanePeer createScrollPane(ScrollPane a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected TextAreaPeer createTextArea(TextArea a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected TextFieldPeer createTextField(TextField a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected WindowPeer createWindow(Window a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+    */
+
+    @Override
+    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public ColorModel getColorModel() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public GraphicsFactory getGraphicsFactory() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getMaximumCursorColors() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getMenuShortcutKeyMask() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    //???AWT
+    /*
+    @Override
+    NativeEventQueue getNativeEventQueue() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    public PrintJob getPrintJob(Frame frame, String jobtitle, JobAttributes jobAttributes, 
+            PageAttributes pageAttributes) throws IllegalArgumentException {
+        throw new IllegalArgumentException();        
+    }
+    
+    @Override
+    public PrintJob getPrintJob(Frame frame, String jobtitle, Properties props) throws NullPointerException  {
+        throw new NullPointerException();
+    }
+    */
+
+    @Override
+    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getScreenResolution() throws HeadlessException {
+        throw new HeadlessException();
+    }    
+
+    @Override
+    public Dimension getScreenSize() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    //???AWT
+    /*
+    @Override
+    public Clipboard getSystemClipboard() throws HeadlessException {
+        throw new HeadlessException();
+    }    
+    
+    @Override
+    public Clipboard getSystemSelection() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    WindowFactory getWindowFactory() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    */
+
+    @Override
+    protected void init() {
+        lockAWT();
+        try {
+            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
+            //???AWT: new EventQueue(this); // create the system EventQueue
+            //???AWT: dispatcher = new Dispatcher(this);
+            desktopProperties = new HashMap<String, Object>();
+            //???AWT: desktopPropsSupport = new PropertyChangeSupport(this);
+//          ???AWT: awtEventsManager = new AWTEventsManager();
+//          ???AWT: dispatchThread = new HeadlessEventDispatchThread(this, dispatcher);            
+//          ???AWT: dtk = DTK.getDTK();
+            dispatchThread.start();            
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public boolean isDynamicLayoutActive() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected boolean isDynamicLayoutSet() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public boolean isFrameStateSupported(int state) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected void loadSystemColors(int[] systemColors) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(
+            InputMethodHighlight highlight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public void setLockingKeyState(int keyCode, boolean on) throws UnsupportedOperationException {
+        throw new HeadlessException();
+    }
+}
diff --git a/awt/java/awt/IllegalComponentStateException.java b/awt/java/awt/IllegalComponentStateException.java
new file mode 100644
index 0000000..21dc35f
--- /dev/null
+++ b/awt/java/awt/IllegalComponentStateException.java
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The IllegalComponentStateException class is used to provide 
+ * notification that AWT component is not in an appropriate state 
+ * for the requested operation.
+ */
+public class IllegalComponentStateException extends IllegalStateException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1889339587208144238L;
+
+    /**
+     * Instantiates a new IllegalComponentStateException with
+     * the specified message.
+     * 
+     * @param s the String message which describes the exception.
+     */
+    public IllegalComponentStateException(String s) {
+        super(s);
+    }
+
+    /**
+     * Instantiates a new IllegalComponentStateException without
+     * detailed message.
+     */
+    public IllegalComponentStateException() {
+    }
+
+}
+
diff --git a/awt/java/awt/Image.java b/awt/java/awt/Image.java
new file mode 100644
index 0000000..c217e38
--- /dev/null
+++ b/awt/java/awt/Image.java
@@ -0,0 +1,203 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.AreaAveragingScaleFilter;
+import java.awt.image.FilteredImageSource;
+import java.awt.image.ImageFilter;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.ReplicateScaleFilter;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Image abstract class represents the graphic images. 
+ */
+public abstract class Image {
+
+    /** 
+     * The UndefinedProperty object should be returned if
+     * property is not defined for a particular image. 
+     */
+    public static final Object UndefinedProperty = new Object();  //$NON-LOCK-1$
+
+    /** 
+     * The Constant SCALE_DEFAULT indicates the default image
+     * scaling algorithm. 
+     */
+    public static final int SCALE_DEFAULT = 1;
+
+    /** 
+     * The Constant SCALE_FAST indicates an image scaling algorithm which 
+     * places a higher priority on scaling speed than on the image's smoothness. 
+     */
+    public static final int SCALE_FAST = 2;
+
+    /** 
+     * The Constant SCALE_SMOOTH indicates an image scaling algorithm which 
+     * places a higher priority on image smoothness than on scaling speed. 
+     */
+    public static final int SCALE_SMOOTH = 4;
+
+    /** 
+     * The Constant SCALE_REPLICATE indicates the image scaling 
+     * algorithm in the ReplicateScaleFilter class. 
+     */
+    public static final int SCALE_REPLICATE = 8;
+
+    /** 
+     * The Constant SCALE_AREA_AVERAGING indicates  
+     * the area averaging image scaling algorithm. 
+     */
+    public static final int SCALE_AREA_AVERAGING = 16;
+
+    /** 
+     * The acceleration priority indicates image acceleration.   
+     */
+    protected float accelerationPriority = 0.5f;
+
+    /** The Constant capabilities. */
+    private static final ImageCapabilities capabilities = new ImageCapabilities(false);
+
+    /**
+     * Gets the image property with the specified name.
+     * The UndefinedProperty object should be return if the property is 
+     * not specified for this image.  The return value should be null if the
+     * property is currently unknown yet and the specified ImageObserver is
+     * to be notified later. 
+     * 
+     * @param name the name of image's property.
+     * @param observer the ImageObserver.
+     * 
+     * @return the Object which represents value of the specified property.
+     */
+    public abstract Object getProperty(String name, ImageObserver observer);
+
+    /**
+     * Gets the ImageProducer object which represents data of this Image.
+     * 
+     * @return the ImageProducer object which represents data of this Image.
+     */
+    public abstract ImageProducer getSource();
+
+    /**
+     * Gets the width of this image. The specified ImageObserver object 
+     * is notified when the width of this image is available.
+     * 
+     * @param observer the ImageObserver object which is 
+     * is notified when the width of this image is available.
+     * 
+     * @return the width of image, or -1 if the width of this image 
+     * is not available.
+     */
+    public abstract int getWidth(ImageObserver observer);
+
+    /**
+     * Gets the height of this image. The specified ImageObserver object 
+     * is notified when the height of this image is available.
+     * 
+     * @param observer the ImageObserver object which is 
+     * is notified when the height of this image is available.
+     * 
+     * @return the height of image, or -1 if the height of this image 
+     * is not available.
+     */
+    public abstract int getHeight(ImageObserver observer);
+
+    /**
+     * Gets the scaled instance of this Image. This method returns 
+     * an Image object constructed from the source of this image 
+     * with the specified width, height, and applied scaling
+     * alghorithm.
+     * 
+     * @param width the width of scaled Image. 
+     * @param height the height of scaled Image.
+     * @param hints the constant which indicates scaling algorithm. 
+     * 
+     * @return the scaled Image.
+     */
+    public Image getScaledInstance(int width, int height, int hints) {
+        ImageFilter filter;
+        if ((hints & (SCALE_SMOOTH | SCALE_AREA_AVERAGING)) != 0) {
+            filter = new AreaAveragingScaleFilter(width, height);
+        } else {
+            filter = new ReplicateScaleFilter(width, height);
+        }
+        ImageProducer producer = new FilteredImageSource(getSource(), filter);
+        return Toolkit.getDefaultToolkit().createImage(producer);
+    }
+
+    /**
+     * Gets a Graphics object for rendering this image. 
+     * This method can be used for off-screen images.
+     * 
+     * @return a Graphics object for rendering to this image.
+     */
+    public abstract Graphics getGraphics();
+
+    /**
+     * Flushes resources which are used by this Image object. 
+     * This method resets the image to the reconstructered state
+     * from the image's source.
+     */
+    public abstract void flush();
+
+    /**
+     * Gets the acceleration priority of this image.
+     * 
+     * @return the acceleration priority of this image.
+     */
+    public float getAccelerationPriority() {
+        return accelerationPriority;
+    }
+
+    /**
+     * Sets the acceleration priority for this image.  
+     *  
+     * @param priority the new acceleration priority (value in the
+     * range 0-1).
+     */
+    public void setAccelerationPriority(float priority) {
+        if (priority < 0 || priority > 1) {
+            // awt.10A=Priority must be a value between 0 and 1, inclusive
+            throw new IllegalArgumentException(Messages.getString("awt.10A")); //$NON-NLS-1$
+        }
+        accelerationPriority = priority;
+    }
+
+    /**
+     * Gets an ImageCapabilities object of this Image object
+     * for the specified GraphicsConfiguration. 
+     * 
+     * @param gc the specified GraphicsConfiguration object 
+     * (null value means default GraphicsConfiguration).
+     * 
+     * @return an ImageCapabilities object of this Image object
+     * for the specified GraphicsConfiguration.
+     */
+    public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
+        // Note: common image is not accelerated.
+        return capabilities;
+    }
+}
+
+
diff --git a/awt/java/awt/ImageCapabilities.java b/awt/java/awt/ImageCapabilities.java
new file mode 100644
index 0000000..6e9ecfc
--- /dev/null
+++ b/awt/java/awt/ImageCapabilities.java
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The ImageCapabilities class gives information about an image's capabilities.
+ */
+public class ImageCapabilities implements Cloneable {
+    
+    /** The accelerated. */
+    private final boolean accelerated;
+
+    /**
+     * Instantiates a new ImageCapabilities with the specified
+     * acceleration flag which indicates whether acceleration
+     * is desired or not.
+     * 
+     * @param accelerated the accelerated flag.
+     */
+    public ImageCapabilities(boolean accelerated) {
+        this.accelerated = accelerated;
+    }
+
+    /**
+     * Returns a copy of this ImageCapabilities object.
+     * 
+     * @return the copy of this ImageCapabilities object.
+     */
+    @Override
+    public Object clone() {
+        return new ImageCapabilities(accelerated);
+    }
+
+    /**
+     * Returne true if the Image of this ImageCapabilities is or can be
+     * accelerated.
+     *  
+     * @return true, if the Image of this ImageCapabilities is or can be
+     * accelerated, false otherwise.
+     */
+    public boolean isAccelerated() {
+        return accelerated;
+    }
+
+    /**
+     * Returns true if this ImageCapabilities applies to
+     * the VolatileImage which can lose its surfaces.
+     * 
+     * @return true if this ImageCapabilities applies to
+     * the VolatileImage which can lose its surfaces, 
+     * false otherwise.
+     */
+    public boolean isTrueVolatile() {
+        return true;
+    }
+}
diff --git a/awt/java/awt/Insets.java b/awt/java/awt/Insets.java
new file mode 100644
index 0000000..61f3fd8
--- /dev/null
+++ b/awt/java/awt/Insets.java
@@ -0,0 +1,165 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.Serializable;
+
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The Insets class represents the borders of a container. 
+ * This class describes the space that a container should leave at each edge:
+ * the top, the bottom, the right side, and the left side. 
+ * The space can be filled with a border, a blank space, or a title.
+ */
+public class Insets implements Cloneable, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -2272572637695466749L;
+
+    /**
+     * The top inset indicates the size of the space added to the 
+     * top of the rectangle.
+     */
+    public int top;
+
+    /** 
+     * The left inset indicates the size of the space added to the 
+     * left side of the rectangle.
+     */
+    public int left;
+
+    /** 
+     * The bottom inset indicates the size of the space subtracted from 
+     * the bottom of the rectangle.
+     */
+    public int bottom;
+
+    /** The right inset indicates the size of the space subtracted from 
+     * the right side of the rectangle. 
+     */
+    public int right;
+
+    /**
+     * Instantiates a new Inset object with the specified top, left, bottom,
+     * right parameters.
+     * 
+     * @param top the top inset.
+     * @param left the left inset.
+     * @param bottom the bottom inset.
+     * @param right the right inset.
+     */
+    public Insets(int top, int left, int bottom, int right) {
+        setValues(top, left, bottom, right);
+    }
+
+    /**
+     * Returns a hash code of the Insets object.
+     * 
+     * @return a hash code of the Insets object.
+     */
+    @Override
+    public int hashCode() {
+        int hashCode = HashCode.EMPTY_HASH_CODE;
+        hashCode = HashCode.combine(hashCode, top);
+        hashCode = HashCode.combine(hashCode, left);
+        hashCode = HashCode.combine(hashCode, bottom);
+        hashCode = HashCode.combine(hashCode, right);
+        return hashCode;
+    }
+
+    /**
+     * Returns a copy of this Insets object.
+     * 
+     * @return a copy of this Insets object.
+     */
+    @Override
+    public Object clone() {
+        return new Insets(top, left, bottom, right);
+    }
+
+    /**
+     * Checks if this Insets object is equal to the specified object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if the object is an Insets object whose data values
+     * are equal to those of this object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof Insets) {
+            Insets i = (Insets) o;
+            return ((i.left == left) && (i.bottom == bottom) &&
+                    (i.right == right) && (i.top == top));
+        }
+        return false;
+    }
+
+    /**
+     * Returns a String representation of this Insets object.
+     * 
+     * @return a String representation of this Insets object.
+     */
+    @Override
+    public String toString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * System.out.println(new Insets(1, 2, 3, 4));
+         */
+
+        return (getClass().getName() +
+                "[left=" + left + ",top=" + top + //$NON-NLS-1$ //$NON-NLS-2$
+                ",right=" + right + ",bottom="  + bottom + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Sets top, left, bottom, and right insets to the specified values.
+     * 
+     * @param top the top inset.
+     * @param left the left inset.
+     * @param bottom the bottom inset.
+     * @param right the right inset.
+     */
+    public void set(int top, int left, int bottom, int right) {
+        setValues(top, left, bottom, right);
+    }
+
+    /**
+     * Sets the values.
+     * 
+     * @param top the top
+     * @param left the left
+     * @param bottom the bottom
+     * @param right the right
+     */
+    private void setValues(int top, int left, int bottom, int right) {
+        this.top = top;
+        this.left = left;
+        this.bottom = bottom;
+        this.right = right;
+    }
+}
+
diff --git a/awt/java/awt/ItemSelectable.java b/awt/java/awt/ItemSelectable.java
new file mode 100644
index 0000000..a46364b
--- /dev/null
+++ b/awt/java/awt/ItemSelectable.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.ItemListener;
+
+/**
+ * The ItemSelectable interface represents a set of items which can be selected.
+ */
+public interface ItemSelectable {
+
+    /**
+     * Adds an ItemListener for receiving item events when the state of an item 
+     * is changed by the user. 
+     * 
+     * @param l the ItemListener.
+     */
+    public void addItemListener(ItemListener l);
+
+    /**
+     * Gets an array of the selected objects or null if there is no selected object.
+     * 
+     * @return an array of the selected objects or null if there is no selected 
+     * object.
+     */
+    public Object[] getSelectedObjects();
+
+    /**
+     * Removes the specified ItemListener.
+     * 
+     * @param l the ItemListener which will be removed.
+     */
+    public void removeItemListener(ItemListener l);
+
+}
diff --git a/awt/java/awt/MenuComponent.java b/awt/java/awt/MenuComponent.java
new file mode 100644
index 0000000..9eb4f3d
--- /dev/null
+++ b/awt/java/awt/MenuComponent.java
@@ -0,0 +1,1041 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.event.FocusListener;
+import java.awt.event.MouseEvent;
+import java.awt.peer.MenuComponentPeer;
+import java.io.Serializable;
+import java.util.Locale;
+//import javax.accessibility.Accessible;
+//import javax.accessibility.AccessibleComponent;
+//import javax.accessibility.AccessibleContext;
+//import javax.accessibility.AccessibleRole;
+//import javax.accessibility.AccessibleSelection;
+//import javax.accessibility.AccessibleStateSet;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.state.MenuItemState;
+import org.apache.harmony.awt.state.MenuState;
+
+/**
+ * The MenuComponent abstract class is the superclass for menu 
+ * components. Menu components receive and process AWT events.
+ */
+public abstract class MenuComponent implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4536902356223894379L;
+
+    /** The name. */
+    private String name;
+
+    /** The font. */
+    private Font font;
+
+    /** The parent. */
+    MenuContainer parent;
+
+    /** The deprecated event handler. */
+    boolean deprecatedEventHandler = true;
+
+    /** The selected item index. */
+    private int selectedItemIndex;
+
+    //???AWT: private AccessibleContext accessibleContext;
+
+    /** The toolkit. */
+    final Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+    //???AWT
+    /*
+    protected abstract class AccessibleAWTMenuComponent extends AccessibleContext implements
+            Serializable, AccessibleComponent, AccessibleSelection {
+        private static final long serialVersionUID = -4269533416223798698L;
+
+        public void addFocusListener(FocusListener listener) {
+        }
+
+        public boolean contains(Point pt) {
+            return false;
+        }
+
+        public Accessible getAccessibleAt(Point pt) {
+            return null;
+        }
+
+        public Color getBackground() {
+            return null;
+        }
+
+        public Rectangle getBounds() {
+            return null;
+        }
+
+        public Cursor getCursor() {
+            return null;
+        }
+
+        public Font getFont() {
+            return MenuComponent.this.getFont();
+        }
+
+        public FontMetrics getFontMetrics(Font font) {
+            return null;
+        }
+
+        public Color getForeground() {
+            return null;
+        }
+
+        public Point getLocation() {
+            return null;
+        }
+
+        public Point getLocationOnScreen() {
+            return null;
+        }
+
+        public Dimension getSize() {
+            return null;
+        }
+
+        public boolean isEnabled() {
+            return true; // always enabled
+        }
+
+        public boolean isFocusTraversable() {
+            return true; // always focus traversable
+        }
+
+        public boolean isShowing() {
+            return true;// always showing
+        }
+
+        public boolean isVisible() {
+            return true; // always visible
+        }
+
+        public void removeFocusListener(FocusListener listener) {
+        }
+
+        public void requestFocus() {
+        }
+
+        public void setBackground(Color color) {
+        }
+
+        public void setBounds(Rectangle rect) {
+        }
+
+        public void setCursor(Cursor cursor) {
+        }
+
+        public void setEnabled(boolean enabled) {
+        }
+
+        public void setFont(Font font) {
+            MenuComponent.this.setFont(font);
+        }
+
+        public void setForeground(Color color) {
+        }
+
+        public void setLocation(Point pt) {
+        }
+
+        public void setSize(Dimension pt) {
+        }
+
+        public void setVisible(boolean visible) {
+        }
+
+        public void addAccessibleSelection(int index) {
+        }
+
+        public void clearAccessibleSelection() {
+        }
+
+        public Accessible getAccessibleSelection(int index) {
+            return null;
+        }
+
+        public int getAccessibleSelectionCount() {
+            return 0;
+        }
+
+        public boolean isAccessibleChildSelected(int index) {
+            return false;
+        }
+
+        public void removeAccessibleSelection(int index) {
+        }
+
+        public void selectAllAccessibleSelection() {
+        }
+
+        @Override
+        public Accessible getAccessibleChild(int index) {
+            return null;
+        }
+
+        @Override
+        public int getAccessibleChildrenCount() {
+            return 0;
+        }
+
+        @Override
+        public AccessibleComponent getAccessibleComponent() {
+            return this;
+        }
+
+        @Override
+        public String getAccessibleDescription() {
+            return super.getAccessibleDescription();
+        }
+
+        @Override
+        public int getAccessibleIndexInParent() {
+            toolkit.lockAWT();
+            try {
+                Accessible aParent = getAccessibleParent();
+                int aIndex = -1;
+                if (aParent instanceof MenuComponent) {
+                    MenuComponent parent = (MenuComponent) aParent;
+                    int count = parent.getItemCount();
+                    for (int i = 0; i < count; i++) {
+                        MenuComponent comp = parent.getItem(i);
+                        if (comp instanceof Accessible) {
+                            aIndex++;
+                            if (comp == MenuComponent.this) {
+                                return aIndex;
+                            }
+                        }
+                    }
+                }
+                return -1;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public String getAccessibleName() {
+            return super.getAccessibleName();
+        }
+
+        @Override
+        public Accessible getAccessibleParent() {
+            toolkit.lockAWT();
+            try {
+                Accessible aParent = super.getAccessibleParent();
+                if (aParent != null) {
+                    return aParent;
+                }
+                MenuContainer parent = getParent();
+                if (parent instanceof Accessible) {
+                    aParent = (Accessible) parent;
+                }
+                return aParent;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleRole getAccessibleRole() {
+            return AccessibleRole.AWT_COMPONENT;
+        }
+
+        @Override
+        public AccessibleSelection getAccessibleSelection() {
+            return this;
+        }
+
+        @Override
+        public AccessibleStateSet getAccessibleStateSet() {
+            return new AccessibleStateSet();
+        }
+
+        @Override
+        public Locale getLocale() {
+            return Locale.getDefault();
+        }
+    }
+    */
+
+    /**
+     * The accessor to MenuComponent internal state,
+     * utilized by the visual theme.
+     * 
+     * @throws HeadlessException the headless exception
+     */
+    //???AWT
+    /*
+    class State implements MenuState {
+        Dimension size;
+
+        Dimension getSize() {
+            if (size == null) {
+                calculate();
+            }
+            return size;
+        }
+
+        public int getWidth() {
+            return getSize().width;
+        }
+
+        public int getHeight() {
+            return getSize().height;
+        }
+
+        public Font getFont() {
+            return MenuComponent.this.getFont();
+        }
+
+        public int getItemCount() {
+            return MenuComponent.this.getItemCount();
+        }
+
+        public int getSelectedItemIndex() {
+            return MenuComponent.this.getSelectedItemIndex();
+        }
+
+        public boolean isFontSet() {
+            return MenuComponent.this.isFontSet();
+        }
+
+        @SuppressWarnings("deprecation")
+        public FontMetrics getFontMetrics(Font f) {
+            return MenuComponent.this.toolkit.getFontMetrics(f);
+        }
+
+        public Point getLocation() {
+            return MenuComponent.this.getLocation();
+        }
+
+        public MenuItemState getItem(int index) {
+            MenuItem item = MenuComponent.this.getItem(index);
+            return item.itemState;
+        }
+
+        public void setSize(int w, int h) {
+            this.size = new Dimension(w, h);
+        }
+
+        void calculate() {
+            size = new Dimension();
+            size.setSize(toolkit.theme.calculateMenuSize(this));
+        }
+
+        void reset() {
+            for (int i = 0; i < getItemCount(); i++) {
+                ((MenuItem.State) getItem(i)).reset();
+            }
+        }
+
+    }
+    */
+    
+    /**
+     * Pop-up box for menu. It transfers the paint events, 
+     * keyboard and mouse events to the menu component itself
+     */
+    //???AWT
+    /*
+    class MenuPopupBox extends PopupBox {
+        private final Point lastMousePos = new Point();
+
+        @Override
+        boolean isMenu() {
+            return true;
+        }
+
+        @Override
+        void paint(Graphics gr) {
+            MenuComponent.this.paint(gr);
+        }
+
+        @Override
+        void onKeyEvent(int eventId, int vKey, long when, int modifiers) {
+            MenuComponent.this.onKeyEvent(eventId, vKey, when, modifiers);
+        }
+
+        @Override
+        void onMouseEvent(int eventId, Point where, int mouseButton, long when, int modifiers,
+                int wheelRotation) {
+            // prevent conflict of mouse and keyboard
+            // when sub-menu drops down due to keyboard navigation
+            if (lastMousePos.equals(where)
+                    && (eventId == MouseEvent.MOUSE_MOVED || eventId == MouseEvent.MOUSE_ENTERED)) {
+                return;
+            }
+            lastMousePos.setLocation(where);
+            MenuComponent.this.onMouseEvent(eventId, where, mouseButton, when, modifiers);
+        }
+    }
+    */
+    
+    /**
+     * Instantiates a new MenuComponent object.
+     * 
+     * @throws HeadlessException if the graphical interface
+     * environment can't support MenuComponents
+     */
+    public MenuComponent() throws HeadlessException {
+        toolkit.lockAWT();
+        try {
+            Toolkit.checkHeadless();
+            name = autoName();
+            selectedItemIndex = -1;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the name of the MenuComponent object.
+     * 
+     * @return the name of the MenuComponent object.
+     */
+    public String getName() {
+        toolkit.lockAWT();
+        try {
+            return name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns a String representation of the MenuComponent object.
+     * 
+     * @return a String representation of the MenuComponent object.
+     */
+    @Override
+    public String toString() {
+        toolkit.lockAWT();
+        try {
+            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Parent menu Container .
+     * 
+     * @return the parent
+     */
+    public MenuContainer getParent() {
+        toolkit.lockAWT();
+        try {
+            return parent;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the name of the MenuComponent to the specified string.
+     * 
+     * @param name the new name of the MenuComponent object. 
+     */
+    public void setName(String name) {
+        toolkit.lockAWT();
+        try {
+            this.name = name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Dispatches AWT event.
+     * 
+     * @param event the AWTEvent.
+     */
+    public final void dispatchEvent(AWTEvent event) {
+        toolkit.lockAWT();
+        try {
+            processEvent(event);
+            if (deprecatedEventHandler) {
+                postDeprecatedEvent(event);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Post deprecated event.
+     * 
+     * @param event the event
+     */
+    void postDeprecatedEvent(AWTEvent event) {
+        Event evt = event.getEvent();
+        if (evt != null) {
+            postEvent(evt);
+        }
+    }
+
+    /**
+     * Gets the peer of the MenuComponent; an application must not
+     * use this method directly.
+     * 
+     * @return the MenuComponentPeer object.
+     *
+     * @deprecated an application must not use this method directly.
+     */
+    @Deprecated
+    public MenuComponentPeer getPeer() throws org.apache.harmony.luni.util.NotImplementedException {
+        toolkit.lockAWT();
+        try {
+        } finally {
+            toolkit.unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Gets the locking object of this MenuComponent.
+     * 
+     * @return the locking object of this MenuComponent.
+     */
+    protected final Object getTreeLock() {
+        return toolkit.awtTreeLock;
+    }
+
+    /**
+     * Posts the Event to the MenuComponent.
+     * 
+     * @param e the Event.
+     * 
+     * @return true, if the event is posted successfully; 
+     * false otherwise.
+     * 
+     * @deprecated Replaced dispatchEvent method.
+     */
+    @SuppressWarnings("deprecation")
+    @Deprecated
+    public boolean postEvent(Event e) {
+        toolkit.lockAWT();
+        try {
+            if (parent != null) {
+                return parent.postEvent(e);
+            }
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the string representation of the MenuComponent state.
+     * 
+     * @return returns the string representation of the MenuComponent
+     * state.
+     */
+    protected String paramString() {
+        toolkit.lockAWT();
+        try {
+            return getName();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    public AccessibleContext getAccessibleContext() {
+        toolkit.lockAWT();
+        try {
+            if (accessibleContext == null) {
+                accessibleContext = createAccessibleContext();
+            }
+            return accessibleContext;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Gets the font of the MenuComponent object.
+     * 
+     * @return the Font of the MenuComponent object.
+     */
+    public Font getFont() {
+        toolkit.lockAWT();
+        try {
+            if (font == null && hasDefaultFont()) {
+                return toolkit.getDefaultFont();
+            }
+            if (font == null && parent != null) {
+                return parent.getFont();
+            }
+            return font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if is font set.
+     * 
+     * @return true, if is font set
+     */
+    boolean isFontSet() {
+        return font != null
+                || ((parent instanceof MenuComponent) && ((MenuComponent) parent).isFontSet());
+    }
+
+    /**
+     * Checks for default font.
+     * 
+     * @return true, if successful
+     */
+    boolean hasDefaultFont() {
+        return false;
+    }
+
+    /**
+     * Processes an AWTEevent on this menu component.
+     * 
+     * @param event the AWTEvent.
+     */
+    protected void processEvent(AWTEvent event) {
+        toolkit.lockAWT();
+        try {
+            // do nothing
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Removes the peer of the MenuComponent.
+     */
+    public void removeNotify() {
+        toolkit.lockAWT();
+        try {
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the Font for this MenuComponent object.
+     * 
+     * @param font the new Font to be used for this MenuComponent.
+     */
+    public void setFont(Font font) {
+        toolkit.lockAWT();
+        try {
+            this.font = font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the parent.
+     * 
+     * @param parent the new parent
+     */
+    void setParent(MenuContainer parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Gets the location.
+     * 
+     * @return the location
+     */
+    Point getLocation() {
+        // to be overridden
+        return new Point(0, 0);
+    }
+
+    /**
+     * Gets the width.
+     * 
+     * @return the width
+     */
+    int getWidth() {
+        // to be overridden
+        return 1;
+    }
+
+    /**
+     * Gets the height.
+     * 
+     * @return the height
+     */
+    int getHeight() {
+        // to be overridden
+        return 1;
+    }
+
+    /**
+     * Recursively find the menu item for a menu shortcut.
+     * 
+     * @param gr the gr
+     * 
+     * @return the menu item;
+     * or null if the item is not available for this shortcut
+     */
+    //???AWT
+    /*
+    MenuItem getShortcutMenuItemImpl(MenuShortcut ms) {
+        if (ms == null) {
+            return null;
+        }
+        for (int i = 0; i < getItemCount(); i++) {
+            MenuItem mi = getItem(i);
+            if (mi instanceof Menu) {
+                mi = ((Menu) mi).getShortcutMenuItemImpl(ms);
+                if (mi != null) {
+                    return mi;
+                }
+            } else if (ms.equals(mi.getShortcut())) {
+                return mi;
+            }
+        }
+        return null;
+    }
+    */
+
+    void paint(Graphics gr) {
+        gr.setColor(Color.LIGHT_GRAY);
+        gr.fillRect(0, 0, getWidth(), getHeight());
+        gr.setColor(Color.BLACK);
+    }
+
+    /**
+     * Mouse events handler.
+     * 
+     * @param eventId - one of the MouseEvent.MOUSE_* constants
+     * @param where - mouse location
+     * @param mouseButton - mouse button that was pressed or released
+     * @param when - event time
+     * @param modifiers - input event modifiers
+     */
+    void onMouseEvent(int eventId, Point where, int mouseButton, long when, int modifiers) {
+        // to be overridden
+    }
+
+    /**
+     * Keyboard event handler.
+     * 
+     * @param eventId - one of the KeyEvent.KEY_* constants
+     * @param vKey - the key code
+     * @param when - event time
+     * @param modifiers - input event modifiers
+     */
+    void onKeyEvent(int eventId, int vKey, long when, int modifiers) {
+        // to be overridden
+    }
+
+    /**
+     * Post the ActionEvent or ItemEvent,
+     * depending on type of the menu item.
+     * 
+     * @param index the index
+     * 
+     * @return the item rect
+     */
+    //???AWT
+    /*
+    void fireItemAction(int item, long when, int modifiers) {
+        MenuItem mi = getItem(item);
+        mi.itemSelected(when, modifiers);
+    }
+
+    MenuItem getItem(int index) {
+        // to be overridden
+        return null;
+    }
+
+    int getItemCount() {
+        return 0;
+    }
+    */
+
+    /**
+     * @return The sub-menu of currently selecetd item, 
+     * or null if such a sub-menu is not available 
+     */
+    //???AWT
+    /*
+    Menu getSelectedSubmenu() {
+        if (selectedItemIndex < 0) {
+            return null;
+        }
+        MenuItem item = getItem(selectedItemIndex);
+        return (item instanceof Menu) ? (Menu) item : null;
+    }
+    */
+
+    /**
+     * Convenience method for selectItem(index, true)
+     */
+    //???AWT
+    /*
+    void selectItem(int index) {
+        selectItem(index, true);
+    }
+    */
+
+    /**
+     * Change the selection in the menu 
+     * @param index - new selecetd item's index
+     * @param showSubMenu - if new selected item has a sub-menu,
+     * should that sub-menu be displayed 
+     */
+    //???AWT
+    /*
+    void selectItem(int index, boolean showSubMenu) {
+        if (selectedItemIndex == index) {
+            return;
+        }
+        if (selectedItemIndex >= 0 && getItem(selectedItemIndex) instanceof Menu) {
+            ((Menu) getItem(selectedItemIndex)).hide();
+        }
+        MultiRectArea clip = getUpdateClip(index, selectedItemIndex);
+        selectedItemIndex = index;
+        Graphics gr = getGraphics(clip);
+        if (gr != null) {
+            paint(gr);
+        }
+        if (showSubMenu) {
+            showSubMenu(selectedItemIndex);
+        }
+    }
+    */
+
+    /**
+     * Change the selected item to the next one in the requested direction
+     * moving cyclically, skipping separators
+     * @param forward - the direction to move the selection
+     * @param showSubMenu - if new selected item has a sub-menu,
+     * should that sub-menu be displayed 
+     */
+    //???AWT
+    /*
+    void selectNextItem(boolean forward, boolean showSubMenu) {
+        int selected = getSelectedItemIndex();
+        int count = getItemCount();
+        if (count == 0) {
+            return;
+        }
+        if (selected < 0) {
+            selected = (forward ? count - 1 : 0);
+        }
+        int i = selected;
+        do {
+            i = (forward ? (i + 1) : (i + count - 1)) % count;
+            i %= count;
+            MenuItem item = getItem(i);
+            if (!"-".equals(item.getLabel())) { //$NON-NLS-1$
+                selectItem(i, showSubMenu);
+                return;
+            }
+        } while (i != selected);
+    }
+
+    
+    void showSubMenu(int index) {
+        if ((index < 0) || !isActive()) {
+            return;
+        }
+        MenuItem item = getItem(index);
+        if (item instanceof Menu) {
+            Menu menu = ((Menu) getItem(index));
+            if (menu.getItemCount() == 0) {
+                return;
+            }
+            Point location = getSubmenuLocation(index);
+            menu.show(location.x, location.y, false);
+        }
+    }
+    */
+
+    /**
+     * @return - the menu bar which is the root of crrent menu's hierarchy;
+     * or null if the hierarchy root is not a menu bar 
+     */
+    //???AWT
+    /*
+    MenuBar getMenuBar() {
+        if (parent instanceof MenuBar) {
+            return (MenuBar) parent;
+        }
+        if (parent instanceof MenuComponent) {
+            return ((MenuComponent) parent).getMenuBar();
+        }
+        return null;
+    }
+
+    PopupBox getPopupBox() {
+        return null;
+    }
+    */
+
+    Rectangle getItemRect(int index) {
+        // to be overridden
+        return null;
+    }
+
+    /**
+     * Determine the clip region when menu selection is changed
+     * from index1 to index2.
+     * 
+     * @param index1 - old selected intem
+     * @param index2 - new selected item
+     * 
+     * @return - the region to repaint
+     */
+    final MultiRectArea getUpdateClip(int index1, int index2) {
+        MultiRectArea clip = new MultiRectArea();
+        if (index1 >= 0) {
+            clip.add(getItemRect(index1));
+        }
+        if (index2 >= 0) {
+            clip.add(getItemRect(index2));
+        }
+        return clip;
+    }
+
+    /**
+     * Gets the submenu location.
+     * 
+     * @param index the index
+     * 
+     * @return the submenu location
+     */
+    Point getSubmenuLocation(int index) {
+        // to be overridden
+        return new Point(0, 0);
+    }
+
+    /**
+     * Gets the selected item index.
+     * 
+     * @return the selected item index
+     */
+    int getSelectedItemIndex() {
+        return selectedItemIndex;
+    }
+
+    /**
+     * Hide.
+     */
+    void hide() {
+        selectedItemIndex = -1;
+        if (parent instanceof MenuComponent) {
+            ((MenuComponent) parent).itemHidden(this);
+        }
+    }
+
+    /**
+     * Item hidden.
+     * 
+     * @param mc the mc
+     */
+    void itemHidden(MenuComponent mc) {
+        // to be overridden
+    }
+
+    /**
+     * Checks if is visible.
+     * 
+     * @return true, if is visible
+     */
+    boolean isVisible() {
+        return true;
+    }
+
+    /**
+     * Checks if is active.
+     * 
+     * @return true, if is active
+     */
+    boolean isActive() {
+        return true;
+    }
+
+    /**
+     * Hide all menu hierarchy.
+     */
+    void endMenu() {
+        //???AWT: toolkit.dispatcher.popupDispatcher.deactivateAll();
+    }
+
+    /**
+     * Handle the mouse click or Enter key event on a menu's item.
+     * 
+     * @param when - the event time
+     * @param modifiers - input event modifiers
+     */
+    void itemSelected(long when, int modifiers) {
+        endMenu();
+    }
+
+    /**
+     * Auto name.
+     * 
+     * @return the string
+     */
+    String autoName() {
+        String name = getClass().getName();
+        if (name.indexOf("$") != -1) { //$NON-NLS-1$
+            return null;
+        }
+        //???AWT: int number = toolkit.autoNumber.nextMenuComponent++;
+        int number = 0;
+        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
+        return name;
+    }
+
+    /**
+     * Creates the Graphics object for the pop-up box of this menu component.
+     * 
+     * @param clip - the clip to set on this Graphics
+     * 
+     * @return - the created Graphics object,
+     * or null if such object is not available.
+     */
+    Graphics getGraphics(MultiRectArea clip) {
+        // to be overridden
+        return null;
+    }
+
+    /**
+     * @return accessible context specific for particular menu component
+     */
+    //???AWT
+    /*
+    AccessibleContext createAccessibleContext() {
+        return null;
+    }
+    */
+}
diff --git a/awt/java/awt/MenuContainer.java b/awt/java/awt/MenuContainer.java
new file mode 100644
index 0000000..7a48f13
--- /dev/null
+++ b/awt/java/awt/MenuContainer.java
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The MenuContainer interface represents all menu containers.
+ */
+public interface MenuContainer {
+
+    /**
+     * Removes the specified MenuComponent from the MenuContainer.
+     * 
+     * @param c the MenuComponent.
+     */
+    public void remove(MenuComponent c);
+
+    /**
+     * Gets the Font of the MenuContainer.
+     * 
+     * @return the font of the MenuContainer.
+     */
+    public Font getFont();
+
+    /**
+     * Posts an Event.
+     * 
+     * @param e the Event.
+     * 
+     * @return true if the event is posted successfully; 
+     * false otherwise.
+     * 
+     * @deprecated Replaced by dispatchEvent method.
+     */
+    @Deprecated
+    public boolean postEvent(Event e);
+
+}
+
diff --git a/awt/java/awt/ModalContext.java b/awt/java/awt/ModalContext.java
new file mode 100644
index 0000000..32a5912
--- /dev/null
+++ b/awt/java/awt/ModalContext.java
@@ -0,0 +1,64 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ *
+ * The context for nested event loop. It can be dialog, popup menu etc.
+ */
+class ModalContext {
+
+    private boolean running = false;
+
+    private final Toolkit toolkit;
+
+    ModalContext() {
+        toolkit = Toolkit.getDefaultToolkit();
+    }
+
+    /**
+     * Set up and run modal loop in this context
+     *
+     */
+    void runModalLoop() {
+        running = true;
+        toolkit.dispatchThread.runModalLoop(this);
+    }
+
+    /**
+     * Leave the modal loop running in this context
+     * This method doesn't stops the loop immediately,
+     * it just sets the flag that says the modal loop to stop
+     *
+     */
+    void endModalLoop() {
+        running = false;
+    }
+
+    /**
+     *
+     * @return modal loop is currently running in this context
+     */
+    boolean isModalLoopRunning() {
+        return running;
+    }
+
+}
diff --git a/awt/java/awt/MouseDispatcher.java b/awt/java/awt/MouseDispatcher.java
new file mode 100644
index 0000000..df48f9d
--- /dev/null
+++ b/awt/java/awt/MouseDispatcher.java
@@ -0,0 +1,418 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev, Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.Dispatcher.MouseGrabManager;
+import java.util.EventListener;
+
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+
+class MouseDispatcher {
+
+    // Fields for synthetic mouse click events generation
+    private static final int clickDelta = 5;
+    private final long[] lastPressTime = new long[] {0l, 0l, 0l};
+    private final Point[] lastPressPos = new Point[] {null, null, null};
+    private final boolean[] buttonPressed = new boolean[] {false, false, false};
+    private final int[] clickCount = new int[] {0, 0, 0};
+
+    // Fields for mouse entered/exited support
+    private Component lastUnderPointer = null;
+    private final Point lastScreenPos = new Point(-1, -1);
+
+    // Fields for redundant mouse moved/dragged filtering
+    private Component lastUnderMotion = null;
+    private Point lastLocalPos = new Point(-1, -1);
+
+    private final MouseGrabManager mouseGrabManager;
+    private final Toolkit toolkit;
+
+    static Point convertPoint(Component src, int x, int y, Component dest) {
+        Point srcPoint = getAbsLocation(src);
+        Point destPoint = getAbsLocation(dest);
+
+        return new Point(x + (srcPoint.x - destPoint.x),
+                         y + (srcPoint.y - destPoint.y));
+    }
+
+    static Point convertPoint(Component src, Point p, Component dst) {
+        return convertPoint(src, p.x, p.y, dst);
+    }
+
+    private static Point getAbsLocation(Component comp) {
+        Point location = new Point(0, 0);
+// BEGIN android-changed: AWT components not supported
+//        for (Component parent = comp; parent != null; parent = parent.parent) {
+//            Point parentPos = (parent instanceof EmbeddedWindow ?
+//                               parent.getNativeWindow().getScreenPos() :
+//                               parent.getLocation());
+//
+//            location.translate(parentPos.x, parentPos.y);
+//
+//            if (parent instanceof Window) {
+//                break;
+//            }
+//        }
+// END android-changed
+
+        return location;
+    }
+
+    MouseDispatcher(MouseGrabManager mouseGrabManager,
+                    Toolkit toolkit) {
+        this.mouseGrabManager = mouseGrabManager;
+        this.toolkit = toolkit;
+    }
+
+    Point getPointerPos() {
+        return lastScreenPos;
+    }
+
+    boolean dispatch(Component src, NativeEvent event) {
+        int id = event.getEventId();
+
+        lastScreenPos.setLocation(event.getScreenPos());
+        checkMouseEnterExit(event.getInputModifiers(), event.getTime());
+
+        if (id == MouseEvent.MOUSE_WHEEL) {
+// BEGIN android-changed: AWT components not supported
+//            dispatchWheelEvent(src, event);
+// END android-changed
+        } else if ((id != MouseEvent.MOUSE_ENTERED) &&
+                   (id != MouseEvent.MOUSE_EXITED)) {
+            PointerInfo info = new PointerInfo(src, event.getLocalPos());
+
+            mouseGrabManager.preprocessEvent(event);
+            findEventSource(info);
+            if ((id == MouseEvent.MOUSE_PRESSED) ||
+                (id == MouseEvent.MOUSE_RELEASED)) {
+
+                dispatchButtonEvent(info, event);
+            } else if ((id == MouseEvent.MOUSE_MOVED) ||
+                       (id == MouseEvent.MOUSE_DRAGGED)) {
+
+                dispatchMotionEvent(info, event);
+            }
+        }
+
+        return false;
+    }
+
+    private void checkMouseEnterExit(int modifiers, long when) {
+// BEGIN android-changed: AWT components not supported
+//        PointerInfo info = findComponentUnderPointer();
+//        Component curUnderPointer =
+//                propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
+//                               MouseListener.class, false).src;
+//
+//        if (curUnderPointer != lastUnderPointer) {
+//            Point pos = info.position;
+//            if ((lastUnderPointer != null) &&
+//                 lastUnderPointer.isMouseExitedExpected()) {
+//
+//                Point exitPos = convertPoint(null, lastScreenPos.x,
+//                                             lastScreenPos.y, lastUnderPointer);
+//
+//                postMouseEnterExit(MouseEvent.MOUSE_EXITED, modifiers, when,
+//                                   exitPos.x, exitPos.y, lastUnderPointer);
+//            }
+//            setCursor(curUnderPointer);
+//            if (curUnderPointer != null) {
+//                postMouseEnterExit(MouseEvent.MOUSE_ENTERED, modifiers, when,
+//                                   pos.x, pos.y, curUnderPointer);
+//            }
+//            lastUnderPointer = curUnderPointer;
+//        }
+// END android-changed
+    }
+
+    private void setCursor(Component comp) {
+        if (comp == null) {
+            return;
+        }
+        Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
+        Component cursorComp = ((grabOwner != null) &&
+                                 grabOwner.isShowing() ? grabOwner : comp);
+        cursorComp.setCursor();
+    }
+
+    private void postMouseEnterExit(int id, int mod, long when,
+                                    int x, int y, Component comp) {
+        if (comp.isIndirectlyEnabled()) {
+            toolkit.getSystemEventQueueImpl().postEvent(
+                    new MouseEvent(comp, id, when, mod, x, y, 0, false));
+            comp.setMouseExitedExpected(id == MouseEvent.MOUSE_ENTERED);
+        } else {
+            comp.setMouseExitedExpected(false);
+        }
+    }
+
+ // BEGIN android-changed: AWT components not supported
+//    private PointerInfo findComponentUnderPointer() {
+//        NativeWindow nativeWindow = toolkit.getWindowFactory().
+//        getWindowFromPoint(lastScreenPos);
+//
+//        if (nativeWindow != null) {
+//            Component comp = toolkit.getComponentById(nativeWindow.getId());
+//
+//            if (comp != null) {
+//                Window window = comp.getWindowAncestor();
+//                Point pointerPos = convertPoint(null, lastScreenPos.x,
+//                                                lastScreenPos.y, window);
+//
+//                if (window.getClient().contains(pointerPos)) {
+//                    PointerInfo info = new PointerInfo(window, pointerPos);
+//
+//                    fall2Child(info);
+//
+//                    return info;
+//                }
+//            }
+//        }
+//
+//        return new PointerInfo(null, null);
+//    }
+// END android-changed
+    
+    private void findEventSource(PointerInfo info) {
+        Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
+
+        if (grabOwner != null && grabOwner.isShowing()) {
+            info.position = convertPoint(info.src, info.position, grabOwner);
+            info.src = grabOwner;
+        } else {
+            //???AWT: rise2TopLevel(info);
+            //???AWT: fall2Child(info);
+        }
+    }
+
+ // BEGIN android-changed: AWT components not supported
+//    private void rise2TopLevel(PointerInfo info) {
+//        while (!(info.src instanceof Window)) {
+//            info.position.translate(info.src.x, info.src.y);
+//            info.src = info.src.parent;
+//        }
+//    }
+//
+//    private void fall2Child(PointerInfo info) {
+//        Insets insets = info.src.getInsets();
+//
+//        final Point pos = info.position;
+//        final int x = pos.x;
+//        final int y = pos.y;
+//        if ((x >= insets.left) && (y >= insets.top) &&
+//                (x < (info.src.w - insets.right)) &&
+//                (y < (info.src.h - insets.bottom)))
+//        {
+//            Component[] children = ((Container) info.src).getComponents();
+//
+//            for (Component child : children) {
+//                if (child.isShowing()) {
+//                    if (child.contains(x - child.getX(),
+//                            y - child.getY()))
+//                    {
+//                        info.src = child;
+//                        pos.translate(-child.x, -child.y);
+//
+//                        if (child instanceof Container) {
+//                            fall2Child(info);
+//                        }
+//
+//                        return;
+//                    }
+//                }
+//            }
+//        }
+//    }
+// END android-changed
+
+    private void dispatchButtonEvent(PointerInfo info, NativeEvent event) {
+        int button = event.getMouseButton();
+        long time = event.getTime();
+        int id = event.getEventId();
+        int index = button - 1;
+        boolean clickRequired = false;
+
+        propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
+                       MouseListener.class, false);
+        if (id == MouseEvent.MOUSE_PRESSED) {
+            int clickInterval = toolkit.dispatcher.clickInterval;
+            mouseGrabManager.onMousePressed(info.src);
+            buttonPressed[index] = true;
+            clickCount[index] = (!deltaExceeded(index, info) &&
+                    ((time - lastPressTime[index]) <= clickInterval)) ?
+                    clickCount[index] + 1 : 1;
+            lastPressTime[index] = time;
+            lastPressPos[index] = info.position;
+        } else {
+            mouseGrabManager.onMouseReleased(info.src);
+            // set cursor back on synthetic mouse grab end:
+// BEGIN android-changed: AWT components not supported
+//            setCursor(findComponentUnderPointer().src);
+// END android-changed
+            if (buttonPressed[index]) {
+                buttonPressed[index] = false;
+                clickRequired = !deltaExceeded(index, info);
+            } else {
+                clickCount[index] = 0;
+            }
+        }
+        if (info.src.isIndirectlyEnabled()) {
+            final Point pos = info.position;
+            final int mod = event.getInputModifiers();
+            toolkit.getSystemEventQueueImpl().postEvent(
+                            new MouseEvent(info.src, id, time, mod, pos.x,
+                            pos.y, clickCount[index],
+                            event.getTrigger(), button));
+            if (clickRequired) {
+                toolkit.getSystemEventQueueImpl().postEvent(
+                            new MouseEvent(info.src,
+                            MouseEvent.MOUSE_CLICKED,
+                            time, mod, pos.x, pos.y,
+                            clickCount[index], false,
+                            button));
+            }
+        }
+    }
+
+    private boolean deltaExceeded(int index, PointerInfo info) {
+        final Point lastPos = lastPressPos[index];
+        if (lastPos == null) {
+            return true;
+        }
+        return ((Math.abs(lastPos.x - info.position.x) > clickDelta) ||
+                (Math.abs(lastPos.y - info.position.y) > clickDelta));
+    }
+
+    private void dispatchMotionEvent(PointerInfo info, NativeEvent event) {
+        propagateEvent(info, AWTEvent.MOUSE_MOTION_EVENT_MASK,
+                       MouseMotionListener.class, false);
+        final Point pos = info.position;
+        if ((lastUnderMotion != info.src) ||
+            !lastLocalPos.equals(pos)) {
+
+            lastUnderMotion = info.src;
+            lastLocalPos = pos;
+
+            if (info.src.isIndirectlyEnabled()) {
+                toolkit.getSystemEventQueueImpl().postEvent(
+                            new MouseEvent(info.src, event.getEventId(),
+                            event.getTime(),
+                            event.getInputModifiers(),
+                            pos.x, pos.y, 0, false));
+            }
+        }
+    }
+
+    MouseWheelEvent createWheelEvent(Component src, NativeEvent event,
+                                     Point where) {
+
+        Integer scrollAmountProperty =
+            (Integer)toolkit.getDesktopProperty("awt.wheelScrollingSize"); //$NON-NLS-1$
+        int amount = 1;
+        int type = MouseWheelEvent.WHEEL_UNIT_SCROLL;
+
+        if (scrollAmountProperty != null) {
+            amount = scrollAmountProperty.intValue();
+            if (amount == -1) {
+                type = MouseWheelEvent.WHEEL_BLOCK_SCROLL;
+                amount = 1;
+            }
+        }
+        return new MouseWheelEvent(src, event.getEventId(),
+                event.getTime(), event.getInputModifiers(),
+                where.x, where.y, 0, false, type, amount,
+                event.getWheelRotation());
+    }
+
+// BEGIN android-changed: AWT components not supported
+//    private void dispatchWheelEvent(Component src, NativeEvent event) {
+//        PointerInfo info = findComponentUnderPointer();
+//
+//        if (info.src == null) {
+//            info.src = src;
+//            info.position = event.getLocalPos();
+//        }
+//
+//        propagateEvent(info, AWTEvent.MOUSE_WHEEL_EVENT_MASK,
+//                       MouseWheelListener.class, true);
+//        if ((info.src != null) && info.src.isIndirectlyEnabled()) {
+//            toolkit.getSystemEventQueueImpl().postEvent(
+//                    createWheelEvent(info.src, event, info.position));
+//        }
+//    }
+// END android-changed
+
+    private PointerInfo propagateEvent(PointerInfo info, long mask,
+                                       Class<? extends EventListener> type, boolean pierceHW) {
+        Component src = info.src;
+        while ((src != null) &&
+               (src.isLightweight() || pierceHW) &&
+              !(src.isMouseEventEnabled(mask) ||
+               (src.getListeners(type).length > 0))) {
+
+            info.position.translate(src.x, src.y);
+// BEGIN android-changed: AWT components not supported
+//            src = src.parent;
+// END android-changed
+            info.src = src;
+        }
+
+        return info;
+    }
+
+// BEGIN android-changed: AWT components not supported
+//    Window findWindowAt(Point p) {
+//        NativeWindow nativeWindow =
+//            toolkit.getWindowFactory().getWindowFromPoint(p);
+//
+//        Window window = null;
+//        if (nativeWindow != null) {
+//            Component comp = toolkit.getComponentById(nativeWindow.getId());
+//
+//            if (comp != null) {
+//                window = comp.getWindowAncestor();
+//            }
+//        }
+//        return window;
+//    }
+// END android-changed
+
+    private class PointerInfo {
+
+        Component src;
+        Point position;
+
+        PointerInfo(Component src, Point position) {
+            this.src = src;
+            this.position = position;
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/Paint.java b/awt/java/awt/Paint.java
new file mode 100644
index 0000000..f8732c8
--- /dev/null
+++ b/awt/java/awt/Paint.java
@@ -0,0 +1,52 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+/**
+ * The Paint interface provides possibility of generating 
+ * color patterns in device space for fill, draw, or stroke operations 
+ * in a Graphics2D.
+ */
+public interface Paint extends Transparency {
+    
+    /**
+     * Creates the PaintContext which is used to generate color 
+     * patterns for rendering operations of Graphics2D.
+     * 
+     * @param cm the ColorModel object, or null.
+     * @param deviceBounds the Rectangle represents the bounding box of
+     * device space for the graphics rendering operations.
+     * @param userBounds the Rectangle represents bounding box of
+     * user space for the graphics rendering operations.
+     * @param xform the AffineTransform for translation from user space 
+     * to device space.
+     * @param hints the RenderingHints preferences.
+     * 
+     * @return the PaintContext for generating color patterns.
+     */
+    PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+            Rectangle2D userBounds, AffineTransform xform,
+            RenderingHints hints);
+}
diff --git a/awt/java/awt/PaintContext.java b/awt/java/awt/PaintContext.java
new file mode 100644
index 0000000..647de8b
--- /dev/null
+++ b/awt/java/awt/PaintContext.java
@@ -0,0 +1,64 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+
+/**
+ * The PaintContext interface determines the specific environment for
+ * generating color patterns in device space for fill, draw, or stroke 
+ * rendering operations using Graphics2D. This interface provides colors
+ * through the Raster object associated with the specific ColorModel 
+ * for Graphics2D rendering operations.
+ */
+public interface PaintContext {
+    
+    /**
+     * Releases the resources allocated for the operation.
+     */
+    void dispose();
+
+    /**
+     * Gets the color model.
+     * 
+     * @return the ColorModel object.
+     */
+    ColorModel getColorModel();
+
+    /**
+     * Gets the Raster which defines the colors of the specified rectangular 
+     * area for Graphics2D rendering operations.
+     * 
+     * @param x the X coordinate of the device space area for which 
+     * colors are generated.
+     * @param y the Y coordinate of the device space area for which 
+     * colors are generated.
+     * @param w the width of the device space area for which 
+     * colors are generated.
+     * @param h the height of the device space area for which 
+     * colors are generated.
+     * 
+     * @return the Raster object which contains the colors of the specified 
+     * rectangular area for Graphics2D rendering operations.
+     */
+    Raster getRaster(int x, int y, int w, int h);
+}
diff --git a/awt/java/awt/Point.java b/awt/java/awt/Point.java
new file mode 100644
index 0000000..99418ed
--- /dev/null
+++ b/awt/java/awt/Point.java
@@ -0,0 +1,195 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.Point2D;
+import java.io.Serializable;
+
+/**
+ * The Point class represents a point location with coordinates X, Y in 
+ * current coordinate system.
+ */
+public class Point extends Point2D implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -5276940640259749850L;
+
+    /** The X coordinate of Point. */
+    public int x;
+    
+    /** The Y coordinate of Point. */
+    public int y;
+
+    /**
+     * Instantiates a new point with (0, O) coordinates, the origin of 
+     * coordinate system.
+     */
+    public Point() {
+        setLocation(0, 0);
+    }
+
+    /**
+     * Instantiates a new point with (x, y) coordinates.
+     * 
+     * @param x the X coordinate of Point.
+     * @param y the Y coordinate of Point.
+     */
+    public Point(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Instantiates a new point, giving it the same locaion as
+     * the parameter p.
+     * 
+     * @param p the Point object giving the coordinates of the new point.
+     */
+    public Point(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Compares current Point with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the Object being compared is a Point 
+     * whose coordinates are equal to the coordinates of this 
+     * Point, otherwise false.
+     * 
+     * @see java.awt.geom.Point2D#equals(Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Point) {
+            Point p = (Point)obj;
+            return x == p.x && y == p.y;
+        }
+        return false;
+    }
+
+    /**
+     * Returns string representation of the current Point object.
+     * 
+     * @return a string representation of the current Point object.
+     */
+    @Override
+    public String toString() {
+        return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Gets X coordinate of Point as a double.
+     * 
+     * @return X coordinate of the point as a double.
+     * 
+     * @see java.awt.geom.Point2D#getX()
+     */
+    @Override
+    public double getX() {
+        return x;
+    }
+
+    /**
+     * Gets Y coordinate of Point as a double.
+     * 
+     * @return Y coordinate of the point as a double.
+     * 
+     * @see java.awt.geom.Point2D#getY()
+     */
+    @Override
+    public double getY() {
+        return y;
+    }
+
+    /**
+     * Gets the location of the Point as a new Point object.
+     * 
+     * @return a copy of the Point.
+     */
+    public Point getLocation() {
+        return new Point(x, y);
+    }
+
+    /**
+     * Sets the location of the Point to the same coordinates as p.
+     * 
+     * @param p the Point that gives the new location.
+     */
+    public void setLocation(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Sets the location of the Point to the coordinates X, Y.
+     * 
+     * @param x the X coordinate of the Point's new location.
+     * @param y the Y coordinate of the Point's new location.
+     */
+    public void setLocation(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Sets the location of Point to the specified double coordinates.
+     * 
+     * @param x the X the Point's new location.
+     * @param y the Y the Point's new location.
+     *  
+     * @see java.awt.geom.Point2D#setLocation(double, double)
+     */
+    @Override
+    public void setLocation(double x, double y) {
+        x = x < Integer.MIN_VALUE ? Integer.MIN_VALUE : x > Integer.MAX_VALUE ? Integer.MAX_VALUE : x;
+        y = y < Integer.MIN_VALUE ? Integer.MIN_VALUE : y > Integer.MAX_VALUE ? Integer.MAX_VALUE : y;
+        setLocation((int)Math.round(x), (int)Math.round(y));
+    }
+
+    /**
+     * Moves the Point to the specified (x, y) location.
+     * 
+     * @param x the X coordinate of the new location.
+     * @param y the Y coordinate of the new location. 
+     */
+    public void move(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Translates current Point moving it from the position (x, y) 
+     * to the new position given by (x+dx, x+dy) coordinates.
+     * 
+     * @param dx the horizontal delta - the Point is moved to this distance along
+     * X axis.
+     * @param dy the vertical delta - the Point is moved to this distance along
+     * Y axis.
+     */
+    public void translate(int dx, int dy) {
+        x += dx;
+        y += dy;
+    }
+
+}
+
diff --git a/awt/java/awt/Polygon.java b/awt/java/awt/Polygon.java
new file mode 100644
index 0000000..6f3fc97
--- /dev/null
+++ b/awt/java/awt/Polygon.java
@@ -0,0 +1,494 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.*;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Polygon class defines an closed area specified by n vertices and 
+ * n edges. The coordinates of the vertices are specified by x, y arrays.
+ * The edges are the line segments from the point (x[i], y[i]) to the point 
+ * (x[i+1], y[i+1]), for -1 < i < (n-1) plus the line segment from 
+ * the point (x[n-1], y[n-1]) to the point (x[0], y[0]) point. 
+ * The Polygon is empty if the number of vertices is zero.   
+ */
+public class Polygon implements Shape, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -6460061437900069969L;
+
+    /** The points buffer capacity. */
+    private static final int BUFFER_CAPACITY = 4;
+    
+    /** The number of Polygon vertices.*/
+    public int npoints;
+    
+    /** The array of X coordinates of the vertices. */
+    public int[] xpoints;
+    
+    /** The array of Y coordinates of the vertices. */
+    public int[] ypoints;
+    
+    /**  
+     * The smallest Rectangle that completely contains this Polygon. 
+     */
+    protected Rectangle bounds;
+
+    /*
+     * Polygon path iterator  
+     */
+    /**
+     * The internal Class Iterator.
+     */
+    class Iterator implements PathIterator {
+
+        /** The source Polygon object. */
+        public Polygon p;
+        
+        /** The path iterator transformation. */
+        public AffineTransform t;
+        
+        /** The current segmenet index. */
+        public int index;
+
+        /**
+         * Constructs a new Polygon.Iterator for the given polygon and transformation
+         * 
+         * @param at - the AffineTransform object to apply rectangle path
+         * @param p the p
+         */
+        public Iterator(AffineTransform at, Polygon p) {
+            this.p = p;
+            this.t = at;
+            if (p.npoints == 0) {
+                index = 1;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_EVEN_ODD;
+        }
+
+        public boolean isDone() {
+            return index > p.npoints;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.110=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+            }
+            if (index == p.npoints) {
+                return SEG_CLOSE;
+            }
+            coords[0] = p.xpoints[index];
+            coords[1] = p.ypoints[index];
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return index == 0 ? SEG_MOVETO : SEG_LINETO;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.110=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+            }
+            if (index == p.npoints) {
+                return SEG_CLOSE;
+            }
+            coords[0] = p.xpoints[index];
+            coords[1] = p.ypoints[index];
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return index == 0 ? SEG_MOVETO : SEG_LINETO;
+        }
+    }
+
+    /**
+     * Instantiates a new empty polygon.
+     */
+    public Polygon() {
+        xpoints = new int[BUFFER_CAPACITY];
+        ypoints = new int[BUFFER_CAPACITY];
+    }
+
+    /**
+     * Instantiates a new polygon with the specified number of vertices,
+     * and the given arrays of x, y vertex coordinates. The length of 
+     * each coordinate array may not be less than the specified number of 
+     * vertices but may be greater. Only the first n elements are used from 
+     * each coordinate array.
+     * 
+     * @param xpoints the array of X vertex coordinates. 
+     * @param ypoints the array of Y vertex coordinates.
+     * @param npoints the number vertices of the polygon.
+     * @throws IndexOutOfBoundsException if the length of xpoints or ypoints
+     * is less than n.
+     * @throws NegativeArraySizeException if n is negative.
+     */
+    public Polygon(int[] xpoints, int[] ypoints, int npoints) {
+        if (npoints > xpoints.length || npoints > ypoints.length) {
+            // awt.111=Parameter npoints is greater than array length
+            throw new IndexOutOfBoundsException(Messages.getString("awt.111")); //$NON-NLS-1$
+        }
+        if (npoints < 0) {
+            // awt.112=Negative number of points
+            throw new NegativeArraySizeException(Messages.getString("awt.112")); //$NON-NLS-1$
+        }
+        this.npoints = npoints;
+        this.xpoints = new int[npoints];
+        this.ypoints = new int[npoints];
+        System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
+        System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);
+    }
+
+    /**
+     * Resets the current Polygon to an empty Polygon. More precisely, 
+     * the number of Polygon vertices is set to zero, but x, y coordinates 
+     * arrays are not affected.  
+     */
+    public void reset() {
+        npoints = 0;
+        bounds = null;
+    }
+
+    /**
+     * Invalidates the data that depends on the vertex coordinates. 
+     * This method should be called after direct manipulations  
+     * of the x, y vertex coordinates arrays to avoid unpredictable 
+     * results of methods which rely on the bounding box.
+     */
+    public void invalidate() {
+        bounds = null;
+    }
+
+    /**
+     * Adds the point to the Polygon and updates the bounding box 
+     * accordingly.
+     * 
+     * @param px the X coordinate of the added vertex.
+     * @param py the Y coordinate of the added vertex.
+     */
+    public void addPoint(int px, int py) {
+        if (npoints == xpoints.length) {
+            int[] tmp;
+
+            tmp = new int[xpoints.length + BUFFER_CAPACITY];
+            System.arraycopy(xpoints, 0, tmp, 0, xpoints.length);
+            xpoints = tmp;
+
+            tmp = new int[ypoints.length + BUFFER_CAPACITY];
+            System.arraycopy(ypoints, 0, tmp, 0, ypoints.length);
+            ypoints = tmp;
+        }
+
+        xpoints[npoints] = px;
+        ypoints[npoints] = py;
+        npoints++;
+
+        if (bounds != null) {
+            bounds.setFrameFromDiagonal(
+                    Math.min(bounds.getMinX(), px),
+                    Math.min(bounds.getMinY(), py),
+                    Math.max(bounds.getMaxX(), px),
+                    Math.max(bounds.getMaxY(), py));
+        }
+    }
+
+    /**
+     * Gets the bounding rectangle of the Polygon. The bounding rectangle
+     * is the smallest rectangle which contains the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * 
+     * @see java.awt.Shape#getBounds()
+     */
+    public Rectangle getBounds() {
+        if (bounds != null) {
+            return bounds;
+        }
+        if (npoints == 0) {
+            return new Rectangle();
+        }
+
+        int bx1 = xpoints[0];
+        int by1 = ypoints[0];
+        int bx2 = bx1;
+        int by2 = by1;
+
+        for (int i = 1; i < npoints; i++) {
+            int x = xpoints[i];
+            int y = ypoints[i];
+            if (x < bx1) {
+                bx1 = x;
+            } else if (x > bx2) {
+                bx2 = x;
+            }
+            if (y < by1) {
+                by1 = y;
+            } else if (y > by2) {
+                by2 = y;
+            }
+        }
+
+        return bounds = new Rectangle(bx1, by1, bx2 - bx1, by2 - by1);
+    }
+
+    /**
+     * Gets the bounding rectangle of the Polygon. The bounding rectangle
+     * is the smallest rectangle which contains the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * 
+     * @deprecated Use getBounds() method.
+     */
+    @Deprecated
+    public Rectangle getBoundingBox() {
+        return getBounds();
+    }
+
+    /**
+     * Gets the Rectangle2D which represents Polygon bounds.
+     * The bounding rectangle is the smallest rectangle which contains 
+     * the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * 
+     * @see java.awt.Shape#getBounds2D()
+     */
+    public Rectangle2D getBounds2D() {
+        return getBounds().getBounds2D();
+    }
+
+    /**
+     * Translates all vertices of Polygon the specified distances
+     * along X, Y axis.
+     * 
+     * @param mx the distance to translate horizontally.
+     * @param my the distance to translate vertically.
+     */
+    public void translate(int mx, int my) {
+        for (int i = 0; i < npoints; i++) {
+            xpoints[i] += mx;
+            ypoints[i] += my;
+        }
+        if (bounds != null) {
+            bounds.translate(mx, my);
+        }
+    }
+
+    /**
+     * Checks whether or not the point given by the coordinates x, y lies inside 
+     * the Polygon.
+     * 
+     * @param x the X coordinate of the point to check.
+     * @param y the Y coordinate of the point to check.
+     * 
+     * @return true, if the specified point lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @deprecated Use contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int x, int y) {
+        return contains((double) x, (double) y);
+    }
+
+    /**
+     * Checks whether or not the point given by the coordinates x, y lies inside 
+     * the Polygon.
+     * 
+     * @param x the X coordinate of the point to check.
+     * @param y the Y coordinate of the point to check.
+     * 
+     * @return true, if the specified point lies inside the Polygon,
+     * otherwise false.
+     */
+    public boolean contains(int x, int y) {
+        return contains((double) x, (double) y);
+    }
+
+    /**
+     * Checks whether or not the point with specified double coordinates 
+     * lies inside the Polygon.
+     * 
+     * @param x the X coordinate of the point to check.
+     * @param y the Y coordinate of the point to check.
+     * 
+     * @return true, if the point given by the double coordinates 
+     * lies inside the Polygon, otherwise false.
+     * 
+     * @see java.awt.Shape#contains(double, double)
+     */
+    public boolean contains(double x, double y) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, x, y));
+    }
+
+    /**
+     * Checks whether or not the rectangle determined by the parameters  
+     * [x, y, width, height] lies inside the Polygon.
+     * 
+     * @param x the X coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param y the Y coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param width the width of rectangle as a double.
+     * @param width the height of rectangle as a double.
+     * 
+     * @return true, if the specified rectangle lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @see java.awt.Shape#contains(double, double, double, double)
+     */
+    public boolean contains(double x, double y, double width, double height) {
+        int cross = Crossing.intersectShape(this, x, y, width, height);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    /**
+     * Checks whether or not the rectangle determined by the parameters  
+     * [x, y, width, height] intersects the interior of
+     * the Polygon.
+     * 
+     * @param x the X coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param y the Y coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param width the width of rectangle as a double.
+     * @param width the height of rectangle as a double.
+     * 
+     * @return true, if the specified rectangle intersects the interior of
+     * the Polygon, otherwise false.
+     * 
+     * @see java.awt.Shape#intersects(double, double, double, double)
+     */
+    public boolean intersects(double x, double y, double width, double height) {
+        int cross = Crossing.intersectShape(this, x, y, width, height);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    /**
+     * Checks whether or not the specified rectangle lies inside the Polygon.
+     * 
+     * @param rect the Rectangle2D object.
+     * 
+     * @return true, if the specified rectangle lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
+     */
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    /**
+     * Checks whether or not the specified Point lies inside the Polygon.
+     * 
+     * @param point the Point object.
+     * 
+     * @return true, if the specified Point lies inside the Polygon,
+     * otherwise false.
+     */
+    public boolean contains(Point point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    /**
+     * Checks whether or not the specified Point2D lies inside the Polygon.
+     * 
+     * @param point the Point2D object.
+     * 
+     * @return true, if the specified Point2D lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @see java.awt.Shape#contains(java.awt.geom.Point2D)
+     */
+    public boolean contains(Point2D point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    /**
+     * Checks whether or not the interior of rectangle specified by 
+     * the Rectangle2D object intersects the interior of the Polygon.
+     * 
+     * @param rect the Rectangle2D object.
+     * 
+     * @return true, if the Rectangle2D intersects the interior of
+     * the Polygon, otherwise false.
+     * 
+     * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D)
+     */
+    public boolean intersects(Rectangle2D rect) {
+        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    /**
+     * Gets the PathIterator object which gives the coordinates of 
+     * the polygon, transformed according to the specified AffineTransform.
+     * 
+     * @param t the specified AffineTransform object, or null.
+     * 
+     * @return PathIterator object for the Polygon.
+     * 
+     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform)
+     */
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(t, this);
+    }
+
+    /**
+     * Gets the PathIterator object which gives the coordinates of 
+     * the polygon, transformed according to the specified AffineTransform.
+     * The flatness parameter is ignored.
+     * 
+     * @param t the specified AffineTransform object, or null.
+     * @param flatness the maximum number of the control points for 
+     * a given curve which varies from colinear before a subdivided curve 
+     * is replaced by a straight line connecting the endpoints. 
+     * This parameter is ignored for the Polygon class.
+     * 
+     * @return PathIterator object for the Polygon.
+     *  
+     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform, double)
+     */
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(t, this);
+    }
+
+}
+
diff --git a/awt/java/awt/Rectangle.java b/awt/java/awt/Rectangle.java
new file mode 100644
index 0000000..86c4dfc
--- /dev/null
+++ b/awt/java/awt/Rectangle.java
@@ -0,0 +1,686 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+
+/**
+ * The Rectangle class defines the rectangular area in terms of its
+ * upper left corner coordinates [x,y], its width, and its height.  
+ * A Rectangle specified by [x, y, width, height] parameters has an 
+ * outline path with corners at [x, y], [x + width,y], [x + width,y + height], 
+ * and [x, y + height]. 
+ * <br><br>
+ * The rectangle is empty if the width or height is negative or zero. 
+ * In this case the isEmpty method returns true.
+ */
+public class Rectangle extends Rectangle2D implements Shape, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4345857070255674764L;
+
+    /** The X coordinate of the rectangle's left upper corner. */
+    public int x;
+    
+    /** The Y coordinate of the rectangle's left upper corner. */
+    public int y;
+    
+    /** The width of rectangle. */
+    public int width;
+    
+    /** The height of rectangle. */
+    public int height;
+
+    /**
+     * Instantiates a new rectangle with [0, 0] upper left corner coordinates,
+     * the width and the height are zero.
+     */
+    public Rectangle() {
+        setBounds(0, 0, 0, 0);
+    }
+
+    /**
+     * Instantiates a new rectangle whose upper left corner coordinates are
+     * given by the Point object (p.X and p.Y), and the width and 
+     * the height are zero. 
+     * 
+     * @param p the Point specifies the upper left corner coordinates of 
+     * the rectangle.
+     */
+    public Rectangle(Point p) {
+        setBounds(p.x, p.y, 0, 0);
+    }
+
+    /**
+      * Instantiates a new rectangle whose upper left corner coordinates are
+     * given by the Point object (p.X and p.Y), and the width and the height
+     * are given by Dimension object (d.width and d.height). 
+     * 
+     * @param p the Point specifies the upper left corner coordinates of 
+     * the rectangle.
+     * @param d the Dimention specifies the width and the height of the rectangle. 
+     */
+    public Rectangle(Point p, Dimension d) {
+        setBounds(p.x, p.y, d.width, d.height);
+    }
+
+    /**
+     * Instantiates a new rectangle determined by the upper left corner 
+     * coordinates (x, y), width and height.
+     * 
+     * @param x the X upper left corner coordinate of the rectangle.
+     * @param y the Y upper left corner coordinate of the rectangle.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle. 
+     */
+    public Rectangle(int x, int y, int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Instantiates a new rectangle with [0, 0] as its upper left 
+     * corner coordinates and the specified width and height.
+     * 
+     * @param width the width of rectangle.
+     * @param height the height of rectangle. 
+     */
+    public Rectangle(int width, int height) {
+        setBounds(0, 0, width, height);
+    }
+
+    /**
+     * Instantiates a new rectangle with the same coordinates 
+     * as the given source rectangle.
+     * 
+     * @param r the Rectangle object which parameters will be used for 
+     * instantiating a new Rectangle.
+     */
+    public Rectangle(Rectangle r) {
+        setBounds(r.x, r.y, r.width, r.height);
+    }
+/*
+    public Rectangle(Dimension d) {
+        setBounds(0, 0, d.width, d.height);
+    }
+*/
+    /**
+     * Gets the X coordinate of bound as a double.
+     * 
+     * @return the X coordinate of bound as a double.
+     *   
+     * @see java.awt.geom.RectangularShape#getX()
+     */
+    @Override
+    public double getX() {
+        return x;
+    }
+
+    /**
+     * Gets the Y coordinate of bound as a double.
+     * 
+     * @return the Y coordinate of bound as a double.
+     * 
+     * @see java.awt.geom.RectangularShape#getY()
+     */
+    @Override
+    public double getY() {
+        return y;
+    }
+
+    /**
+     * Gets the height of the rectangle as a double.
+     * 
+     * @return the height of the rectangle as a double. 
+     * 
+     * @see java.awt.geom.RectangularShape#getHeight()
+     */
+    @Override
+    public double getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the width of the rectangle as a double.
+     * 
+     * @return the width of the rectangle as a double.
+     *  
+     * @see java.awt.geom.RectangularShape#getWidth()
+     */
+    @Override
+    public double getWidth() {
+        return width;
+    }
+
+    /**
+     * Determines whether or not the rectangle is empty. The rectangle is empty if 
+     * its width or height is negative or zero.
+     * 
+     * @return true, if the rectangle is empty, otherwise false.
+     * 
+     * @see java.awt.geom.RectangularShape#isEmpty()
+     */
+    @Override
+    public boolean isEmpty() {
+        return width <= 0 || height <= 0;
+    }
+
+    /**
+     * Gets the size of a Rectangle as Dimention object.
+     * 
+     * @return a Dimention object which represents size of the rectangle.
+     */
+    public Dimension getSize() {
+        return new Dimension(width, height);
+    }
+
+    /**
+     * Sets the size of the Rectangle.
+     * 
+     * @param width the new width of the rectangle. 
+     * @param height the new height of the rectangle.
+     */
+    public void setSize(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+
+    /**
+     * Sets the size of a Rectangle specified as Dimension object.
+     * 
+     * @param d a Dimension object which represents new size of a rectangle.
+     */
+    public void setSize(Dimension d) {
+        setSize(d.width, d.height);
+    }
+
+    /**
+     * Gets the location of a rectangle's upper left corner as a Point object.
+     * 
+     * @return the Point object with coordinates equal to the upper left corner 
+     * of the rectangle.
+     */
+    public Point getLocation() {
+        return new Point(x, y);
+    }
+
+    /**
+     * Sets the location of the rectangle in terms of its upper left 
+     * corner coordinates X and Y.
+     * 
+     * @param x the X coordinate of the rectangle's upper left corner.
+     * @param y the Y coordinate of the rectangle's upper left corner.
+     */
+    public void setLocation(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Sets the location of a rectangle using a Point object to give the 
+     * coordinates of the upper left corner.
+     * 
+     * @param p the Point object which represents the new upper left corner 
+     * coordinates of rectangle.  
+     */
+    public void setLocation(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Moves a rectangle to the new location by moving its upper left corner
+     * to the point with coordinates X and Y.
+     * 
+     * @param x the new X coordinate of the rectangle's upper left corner.
+     * @param y the new Y coordinate of the rectangle's upper left corner.
+     * 
+     * @deprecated Use setLocation(int, int) method.
+     */
+    @Deprecated
+    public void move(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Sets the rectangle to be the nearest rectangle with integer coordinates 
+     * bounding the rectangle defined by the double-valued parameters.
+     * 
+     * @param x the X coordinate of the upper left corner of the double-valued
+     * rectangle to be bounded.
+     * @param y the Y coordinate of the upper left corner of the double-valued
+     * rectangle to be bounded.
+     * @param width the width of the rectangle to be bounded.
+     * @param height the height of the rectangle to be bounded.      
+     * 
+     * @see java.awt.geom.Rectangle2D#setRect(double, double, double, double)
+     */
+    @Override
+    public void setRect(double x, double y, double width, double height) {
+        int x1 = (int)Math.floor(x);
+        int y1 = (int)Math.floor(y);
+        int x2 = (int)Math.ceil(x + width);
+        int y2 = (int)Math.ceil(y + height);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Sets a new size for the rectangle.
+     * 
+     * @param width the rectangle's new width.
+     * @param height the rectangle's new height.
+     * 
+     * @deprecated use the setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Resets the bounds of a rectangle to the specified x, y, width and height 
+     * parameters.
+     * 
+     * @param x the new X coordinate of the upper left corner.
+     * @param y the new Y coordinate of the upper left corner.
+     * @param width the new width of rectangle.
+     * @param height the new height of rectangle. 
+     * 
+     * @deprecated use setBounds(int, int, int, int) method
+     */
+    @Deprecated
+    public void reshape(int x, int y, int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Gets bounds of the rectangle as a new Rectangle object.
+     *  
+     * @return the Rectangle object with the same bounds as 
+     * the original rectangle. 
+     * 
+     * @see java.awt.geom.RectangularShape#getBounds()
+     */
+    @Override
+    public Rectangle getBounds() {
+        return new Rectangle(x, y, width, height);
+    }
+
+    /**
+     * Gets the bounds of the original rectangle as a Rectangle2D object.
+     *  
+     * @return the Rectangle2D object which represents the bounds of 
+     * the original rectangle. 
+     * 
+     * @see java.awt.geom.Rectangle2D#getBounds2D()
+     */
+    @Override
+    public Rectangle2D getBounds2D() {
+        return getBounds();
+    }
+
+    /**
+     * Sets the bounds of a rectangle to the specified x, y, width, and height 
+     * parameters.
+     * 
+     * @param x the X coordinate of the upper left corner.
+     * @param y the Y coordinate of the upper left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle. 
+     */
+    public void setBounds(int x, int y, int width, int height) {
+        this.x = x;
+        this.y = y;
+        this.height = height;
+        this.width = width;
+    }
+
+    /**
+     * Sets the bounds of the rectangle to match the bounds of the
+     * Rectangle object sent as a parameter.
+     * 
+     * @param r the Rectangle object which specifies the new bounds. 
+     */
+    public void setBounds(Rectangle r) {
+        setBounds(r.x, r.y, r.width, r.height);
+    }
+
+    /**
+     * Enlarges the rectangle by moving each corner outward from the 
+     * center by a distance of dx horizonally and a distance of dy 
+     * vertically. Specifically, changes a rectangle with 
+     * [x, y, width, height] parameters to 
+     * a rectangle with [x-dx, y-dy, width+2*dx, height+2*dy]
+     * parameters. 
+     *   
+     * @param dx the horizontal distance to move each corner coordinate.
+     * @param dy the vertical distance to move each corner coordinate.
+     */
+    public void grow(int dx, int dy) {
+        x -= dx;
+        y -= dy;
+        width += dx + dx;
+        height += dy + dy;
+    }
+
+    /**
+     * Moves a rectangle a distance of mx along the x coordinate axis 
+     * and a distance of my along y coordinate axis.
+     * 
+     * @param mx the horizontal translation increment.
+     * @param my the vertical translation increment.
+     */
+    public void translate(int mx, int my) {
+        x += mx;
+        y += my;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified point.
+     * 
+     * @param px the X coordinate of the new point to be covered by the rectangle.
+     * @param py the Y coordinate of the new point to be covered by the rectangle.
+     */
+    public void add(int px, int py) {
+        int x1 = Math.min(x, px);
+        int x2 = Math.max(x + width, px);
+        int y1 = Math.min(y, py);
+        int y2 = Math.max(y + height, py);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified point with the
+     * new point given as a Point object.
+     * 
+     * @param p the Point object that specifies the new point to 
+     * be covered by the rectangle.
+     */
+    public void add(Point p) {
+        add(p.x, p.y);
+    }
+
+    /**
+     * Adds a new rectangle to the original rectangle, the result is an union of
+     * the specified specified rectangle and original rectangle.
+     * 
+     * @param r the Rectangle which is added to the original rectangle. 
+     */
+    public void add(Rectangle r) {
+        int x1 = Math.min(x, r.x);
+        int x2 = Math.max(x + width, r.x + r.width);
+        int y1 = Math.min(y, r.y);
+        int y2 = Math.max(y + height, r.y + r.height);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Determines whether or not the point with specified coordinates [px, py] 
+     * is within the bounds of the rectangle.
+     * 
+     * @param px the X coordinate of point.
+     * @param py the Y coordinate of point.
+     * 
+     * @return true, if the point with specified coordinates [px, py] is 
+     * within the bounds of the rectangle, otherwise false.
+     */
+    public boolean contains(int px, int py) {
+        if (isEmpty()) {
+            return false;
+        }
+        if (px < x || py < y) {
+            return false;
+        }
+        px -= x;
+        py -= y;
+        return px < width && py < height;
+    }
+
+    /**
+     * Determines whether or not the point given as a Point object 
+     * is within the bounds of the rectangle.
+     * 
+     * @param p the Point object
+     * 
+     * @return true, if the point p is within the bounds of the 
+     * rectangle, otherwise false.
+     */
+    public boolean contains(Point p) {
+        return contains(p.x, p.y);
+    }
+
+    /**
+     * Determines whether or not the rectangle specified by [rx, ry, rw, rh] 
+     * parameters is located inside the original rectangle.
+     * 
+     * @param rx the X coordinate of the rectangle to compare.
+     * @param ry the Y coordinate of the rectangle to compare.
+     * @param rw the width of the rectangle to compare.
+     * @param rh the height of the rectangle to compare.
+     * 
+     * @return true, if a rectangle with [rx, ry, rw, rh] parameters is entirely
+     * contained in the original rectangle, otherwise false.
+     */
+    public boolean contains(int rx, int ry, int rw, int rh) {
+        return contains(rx, ry) && contains(rx + rw - 1, ry + rh - 1);
+    }
+
+    /**
+     * Compares whether or not the rectangle specified by the Rectangle object
+     * is located inside the original rectangle.
+     * 
+     * @param r the Rectangle object.
+     * 
+     * @return true, if the rectangle specified by Rectangle object is entirely
+     * contained in the original rectangle, otherwise false.
+     */
+    public boolean contains(Rectangle r) {
+        return contains(r.x, r.y, r.width, r.height);
+    }
+
+    /**
+     * Compares whether or not a point with specified coordinates [px, py] belongs 
+     * to a rectangle.
+     * 
+     * @param px the X coordinate of a point.
+     * @param py the Y coordinate of a point.
+     * 
+     * @return true, if a point with specified coordinates [px, py] belongs 
+     * to a rectangle, otherwise false.
+     * 
+     * @deprecated use contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int px, int py) {
+        return contains(px, py);
+    }
+
+    /**
+     * Returns the intersection of the original rectangle with the 
+     * specified Rectangle2D.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return the Rectangle2D object that is the result of intersecting 
+     * the original rectangle with the specified Rectangle2D.
+     * 
+     * @see java.awt.geom.Rectangle2D#createIntersection(java.awt.geom.Rectangle2D)
+     */
+    @Override
+    public Rectangle2D createIntersection(Rectangle2D r) {
+        if (r instanceof Rectangle) {
+            return intersection((Rectangle) r);
+        }
+        Rectangle2D dst = new Rectangle2D.Double();
+        Rectangle2D.intersect(this, r, dst);
+        return dst;
+    }
+
+    /**
+     * Returns the intersection of the original rectangle with the 
+     * specified rectangle. An empty rectangle is returned if there is no
+     * intersection.
+     * 
+     * @param r the Rectangle object.
+     * 
+     * @return the Rectangle object is result of the original rectangle with the 
+     * specified rectangle. 
+     */
+    public Rectangle intersection(Rectangle r) {
+        int x1 = Math.max(x, r.x);
+        int y1 = Math.max(y, r.y);
+        int x2 = Math.min(x + width, r.x + r.width);
+        int y2 = Math.min(y + height, r.y + r.height);
+        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Determines whether or not the original rectangle intersects 
+     * the specified rectangle.
+     * 
+     * @param r the Rectangle object.
+     * 
+     * @return true, if the two rectangles overlap; otherwise false.
+     */
+    public boolean intersects(Rectangle r) {
+        return !intersection(r).isEmpty();
+    }
+
+    /**
+     * Determines where the specified Point is located with respect to 
+     * the rectangle. This method computes whether the point is to the 
+     * right or to the left of the rectangle and whether it is above 
+     * or below the rectangle, and packs the result into an int by 
+     * using a binary OR operation with the following masks:
+     * <ul>
+     *<li>Rectangle2D.OUT_LEFT</li>
+     *<li>Rectangle2D.OUT_TOP</li>
+     *<li>Rectangle2D.OUT_RIGHT</li>
+     *<li>Rectangle2D.OUT_BOTTOM</li>
+     *</ul>
+     *
+     * If the rectangle is empty, all masks are set, and if the 
+     * point is inside the rectangle, none are set.
+     * 
+     * @param px the X coordinate of the specified point.
+     * @param py the Y coordinate of the specified point.
+     * 
+     * @return the location of the Point relative to the rectangle 
+     * as the result of logical OR operation with all out masks.
+     * 
+     * @see java.awt.geom.Rectangle2D#outcode(double, double)
+     */
+    @Override
+    public int outcode(double px, double py) {
+        int code = 0;
+
+        if (width <= 0) {
+            code |= OUT_LEFT | OUT_RIGHT;
+        } else
+            if (px < x) {
+                code |= OUT_LEFT;
+            } else
+                if (px > x + width) {
+                    code |= OUT_RIGHT;
+                }
+
+        if (height <= 0) {
+            code |= OUT_TOP | OUT_BOTTOM;
+        } else
+            if (py < y) {
+                code |= OUT_TOP;
+            } else
+                if (py > y + height) {
+                    code |= OUT_BOTTOM;
+                }
+
+        return code;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified Rectangle2D.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return the union of the original and the specified Rectangle2D.
+     * 
+     * @see java.awt.geom.Rectangle2D#createUnion(java.awt.geom.Rectangle2D)
+     */
+    @Override
+    public Rectangle2D createUnion(Rectangle2D r) {
+        if (r instanceof Rectangle) {
+            return union((Rectangle)r);
+        }
+        Rectangle2D dst = new Rectangle2D.Double();
+        Rectangle2D.union(this, r, dst);
+        return dst;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified rectangle.
+     * 
+     * @param r the Rectangle.
+     * 
+     * @return the union of the original and the specified rectangle.
+     */
+    public Rectangle union(Rectangle r) {
+        Rectangle dst = new Rectangle(this);
+        dst.add(r);
+        return dst;
+    }
+
+    /**
+     * Compares the original Rectangle with the specified object.
+     * 
+     * @param obj the specified Object for comparison.
+     * 
+     * @return true, if the specified Object is a rectangle with the 
+     * same dimensions as the original rectangle, otherwise false.
+     * 
+     * @see java.awt.geom.Rectangle2D#equals(Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Rectangle) {
+            Rectangle r = (Rectangle)obj;
+            return r.x == x && r.y == y && r.width == width && r.height == height;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of the rectangle; the string contains 
+     * [x, y, width, height] parameters of the rectangle.
+     * 
+     * @return the string representation of the rectangle.
+     */
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. It could be obtained in the following way
+        // System.out.println(new Rectangle().toString())
+        return getClass().getName() + "[x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$
+            ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+}
+
diff --git a/awt/java/awt/RenderingHints.java b/awt/java/awt/RenderingHints.java
new file mode 100644
index 0000000..4957884
--- /dev/null
+++ b/awt/java/awt/RenderingHints.java
@@ -0,0 +1,601 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The RenderingHints class represents preferences for the rendering algorithms. 
+ * The preferences are arbitrary and can be specified by Map objects or by 
+ * key-value pairs. 
+ */
+public class RenderingHints implements Map<Object, Object>, Cloneable {
+    
+    /**
+     * The Constant KEY_ALPHA_INTERPOLATION - alpha interpolation rendering 
+     * hint key. 
+     */
+    public static final Key KEY_ALPHA_INTERPOLATION = new KeyImpl(1);
+    
+    /** 
+     * The Constant VALUE_ALPHA_INTERPOLATION_DEFAULT - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT = new KeyValue(KEY_ALPHA_INTERPOLATION);
+    
+    /** 
+     * The Constant VALUE_ALPHA_INTERPOLATION_SPEED - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_SPEED = new KeyValue(KEY_ALPHA_INTERPOLATION);
+    
+    /** 
+     * The Constant VALUE_ALPHA_INTERPOLATION_QUALITY - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY = new KeyValue(KEY_ALPHA_INTERPOLATION);
+
+    /** 
+     * The Constant KEY_ANTIALIASING - antialiasing rendering 
+     * hint key. 
+     */
+    public static final Key KEY_ANTIALIASING = new KeyImpl(2);
+    
+    /**
+     * The Constant VALUE_ANTIALIAS_DEFAULT - antialiasing
+     * rendering hint value. 
+     */
+    public static final Object VALUE_ANTIALIAS_DEFAULT = new KeyValue(KEY_ANTIALIASING);
+    
+    /** 
+     * The Constant VALUE_ANTIALIAS_ON - antialiasing
+     * rendering hint value.
+     */
+    public static final Object VALUE_ANTIALIAS_ON = new KeyValue(KEY_ANTIALIASING);
+    
+    /**
+     * The Constant VALUE_ANTIALIAS_OFF - antialiasing
+     * rendering hint value.
+     */
+    public static final Object VALUE_ANTIALIAS_OFF = new KeyValue(KEY_ANTIALIASING);
+
+    /** 
+     * The Constant KEY_COLOR_RENDERING  - color rendering 
+     * hint key.
+     */
+    public static final Key KEY_COLOR_RENDERING = new KeyImpl(3);
+    
+    /**
+     * The Constant VALUE_COLOR_RENDER_DEFAULT - color
+     * rendering hint value. 
+     */
+    public static final Object VALUE_COLOR_RENDER_DEFAULT = new KeyValue(KEY_COLOR_RENDERING);
+    
+    /** 
+     * The Constant VALUE_COLOR_RENDER_SPEED  - color
+     * rendering hint value. 
+     */
+    public static final Object VALUE_COLOR_RENDER_SPEED = new KeyValue(KEY_COLOR_RENDERING);
+    
+    /** 
+     * The Constant VALUE_COLOR_RENDER_QUALITY - color
+     * rendering hint value.
+     */
+    public static final Object VALUE_COLOR_RENDER_QUALITY = new KeyValue(KEY_COLOR_RENDERING);
+
+    /**
+     *  The Constant KEY_DITHERING  - dithering
+     * rendering hint key.
+     */
+    public static final Key KEY_DITHERING = new KeyImpl(4);
+    
+    /**
+     * The Constant VALUE_DITHER_DEFAULT - dithering
+     * rendering hint value.
+     */
+    public static final Object VALUE_DITHER_DEFAULT = new KeyValue(KEY_DITHERING);
+    
+    /** 
+     * The Constant VALUE_DITHER_DISABLE - dithering
+     * rendering hint value.
+     */
+    public static final Object VALUE_DITHER_DISABLE = new KeyValue(KEY_DITHERING);
+    
+    /** 
+     * The Constant VALUE_DITHER_DISABLE - dithering
+     * rendering hint value.
+     */
+    public static final Object VALUE_DITHER_ENABLE = new KeyValue(KEY_DITHERING);
+
+    /** 
+     * The Constant KEY_FRACTIONALMETRICS - fractional metrics
+     * rendering hint key.
+     */
+    public static final Key KEY_FRACTIONALMETRICS = new KeyImpl(5);
+    
+    /**
+     * The Constant VALUE_FRACTIONALMETRICS_DEFAULT - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_DEFAULT = new KeyValue(KEY_FRACTIONALMETRICS);
+    
+    /**
+     * The Constant VALUE_FRACTIONALMETRICS_ON - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_ON = new KeyValue(KEY_FRACTIONALMETRICS);
+    
+    /**
+     *  The Constant VALUE_FRACTIONALMETRICS_OFF - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_OFF = new KeyValue(KEY_FRACTIONALMETRICS);
+
+    /** 
+     * The Constant KEY_INTERPOLATION - interpolation
+     * rendering hint key.
+     */
+    public static final Key KEY_INTERPOLATION = new KeyImpl(6);
+    
+    /** 
+     * The Constant VALUE_INTERPOLATION_BICUBIC - interpolation
+     * rendering hint value. 
+     */
+    public static final Object VALUE_INTERPOLATION_BICUBIC = new KeyValue(KEY_INTERPOLATION);
+    
+    /**
+     * The Constant VALUE_INTERPOLATION_BILINEAR - interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_INTERPOLATION_BILINEAR = new KeyValue(KEY_INTERPOLATION);
+    
+    /** The Constant VALUE_INTERPOLATION_NEAREST_NEIGHBOR - interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR = new KeyValue(KEY_INTERPOLATION);
+
+    /**
+     * The Constant KEY_RENDERING - rendering hint key.
+     */
+    public static final Key KEY_RENDERING = new KeyImpl(7);
+    
+    /** 
+     * The Constant VALUE_RENDER_DEFAULT - rendering hint value. 
+     */
+    public static final Object VALUE_RENDER_DEFAULT = new KeyValue(KEY_RENDERING);
+    
+    /** 
+     * The Constant VALUE_RENDER_SPEED - rendering hint value. 
+     */
+    public static final Object VALUE_RENDER_SPEED = new KeyValue(KEY_RENDERING);
+    
+    /** 
+     * The Constant VALUE_RENDER_QUALITY - rendering hint value. 
+     */
+    public static final Object VALUE_RENDER_QUALITY = new KeyValue(KEY_RENDERING);
+
+    /** 
+     * The Constant KEY_STROKE_CONTROL - stroke control hint key. 
+     */
+    public static final Key KEY_STROKE_CONTROL = new KeyImpl(8);
+    
+    /** 
+     * The Constant VALUE_STROKE_DEFAULT - stroke hint value. 
+     */
+    public static final Object VALUE_STROKE_DEFAULT = new KeyValue(KEY_STROKE_CONTROL);
+    
+    /** 
+     * The Constant VALUE_STROKE_NORMALIZE - stroke hint value. 
+     */
+    public static final Object VALUE_STROKE_NORMALIZE = new KeyValue(KEY_STROKE_CONTROL);
+    
+    /** 
+     * The Constant VALUE_STROKE_PURE - stroke hint value. 
+     */
+    public static final Object VALUE_STROKE_PURE = new KeyValue(KEY_STROKE_CONTROL);
+
+    /** 
+     * The Constant KEY_TEXT_ANTIALIASING - text antialiasing hint key. 
+     */
+    public static final Key KEY_TEXT_ANTIALIASING = new KeyImpl(9);
+    
+    /**
+     *  The Constant VALUE_TEXT_ANTIALIAS_DEFAULT - text antialiasing hint key. 
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT = new KeyValue(KEY_TEXT_ANTIALIASING);
+    
+    /**
+     * The Constant VALUE_TEXT_ANTIALIAS_ON - text antialiasing hint key.
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_ON = new KeyValue(KEY_TEXT_ANTIALIASING);
+    
+    /**
+     * The Constant VALUE_TEXT_ANTIALIAS_OFF - text antialiasing hint key. 
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_OFF = new KeyValue(KEY_TEXT_ANTIALIASING);
+
+    /** The map. */
+    private HashMap<Object, Object> map = new HashMap<Object, Object>();
+    
+    /**
+     * Instantiates a new rendering hints object from specified Map object with defined
+     * key/value pairs or null for empty RenderingHints. 
+     * 
+     * @param map the Map object with defined key/value pairs or null for
+     * empty RenderingHints. 
+     */
+    public RenderingHints(Map<Key, ?> map) {
+        super();
+        if (map != null) {
+            putAll(map);
+        }
+    }
+
+    /**
+     * Instantiates a new rendering hints object with the specified key/value pair.
+     * 
+     * @param key the key of hint property.
+     * @param value the value of hint property.
+     */
+    public RenderingHints(Key key, Object value) {
+        super();
+        put(key, value);
+    }
+
+    /**
+     * Adds the properties represented by key/value pairs from the specified
+     * RenderingHints object to current object.
+     * 
+     * @param hints the RenderingHints to be added.
+     */
+    public void add(RenderingHints hints) {
+        map.putAll(hints.map);
+    }
+
+    /**
+     * Puts the specified value to the specified key. Neither the key nor 
+     * the value can be null.
+     * 
+     * @param key the rendering hint key.
+     * @param value the rendering hint value. 
+     * 
+     * @return the previous rendering hint value assigned to the key or null.
+     * 
+     */
+    public Object put(Object key, Object value) {
+        if (!((Key)key).isCompatibleValue(value)) {
+            throw new IllegalArgumentException();
+        }
+
+        return map.put(key, value);
+    }
+
+    /**
+     * Removes the specified key and corresponding value from 
+     * the RenderingHints object.
+     * 
+     * @param key the specified hint key to be removed.
+     * 
+     * @return the object of previous rendering hint value which is 
+     * assigned to the specified key, or null.
+     */
+    public Object remove(Object key) {
+        return map.remove(key);
+    }
+
+    /**
+     * Gets the value assigned to the specified key.
+     * 
+     * @param key the rendering hint key.
+     * 
+     * @return the object assigned to the specified key.
+     */
+    public Object get(Object key) {
+        return map.get(key);
+    }
+
+    /**
+     * Returns a set of rendering hints keys for current RenderingHints object.
+     * 
+     * @return the set of rendering hints keys. 
+     */
+    public Set<Object> keySet() {
+        return map.keySet();
+    }
+
+    /**
+     * Returns a set of Map.Entry objects which contain current RenderingHint
+     * key/value pairs.
+     * 
+     * @return the a set of mapped RenderingHint key/value pairs.
+     */
+    public Set<Map.Entry<Object, Object>> entrySet() {
+        return map.entrySet();
+    }
+
+    /**
+     * Puts all of the preferences from the specified Map into 
+     * the current RenderingHints object. These mappings replace 
+     * all existing preferences.
+     * 
+     * @param m the specified Map of preferences.
+     */
+    public void putAll(Map<?, ?> m) {
+        if (m instanceof RenderingHints) {
+            map.putAll(((RenderingHints) m).map);
+        } else {
+            Set<?> entries = m.entrySet();
+
+            if (entries != null){
+                Iterator<?> it = entries.iterator();
+                while (it.hasNext()) {
+                    Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();
+                    Key key = (Key) entry.getKey();
+                    Object val = entry.getValue();
+                    put(key, val);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a Collection of values contained in current RenderingHints object.
+     * 
+     * @return the Collection of RenderingHints's values.
+     */
+    public Collection<Object> values() {
+        return map.values();
+    }
+
+    /**
+     * Checks whether or not current RenderingHints object contains at least one
+     * the value which is equal to the specified Object.
+     * 
+     * @param value the specified Object.
+     * 
+     * @return true, if the specified object is assigned to at least one
+     * RenderingHint's key, false otherwise.
+     */
+    public boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    /**
+     * Checks whether or not current RenderingHints object contains the key
+     * which is equal to the specified Object.
+     * 
+     * @param key the specified Object.
+     * 
+     * @return true, if the RenderingHints object contains the specified Object
+     * as a key, false otherwise.
+     * 
+     */
+    public boolean containsKey(Object key) {
+        if (key == null) {
+            throw new NullPointerException();
+        }
+
+        return map.containsKey(key);
+    }
+
+    /**
+     * Checks whether or not the RenderingHints object contains any 
+     * key/value pairs.
+     * 
+     * @return true, if the RenderingHints object is empty, false otherwise.
+     */
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    /**
+     * Clears the RenderingHints of all key/value pairs.
+     */
+    public void clear() {
+        map.clear();
+    }
+
+    /**
+     * Returns the number of key/value pairs in the RenderingHints.
+     * 
+     * @return the number of key/value pairs.
+     */
+    public int size() {
+        return map.size();
+    }
+
+    /**
+     * Compares the RenderingHints object with the specified object.
+     * 
+     * @param o the specified Object to be compaired.
+     * 
+     * @return true, if the Object is a Map whose key/value pairs 
+     * match this RenderingHints' key/value pairs, 
+     * false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Map)) {
+            return false;
+        }
+
+        Map<?, ?> m = (Map<?, ?>)o;
+        Set<?> keys = keySet();
+        if (!keys.equals(m.keySet())) {
+            return false;
+        }
+
+        Iterator<?> it = keys.iterator();
+        while (it.hasNext()) {
+            Key key = (Key)it.next();
+            Object v1 = get(key);
+            Object v2 = m.get(key);
+            if (!(v1==null?v2==null:v1.equals(v2))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the hash code for this RenderingHints object.
+     * 
+     * @return the hash code for this RenderingHints object.
+     */
+    @Override
+    public int hashCode() {
+        return map.hashCode();
+    }
+
+    /**
+     * Returns the clone of the RenderingHints object with the same contents.
+     * 
+     * @return the clone of the RenderingHints instance.
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object clone() {
+        RenderingHints clone = new RenderingHints(null);
+        clone.map = (HashMap<Object, Object>)this.map.clone();
+        return clone;
+    }
+
+    /**
+     * Returns the string representation of the RenderingHints object.
+     * 
+     * @return the String object which represents RenderingHints object. 
+     */
+    @Override
+    public String toString() {
+        return "RenderingHints["+map.toString()+"]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * The RenderingHints.Key class is abstract and defines a base type for 
+     * all RenderingHints keys.
+     */
+    public abstract static class Key {
+        
+        /** The key. */
+        private final int key;
+
+        /**
+         * Instantiates a new key with unique int identifier. 
+         * No two objects of the same subclass with the same integer key
+         * can be instantiated. 
+         * 
+         * @param key the unique key.
+         */
+        protected Key(int key) {
+            this.key = key;
+        }
+
+        /**
+         * Compares the Key object with the specified object.
+         * 
+         * @param o the specified Object to be compaired.
+         * 
+         * @return true, if the Key is equal to the specified object, 
+         * false otherwise.
+         */
+        @Override
+        public final boolean equals(Object o) {
+            return this == o;
+        }
+
+        /**
+         * Returns the hash code for this Key object.
+         * 
+         * @return the hash code for this Key object.
+         */
+        @Override
+        public final int hashCode() {
+            return System.identityHashCode(this);
+        }
+
+        /**
+         * Returns int unique key with which this Key object has been 
+         * instantiated.
+         * 
+         * @return the int unique key with which this Key object has been 
+         * instantiated.
+         */
+        protected final int intKey() {
+            return key;
+        }
+
+        /**
+         * Checks whether or not specified value is compatible with the Key.
+         * 
+         * @param val the Object.
+         * 
+         * @return true, if the specified value is compatible with the Key,
+         * false otherwise.
+         */
+        public abstract boolean isCompatibleValue(Object val);
+    }
+
+    /**
+     * Private implementation of Key class.
+     */
+    private static class KeyImpl extends Key {
+
+        /**
+         * Instantiates a new key impl.
+         * 
+         * @param key the key
+         */
+        protected KeyImpl(int key) {
+            super(key);
+        }
+
+        @Override
+        public boolean isCompatibleValue(Object val) {
+            if (!(val instanceof KeyValue)) {
+                return false;
+            }
+
+            return ((KeyValue)val).key == this;
+        }
+    }
+
+    /**
+     * Private class KeyValue is used as value for Key class instance.
+     */
+    private static class KeyValue {
+        
+        /** The key. */
+        private final Key key;
+
+        /**
+         * Instantiates a new key value.
+         * 
+         * @param key the key
+         */
+        protected KeyValue(Key key) {
+            this.key = key;
+        }
+    }
+}
diff --git a/awt/java/awt/Shape.java b/awt/java/awt/Shape.java
new file mode 100644
index 0000000..3dbad25
--- /dev/null
+++ b/awt/java/awt/Shape.java
@@ -0,0 +1,162 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The Shape interface defines a geometric shape defined by a boundary 
+ * (outline) path. The path outline can be accessed through a 
+ * PathIterator object. The Shape 
+ * interface provides methods for obtaining the bounding box (which is 
+ * the smallest rectangle containing the shape and for obtaining a PathIterator 
+ * object for current Shape, as well as utility methods which 
+ * determine if the Shape contains or intersects a Rectangle or contains a Point.
+ */
+public interface Shape {
+    
+    /**
+     * Checks whether or not the point with specified coordinates lies inside 
+     * the Shape.
+     * 
+     * @param x the X coordinate.
+     * @param y the Y coordinate.
+     * 
+     * @return true, if the specified coordinates lie inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(double x, double y);
+
+    /**
+     * Checks whether or not the rectangle with specified 
+     * [x, y, width, height] parameters lies inside the Shape.
+     * 
+     * @param x the X double coordinate of the rectangle's upper left 
+     * corner.
+     * @param y the Y double coordinate of the rectangle's upper left 
+     * corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle.
+     * 
+     * @return true, if the specified rectangle lies inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(double x, double y, double w, double h);
+
+    /**
+     * Checks whether or not the specified Point2D lies inside the Shape.
+     * 
+     * @param point the Point2D object.
+     * 
+     * @return true, if the specified Point2D lies inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(Point2D point);
+
+    /**
+     * Checks whether or not the specified rectangle lies inside the Shape.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return true, if the specified rectangle lies inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(Rectangle2D r);
+
+    /**
+     * Gets the bounding rectangle of the Shape. The bounding rectangle
+     * is the smallest rectangle which contains the Shape.
+     * 
+     * @return the bounding rectangle of the Shape.
+     */
+    public Rectangle getBounds();
+
+    /**
+     * Gets the Rectangle2D which represents Shape bounds.
+     * The bounding rectangle is the smallest rectangle which contains 
+     * the Shape.
+     * 
+     * @return the bounding rectangle of the Shape.
+     */
+    public Rectangle2D getBounds2D();
+
+    /**
+     * Gets the PathIterator object of the Shape which provides 
+     * access to the shape's boundary modified 
+     * by the specified AffineTransform.
+     * 
+     * @param at the specified AffineTransform object, or null.
+     * 
+     * @return PathIterator object for the Shape.
+     */
+    public PathIterator getPathIterator(AffineTransform at);
+
+    /**
+     * Gets the PathIterator object of the Shape which provides 
+     * access to the coordinates of the shapes boundary modified 
+     * by the specified AffineTransform. The flatness parameter
+     * defines the amount of subdivision of the curved segments and
+     * specifies the maximum distance which every point on the 
+     * unflattened transformed curve can deviate from the returned 
+     * flattened path segments.  
+     * 
+     * @param at the specified AffineTransform object, or null.
+     * @param flatness the maximum number of the control points for 
+     * a given curve which varies from colinear before a subdivided 
+     * curve is replaced by a straight line connecting the endpoints. 
+     * 
+     * @return PathIterator object for the Shape.
+     */
+    public PathIterator getPathIterator(AffineTransform at, double flatness);
+
+    /**
+     * Checks whether or not the interior of rectangular specified by 
+     * [x, y, width, height] parameters intersects the interior of
+     * the Shape.
+     * 
+     * @param x the X double coordinate of the rectangle's upper left
+     * corner.
+     * @param y the Y double coordinate of the rectangle's upper left 
+     * corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle.
+     * 
+     * @return true, if the rectangle specified by 
+     * [x, y, width, height] parameters intersects the interior of
+     * the Shape, otherwise false.
+     * 
+     */
+    public boolean intersects(double x, double y, double w, double h);
+
+    /**
+     * Checks whether or not the interior of rectangl specified by 
+     * Rectangle2D object intersects the interior of the Shape.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return true, if the Rectangle2D intersects the interior of
+     * the Shape, otherwise false.
+     */
+    public boolean intersects(Rectangle2D r);
+}
diff --git a/awt/java/awt/Stroke.java b/awt/java/awt/Stroke.java
new file mode 100644
index 0000000..e6d683d
--- /dev/null
+++ b/awt/java/awt/Stroke.java
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The Stroke interface gives a pen style to be used by the 
+ * Graphics2D interface. It provides a means for getting a stroked version 
+ * of a shape, which is the version that is suitable for drawing via 
+ * the Graphics2D interface. Stroking a shape gives the shape's outline
+ * a width or drawing style. 
+ * <p>
+ * The Draw methods from Graphics2D interface should use the Stroke object for 
+ * rendering the shape's outline. The stroke should be set by 
+ * setStroke(java.awt.Stroke) method of the Graphics2D interface. 
+ * @see java.awt.Graphics2D#setStroke(java.awt.Stroke)
+ */
+public interface Stroke {
+    
+    /**
+     * Creates the stroked shape, which is the version that is suitable for drawing via 
+     * the Graphics2D interface. Stroking a shape gives the shape's outline
+     * a width or drawing style.
+     * 
+     * @param p the original shape.
+     * 
+     * @return the stroked shape.
+     */
+    public Shape createStrokedShape(Shape p);
+}
diff --git a/awt/java/awt/Toolkit.java b/awt/java/awt/Toolkit.java
new file mode 100644
index 0000000..0c066b2
--- /dev/null
+++ b/awt/java/awt/Toolkit.java
@@ -0,0 +1,1338 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.event.AWTEventListener;
+import java.awt.event.AWTEventListenerProxy;
+import java.awt.event.InputEvent;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.peer.FontPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+import org.apache.harmony.awt.ChoiceStyle;
+import org.apache.harmony.awt.ComponentInternals;
+import org.apache.harmony.awt.ContextStorage;
+import org.apache.harmony.awt.ReadOnlyIterator;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.CreationParams;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeCursor;
+
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.NativeEventThread;
+import org.apache.harmony.awt.wtk.ShutdownWatchdog;
+import org.apache.harmony.awt.wtk.Synchronizer;
+import org.apache.harmony.awt.wtk.WTK;
+
+/**
+ * The Toolkit class is the representation of the platform-specific 
+ * Abstract Window Toolkit implementation. Toolkit's subclasses 
+ * are used to bind the various components to particular native 
+ * toolkit implementations.
+ */
+public abstract class Toolkit {
+    
+    /** The Constant RECOURCE_PATH. */
+    private static final String RECOURCE_PATH = "org.apache.harmony.awt.resources.AWTProperties"; //$NON-NLS-1$
+    
+    /** The Constant properties. */
+    private static final ResourceBundle properties = loadResources(RECOURCE_PATH);
+    
+    /** The dispatcher. */
+    Dispatcher dispatcher;
+
+    /** The system event queue core. */
+    private EventQueueCore systemEventQueueCore;
+
+    /** The dispatch thread. */
+    EventDispatchThread dispatchThread;
+
+    /** The native thread. */
+    NativeEventThread nativeThread;
+
+    /** The awt events manager. */
+    protected AWTEventsManager awtEventsManager;
+
+    /**
+     * The Class AWTTreeLock.
+     */
+    private class AWTTreeLock {
+    }
+
+    /** The awt tree lock. */
+    final Object awtTreeLock = new AWTTreeLock();
+
+    /** The synchronizer. */
+    private final Synchronizer synchronizer = ContextStorage.getSynchronizer();
+
+    /** The shutdown watchdog. */
+    final ShutdownWatchdog shutdownWatchdog = new ShutdownWatchdog();
+
+    /** The auto number. */
+    final AutoNumber autoNumber = new AutoNumber();
+
+    /** The event type lookup. */
+    final AWTEvent.EventTypeLookup eventTypeLookup = new AWTEvent.EventTypeLookup();
+
+    /** The b dynamic layout set. */    
+    private boolean bDynamicLayoutSet = true;
+
+    /** The set of desktop properties that user set directly. */
+    private final HashSet<String> userPropSet = new HashSet<String>();
+
+    /** The desktop properties. */
+    protected Map<String, Object> desktopProperties;
+
+    /** The desktop props support. */
+    protected PropertyChangeSupport desktopPropsSupport;
+
+    /**
+     * For this component the native window is being created
+     * It is used in the callback-driven window creation
+     * (e.g. on Windows in the handler of WM_CREATE event)
+     * to establish the connection between this component
+     * and its native window.
+     */
+    private Object recentNativeWindowComponent;
+
+    /** The wtk. */
+    private WTK wtk;
+
+    /**
+     * The Class ComponentInternalsImpl.
+     */
+    protected final class ComponentInternalsImpl extends ComponentInternals {
+
+        /**
+         * Shutdown.
+         */
+        @Override
+        public void shutdown() {
+            dispatchThread.shutdown();
+        }
+       
+        /**
+         * Sets the desktop property to the specified value and fires a property 
+         * change event.  
+         * 
+         * @param name the name of property.
+         * @param value the new value of property.
+         */
+        @Override
+        public void setDesktopProperty(String name, Object value) {
+            Toolkit.this.setDesktopProperty(name, value);
+        }
+    }
+
+
+    /**
+     * A lot of methods must throw HeadlessException
+     * if <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
+     * 
+     * @throws HeadlessException the headless exception
+     */
+    static void checkHeadless() throws HeadlessException {
+        if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance())
+            throw new HeadlessException();
+    }
+
+    /**
+     * Lock awt.
+     */
+    final void lockAWT() {
+        synchronizer.lock();
+    }
+
+    /**
+     * Static lock awt.
+     */
+    static final void staticLockAWT() {
+        ContextStorage.getSynchronizer().lock();
+    }
+
+    /**
+     * Unlock awt.
+     */
+    final void unlockAWT() {
+        synchronizer.unlock();
+    }
+
+    /**
+     * Static unlock awt.
+     */
+    static final void staticUnlockAWT() {
+        ContextStorage.getSynchronizer().unlock();
+    }    
+
+    /**
+     * InvokeAndWait under AWT lock. W/o this method system can hang up.
+     * Added to support modality (Dialog.show() & PopupMenu.show()) from
+     * not event dispatch thread. Use in other cases is not recommended.
+     *
+     * Still can be called only for whole API methods that
+     * cannot be called from other classes API methods.
+     * Examples:
+     *      show() for modal dialogs    - correct, only user can call it,
+     *                                      directly or through setVisible(true)
+     *      setBounds() for components  - incorrect, setBounds()
+     *                                      can be called from layoutContainer()
+     *                                      for layout managers
+     * 
+     * @param runnable the runnable
+     * 
+     * @throws InterruptedException the interrupted exception
+     * @throws InvocationTargetException the invocation target exception
+     */
+    final void unsafeInvokeAndWait(Runnable runnable) throws InterruptedException,
+            InvocationTargetException {
+        synchronizer.storeStateAndFree();
+        try {
+            EventQueue.invokeAndWait(runnable);
+        } finally {
+            synchronizer.lockAndRestoreState();
+        }
+    }
+
+    /**
+     * Gets the synchronizer.
+     * 
+     * @return the synchronizer
+     */
+    final Synchronizer getSynchronizer() {
+        return synchronizer;
+    }
+
+    /**
+     * Gets the wTK.
+     * 
+     * @return the wTK
+     */
+    final WTK getWTK() {
+        return wtk;
+    }
+
+    /**
+     * Gets the property with the specified key and default value. 
+     * This method returns the defValue if the property is not found. 
+     * 
+     * @param propName the name of property.
+     * @param defVal the default value.
+     * 
+     * @return the property value.
+     */
+    public static String getProperty(String propName, String defVal) {
+        if (propName == null) {
+            // awt.7D=Property name is null
+            throw new NullPointerException(Messages.getString("awt.7D")); //$NON-NLS-1$
+        }
+        staticLockAWT();
+        try {
+            String retVal = null;
+            if (properties != null) {
+                try {
+                    retVal = properties.getString(propName);
+                } catch (MissingResourceException e) {
+                } catch (ClassCastException e) {
+                }
+            }
+            return (retVal == null) ? defVal : retVal;
+        } finally {
+            staticUnlockAWT();
+        }
+    }
+    
+    /**
+     * Gets the default Toolkit.
+     * 
+     * @return the default Toolkit
+     */
+    public static Toolkit getDefaultToolkit() {
+        synchronized (ContextStorage.getContextLock()) {
+            if (ContextStorage.shutdownPending()) {
+                return null;
+            }
+            Toolkit defToolkit = ContextStorage.getDefaultToolkit();
+            if (defToolkit != null) {
+                return defToolkit;
+            }
+            staticLockAWT();
+            try {
+                defToolkit = GraphicsEnvironment.isHeadless() ?
+                        new HeadlessToolkit() : new ToolkitImpl();
+                ContextStorage.setDefaultToolkit(defToolkit);
+                return defToolkit;
+            } finally {
+                staticUnlockAWT();
+            }
+            //TODO: read system property named awt.toolkit
+            //and create an instance of the specified class,
+            //by default use ToolkitImpl
+        }
+    }
+    
+    /**
+     * Gets the default Font.
+     * 
+     * @return the derault Font for Toolkit.
+     */
+    Font getDefaultFont() {
+        return wtk.getSystemProperties().getDefaultFont();
+    }
+    
+    /**
+     * Load resources.
+     * 
+     * @param path the path
+     * 
+     * @return the resource bundle
+     */
+    private static ResourceBundle loadResources(String path) {
+        try {
+            return ResourceBundle.getBundle(path);
+        } catch (MissingResourceException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Gets the wTK class name.
+     * 
+     * @return the wTK class name
+     */
+    private static String getWTKClassName() {
+        return "com.android.internal.awt.AndroidWTK";
+    }
+
+    /**
+     * Gets the component by id.
+     * 
+     * @param id the id
+     * 
+     * @return the component by id
+     */
+    Component getComponentById(long id) {
+        if (id == 0) {
+            return null;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the GraphicsFactory.
+     * 
+     * @return the GraphicsFactory object.
+     */
+    public GraphicsFactory getGraphicsFactory() {
+        return wtk.getGraphicsFactory();
+    }
+
+    /**
+     * Instantiates a new toolkit.
+     */
+    public Toolkit() {        
+        init();
+    }
+
+    /**
+     * Inits AWT.
+     */
+    protected void init() {
+        lockAWT();
+        try {
+            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
+            new EventQueue(this); // create the system EventQueue
+            dispatcher = new Dispatcher(this);
+            final String className = getWTKClassName();
+            desktopProperties = new HashMap<String, Object>();
+            desktopPropsSupport = new PropertyChangeSupport(this);
+            awtEventsManager = new AWTEventsManager();
+            dispatchThread = new EventDispatchThread(this, dispatcher);
+            nativeThread = new NativeEventThread();
+            NativeEventThread.Init init = new NativeEventThread.Init() {
+                public WTK init() {
+                    wtk = createWTK(className);
+                    wtk.getNativeEventQueue().setShutdownWatchdog(shutdownWatchdog);
+                    synchronizer.setEnvironment(wtk, dispatchThread);
+                    ContextStorage.setWTK(wtk);
+                    return wtk;
+                }
+            };
+            nativeThread.start(init);
+            dispatchThread.start();
+            wtk.getNativeEventQueue().awake();
+        } finally {
+            unlockAWT();
+        }
+    }
+    
+    /**
+     * Synchronizes this toolkit's graphics.
+     */
+    public abstract void sync();
+
+    /**
+     * Returns the construction status of a specified image that is being created.
+     * 
+     * @param a0 the image to be checked.
+     * @param a1 the width of scaled image for which the status is being checked, or -1.
+     * @param a2 the height of scaled image for which the status is being checked, or -1.
+     * @param a3 the ImageObserver object to be notified while 
+     * the image is being prepared.
+     * 
+     * @return the ImageObserver flags which give the current state of the image data.
+     */
+    public abstract int checkImage(Image a0, int a1, int a2, ImageObserver a3);
+   
+    /**
+     * Creates the image with the specified ImageProducer.
+     * 
+     * @param a0 the ImageProducer to be used for image creation.
+     * 
+     * @return the image with the specified ImageProducer.
+     */
+    public abstract Image createImage(ImageProducer a0);
+
+    /**
+     * Creates the image from the specified byte array, offset and length.
+     * The byte array should contain data with image format supported by 
+     * Toolkit such as JPEG, GIF, or PNG.  
+     * 
+     * @param a0 the byte array with the image data.
+     * @param a1 the offset of the beggining the image data in the byte array.
+     * @param a2 the length of the image data in the byte array.
+     * 
+     * @return the created Image.
+     */
+    public abstract Image createImage(byte[] a0, int a1, int a2);
+
+    /**
+     * Creates the image using image data from the specified URL.
+     * 
+     * @param a0 the URL for extracting image data.
+     * 
+     * @return the Image.
+     */
+    public abstract Image createImage(URL a0);
+
+    /**
+     * Creates the image using image data from the specified file.
+     * 
+     * @param a0 the file name which contains image data of supported format.
+     * 
+     * @return the Image.
+     */
+    public abstract Image createImage(String a0);
+
+    /**
+     * Gets the color model.
+     * 
+     * @return the ColorModel of Toolkit's screen.
+     * 
+     * @throws HeadlessException if the 
+     * GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public abstract ColorModel getColorModel() throws HeadlessException;
+    
+    /**
+     * Gets the screen device metrics for the specified font.
+     * 
+     * @param font the Font.
+     * 
+     * @return the FontMetrics for the specified Font.
+     * 
+     * @deprecated Use getLineMetrics method from Font class.
+     */
+        
+    @Deprecated
+    public abstract FontMetrics getFontMetrics(Font font);
+
+    /**
+     * Prepares the specified image for rendering on the screen with the
+     * specified size.
+     * 
+     * @param a0 the Image to be prepared.
+     * @param a1 the width of the screen representation or -1 for the current screen.
+     * @param a2 the height of the screen representation or -1 for the current screen.
+     * @param a3 the ImageObserver object to be notified as soon as 
+     * the image is prepared.
+     * 
+     * @return true, if image is fully prepared; false otherwise.
+     */
+    public abstract boolean prepareImage(Image a0, int a1, int a2, ImageObserver a3);
+
+    /**
+     * Creates an audio beep.
+     */
+    public abstract void beep();
+
+    /**
+     * Returns the array of font names which are available in this Toolkit.
+     * 
+     * @return the array of font names which are available in this Toolkit.
+     * 
+     * @deprecated use GraphicsEnvironment.getAvailableFontFamilyNames() method.
+     */
+    @Deprecated
+    public abstract String[] getFontList();
+    
+    /**
+     * Gets the the Font implementation using the specified peer 
+     * interface.
+     * 
+     * @param a0 the Font name to be implemented.
+     * @param a1 the the font style: PLAIN, BOLD, ITALIC.
+     * 
+     * @return the FontPeer implementation of the specified Font.
+     * 
+     * @deprecated use java.awt.GraphicsEnvironment.getAllFonts method.
+     */
+
+    @Deprecated
+    protected abstract FontPeer getFontPeer(String a0, int a1);
+
+    /**
+     * Gets the image from the specified file which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG); this method 
+     * should return the same Image for multiple calls of this method with 
+     * the same image file name.
+     * 
+     * @param a0 the file name which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG).
+     * 
+     * @return the Image.
+     */
+    public abstract Image getImage(String a0);
+
+    /**
+     * Gets the image from the specified URL which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG); this method 
+     * should return the same Image for multiple calls of this method with 
+     * the same image URL.
+     * 
+     * @param a0 the URL which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG).
+     * 
+     * @return the Image.
+     */
+    public abstract Image getImage(URL a0);
+
+    /**
+     * Gets the screen resolution.
+     * 
+     * @return the screen resolution.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public abstract int getScreenResolution() throws HeadlessException;
+
+    /**
+     * Gets the screen size.
+     * 
+     * @return a Dimension object containing the width and height of
+     * the screen.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public abstract Dimension getScreenSize() throws HeadlessException;
+
+    /**
+     * Gets the EventQueue instance without checking access.
+     * 
+     * @return the system EventQueue.
+     */
+    protected abstract EventQueue getSystemEventQueueImpl();
+
+    /**
+     * Returns a map of text attributes for the abstract level description 
+     * of the specified input method highlight, or null if no mapping is found. 
+     *  
+     * @param highlight the InputMethodHighlight.
+     * 
+     * @return the Map<java.awt.font. text attribute,?>
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public abstract Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException;
+
+    /**
+     * Map input method highlight impl.
+     * 
+     * @param highlight the highlight
+     * 
+     * @return the map<java.awt.font. text attribute,?>
+     * 
+     * @throws HeadlessException the headless exception
+     */
+    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(
+            InputMethodHighlight highlight) throws HeadlessException {
+        HashMap<java.awt.font.TextAttribute, ?> map = new HashMap<java.awt.font.TextAttribute, Object>();
+        wtk.getSystemProperties().mapInputMethodHighlight(highlight, map);
+        return Collections.<java.awt.font.TextAttribute, Object> unmodifiableMap(map);
+    }
+
+    /**
+     * Adds the specified PropertyChangeListener listener for the specified
+     * property.
+     * 
+     * @param propName the property name for which the specified PropertyChangeListener
+     * will be added. 
+     * @param l the PropertyChangeListener object.
+     */
+    public void addPropertyChangeListener(String propName, PropertyChangeListener l) {
+        lockAWT();
+        try {
+            if (desktopProperties.isEmpty()) {
+                initializeDesktopProperties();
+            }
+        } finally {
+            unlockAWT();
+        }
+        if (l != null) { // there is no guarantee that null listener will not be added
+            desktopPropsSupport.addPropertyChangeListener(propName, l);
+        }
+    }
+
+    /**
+     * Returns an array of the property change listeners registered with
+     * this Toolkit.
+     * 
+     * @return an array of the property change listeners registered with
+     * this Toolkit. 
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        return desktopPropsSupport.getPropertyChangeListeners();
+    }
+
+    /**
+     * Returns an array of the property change listeners registered with
+     * this Toolkit for notification regarding the specified property.
+     * 
+     * @param propName the property name for which the PropertyChangeListener
+     * was registered.
+     * 
+     * @return the array of PropertyChangeListeners registered for the specified 
+     * property name.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners(String propName) {
+        return desktopPropsSupport.getPropertyChangeListeners(propName);
+    }
+
+    /**
+     * Removes the specified property change listener registered for the
+     * specified property name.
+     * 
+     * @param propName the property name.
+     * @param l the PropertyChangeListener registered for the specified property name.
+     */
+    public void removePropertyChangeListener(String propName, PropertyChangeListener l) {
+        desktopPropsSupport.removePropertyChangeListener(propName, l);
+    }
+    
+    /**
+     * Creates a custom cursor with the specified Image, hot spot, and cursor
+     * description.
+     * 
+     * @param img the image of activated cursor.
+     * @param hotSpot the Point giving the coordinates of the cursor's hot spot. 
+     * @param name the cursor description.
+     * 
+     * @return the cursor with the specified Image, hot spot, and cursor
+     * description.
+     * 
+     * @throws IndexOutOfBoundsException if the hot spot values are outside  
+     * the bounds of the cursor.
+     * @throws HeadlessException if isHeadless() method of GraphicsEnvironment
+     * class returns true.
+     */
+    public Cursor createCustomCursor(Image img, Point hotSpot, String name)
+            throws IndexOutOfBoundsException, HeadlessException {
+        lockAWT();
+        try {
+            int w = img.getWidth(null), x = hotSpot.x;
+            int h = img.getHeight(null), y = hotSpot.y;
+            if (x < 0 || x >= w || y < 0 || y >= h) {
+                // awt.7E=invalid hotSpot
+                throw new IndexOutOfBoundsException(Messages.getString("awt.7E")); //$NON-NLS-1$
+            }
+            return new Cursor(name, img, hotSpot);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the supported cursor dimension which is closest to the 
+     * specified width and height. If the Toolkit only supports a single 
+     * cursor size, this method should return the supported cursor size.
+     * If custom cursor is not supported, a dimension of 0, 0 should be
+     * returned.
+     * 
+     * @param prefWidth the preffered cursor width.
+     * @param prefHeight the preffered cursor height.
+     * 
+     * @return the supported cursor dimension which is closest to the 
+     * specified width and height.
+     * 
+     * @throws HeadlessException if GraphicsEnvironment.isHeadless() 
+     * returns true.
+     */
+    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getCursorFactory().getBestCursorSize(prefWidth, prefHeight);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the value for the specified desktop property. 
+     * 
+     * @param propName the property name.
+     * 
+     * @return the Object that is the property's value.
+     */
+    public final Object getDesktopProperty(String propName) {
+        lockAWT();
+        try {
+            if (desktopProperties.isEmpty()) {
+                initializeDesktopProperties();
+            }
+            if (propName.equals("awt.dynamicLayoutSupported")) { //$NON-NLS-1$
+                // dynamicLayoutSupported is special case
+                return Boolean.valueOf(isDynamicLayoutActive());
+            }
+            Object val = desktopProperties.get(propName);
+            if (val == null) {
+                // try to lazily load prop value
+                // just for compatibility, our lazilyLoad is empty
+                val = lazilyLoadDesktopProperty(propName);
+            }
+            return val;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the locking key state for the specified key.
+     * 
+     * @param a0 the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, 
+     * or VK_KANA_LOCK.
+     * 
+     * @return true if the specified key code is in the locked state,
+     * false otherwise.
+     * 
+     * @throws UnsupportedOperationException if the state of this key 
+     * can't be retrieved, or if the keyboard doesn't have this key.
+     * @throws NotImplementedException if this method is not implemented.
+     */
+    public boolean getLockingKeyState(int a0) throws UnsupportedOperationException, org.apache.harmony.luni.util.NotImplementedException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return true;
+    }
+
+    /**
+     * Returns the maximum number of colors which the Toolkit supports for
+     * custom cursor.
+     * 
+     * @return the maximum cursor colors.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public int getMaximumCursorColors() throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getCursorFactory().getMaximumCursorColors();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the menu shortcut key mask.
+     *
+     * @return the menu shortcut key mask.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public int getMenuShortcutKeyMask() throws HeadlessException {
+        lockAWT();
+        try {
+            return InputEvent.CTRL_MASK;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the screen insets.
+     * 
+     * @param gc the GraphicsConfiguration.
+     * 
+     * @return the insets of this toolkit.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
+        if (gc == null) {
+            throw new NullPointerException();
+        }
+        lockAWT();
+        try {
+            return new Insets(0, 0, 0, 0); //TODO: get real screen insets
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the system EventQueue instance. 
+     * If the default implementation of checkAwtEventQueueAccess is used,
+     * then this results of a call to the security manager's checkPermission
+     * method with an AWTPermission("accessEventQueue") permission.
+     * 
+     * @return the system EventQueue instance.
+     */
+    public final EventQueue getSystemEventQueue() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkAwtEventQueueAccess();
+        }
+        return getSystemEventQueueImpl();
+    }
+
+    /** 
+     * Gets the system event queue core.
+     * 
+     * @return the system event queue core
+     */
+    EventQueueCore getSystemEventQueueCore() {
+        return systemEventQueueCore;
+    }
+    
+    /**
+     * Sets the system event queue core.
+     * 
+     * @param core the new system event queue core
+     */
+    void setSystemEventQueueCore(EventQueueCore core) {
+        systemEventQueueCore = core;
+    }
+
+    /**
+     * Initialize the desktop properties.
+     */
+    protected void initializeDesktopProperties() {
+        lockAWT();
+        try {
+            wtk.getSystemProperties().init(desktopProperties);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if dynamic layout of Containers is active or not.
+     * 
+     * @return true, if is dynamic layout of Containers is active,
+     * false otherwise.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public boolean isDynamicLayoutActive() throws HeadlessException {
+        lockAWT();
+        try {
+            // always return true
+            return true;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+
+    /**
+     * Returns if the layout of Containers is checked dynamically during resizing,
+     * or statically after resizing is completed. 
+     * 
+     * @return true, if if the layout of Containers is checked dynamically during 
+     * resizing; false, if the layout of Containers is checked statically after 
+     * resizing is completed. 
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    protected boolean isDynamicLayoutSet() throws HeadlessException {
+        lockAWT();
+        try {
+            return bDynamicLayoutSet;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if the specified frame state is supported by Toolkit or not.
+     * 
+     * @param state the frame state.
+     * 
+     * @return true, if frame state is supported; false othrwise.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public boolean isFrameStateSupported(int state) throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getWindowFactory().isWindowStateSupported(state);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Loads the value of the desktop property with the specified property name.
+     * 
+     * @param propName the property name.
+     * 
+     * @return the desktop property values.
+     */
+    protected Object lazilyLoadDesktopProperty(String propName) {
+        return null;
+    }
+
+    /**
+     * Loads the current system color values to the specified array.
+     * 
+     * @param colors the array where the current system color values 
+     * are written by this method.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    protected void loadSystemColors(int[] colors) throws HeadlessException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the value of the desktop property with the specified name.
+     * 
+     * @param propName the property's name.
+     * @param value the property's value.
+     */
+    protected final void setDesktopProperty(String propName, Object value) {
+        Object oldVal;
+        lockAWT();
+        try {
+            oldVal = getDesktopProperty(propName);
+            userPropSet.add(propName);
+            desktopProperties.put(propName, value);
+        } finally {
+            unlockAWT();
+        }
+        desktopPropsSupport.firePropertyChange(propName, oldVal, value);
+    }
+
+    /**
+     * Sets the layout state, whether the Container layout is checked 
+     * dynamically during resizing, or statically after resizing is completed. 
+     * 
+     * @param dynamic the new dynamic layout state - if true the layout of 
+     * Containers is checked dynamically during resizing, if false -
+     * statically after resizing is completed.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
+        lockAWT();
+        try {
+            bDynamicLayoutSet = dynamic;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the locking key state for the specified key code.
+     * 
+     * @param a0 the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, 
+     * or VK_KANA_LOCK.
+     * @param a1 the state - true to set the specified key code to the locked state,
+     * false - to unlock it.
+     * 
+     * @throws UnsupportedOperationException if the state of this key 
+     * can't be set, or if the keyboard doesn't have this key.
+     * @throws NotImplementedException if this method is not implemented.
+     */
+    public void setLockingKeyState(int a0, boolean a1) throws UnsupportedOperationException, org.apache.harmony.luni.util.NotImplementedException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return;
+    }
+
+
+    /**
+     * On queue empty.
+     */
+    void onQueueEmpty() {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    /**
+     * Creates the wtk.
+     * 
+     * @param clsName the cls name
+     * 
+     * @return the wTK
+     */
+    private WTK createWTK(String clsName) {
+        WTK newWTK = null;
+        try {
+            newWTK = (WTK) Class.forName(clsName).newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return newWTK;
+    }
+
+    /**
+     * Connect the component to its native window
+     * @param winId - id of native window just created
+     */
+    boolean onWindowCreated(long winId) {
+        return false;
+    }
+
+    /**
+     * Gets the native event queue.
+     * 
+     * @return the native event queue
+     */
+    NativeEventQueue getNativeEventQueue() {
+        return wtk.getNativeEventQueue();
+    }
+
+    /**
+     * Returns a shared instance of implementation of org.apache.harmony.awt.wtk.NativeCursor
+     * for current platform for
+     * 
+     * @param type - Java Cursor type
+     * 
+     * @return new instance of implementation of NativeCursor
+     */
+    NativeCursor createNativeCursor(int type) {
+        return wtk.getCursorFactory().getCursor(type);
+    }
+
+    /**
+     * Returns a shared instance of implementation of org.apache.harmony.awt.wtk.NativeCursor
+     * for current platform for custom cursor
+     * 
+     * @param img the img
+     * @param hotSpot the hot spot
+     * @param name the name
+     * 
+     * @return new instance of implementation of NativeCursor
+     */
+    NativeCursor createCustomNativeCursor(Image img, Point hotSpot, String name) {
+        return wtk.getCursorFactory().createCustomCursor(img, hotSpot.x, hotSpot.y);
+    }
+
+    /**
+     * Adds an AWTEventListener to the Toolkit to listen for events
+     * of types corresponding to bits in the specified event mask. 
+     * Event masks are defined in AWTEvent class.
+     * 
+     * @param listener the AWTEventListener.
+     * @param eventMask he bitmask of event types.
+     */
+    public void addAWTEventListener(AWTEventListener listener, long eventMask) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            awtEventsManager.addAWTEventListener(listener, eventMask);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Removes the specified awt event listener.
+     * 
+     * @param listener the AWTEventListener to be removed.
+     */
+    public void removeAWTEventListener(AWTEventListener listener) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            awtEventsManager.removeAWTEventListener(listener);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the array of all AWT event listeners registered with this Toolkit.
+     * 
+     * @return the array of all AWT event listeners registered with this Toolkit.
+     */
+    public AWTEventListener[] getAWTEventListeners() {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            return awtEventsManager.getAWTEventListeners();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the array of the AWT event listeners registered with this Toolkit 
+     * for the event types corresponding to the specified event mask.
+     * 
+     * @param eventMask the bit mask of event type.
+     * 
+     * @return the array of the AWT event listeners registered in this Toolkit 
+     * for the event types corresponding to the specified event mask.
+     */
+    public AWTEventListener[] getAWTEventListeners(long eventMask) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            return awtEventsManager.getAWTEventListeners(eventMask);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Dispatch awt event.
+     * 
+     * @param event the event
+     */
+    void dispatchAWTEvent(AWTEvent event) {
+        awtEventsManager.dispatchAWTEvent(event);
+    }
+    
+    /**
+     * The Class AWTEventsManager.
+     */
+    final class AWTEventsManager {
+
+        /** The permission. */
+        AWTPermission permission = new AWTPermission("listenToAllAWTEvents"); //$NON-NLS-1$
+
+        /** The listeners. */
+        private final AWTListenerList<AWTEventListenerProxy> listeners = new AWTListenerList<AWTEventListenerProxy>();
+
+        /**
+         * Adds the awt event listener.
+         * 
+         * @param listener the listener
+         * @param eventMask the event mask
+         */
+        void addAWTEventListener(AWTEventListener listener, long eventMask) {
+            if (listener != null) {
+                listeners.addUserListener(new AWTEventListenerProxy(eventMask, listener));
+            }
+        }
+
+        /**
+         * Removes the awt event listener.
+         * 
+         * @param listener the listener
+         */
+        void removeAWTEventListener(AWTEventListener listener) {
+            if (listener != null) {
+                for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                    if (listener == proxy.getListener()) {
+                        listeners.removeUserListener(proxy);
+                        return;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Gets the aWT event listeners.
+         * 
+         * @return the aWT event listeners
+         */
+        AWTEventListener[] getAWTEventListeners() {
+            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                listenersSet.add(proxy.getListener());
+            }
+            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
+        }
+
+        /**
+         * Gets the aWT event listeners.
+         * 
+         * @param eventMask the event mask
+         * 
+         * @return the aWT event listeners
+         */
+        AWTEventListener[] getAWTEventListeners(long eventMask) {
+            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                if ((proxy.getEventMask() & eventMask) == eventMask) {
+                    listenersSet.add(proxy.getListener());
+                }
+            }
+            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
+        }
+
+        /**
+         * Dispatch awt event.
+         * 
+         * @param event the event
+         */
+        void dispatchAWTEvent(AWTEvent event) {
+            AWTEvent.EventDescriptor descriptor = eventTypeLookup.getEventDescriptor(event);
+            if (descriptor == null) {
+                return;
+            }
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                if ((proxy.getEventMask() & descriptor.eventMask) != 0) {
+                    proxy.eventDispatched(event);
+                }
+            }
+        }
+    }
+    
+    /**
+     * The Class AutoNumber.
+     */
+    static final class AutoNumber {
+
+        /** The next component. */
+        int nextComponent = 0;
+
+        /** The next canvas. */
+        int nextCanvas = 0;
+
+        /** The next panel. */
+        int nextPanel = 0;
+
+        /** The next window. */
+        int nextWindow = 0;
+
+        /** The next frame. */
+        int nextFrame = 0;
+
+        /** The next dialog. */
+        int nextDialog = 0;
+
+        /** The next button. */
+        int nextButton = 0;
+
+        /** The next menu component. */
+        int nextMenuComponent = 0;
+
+        /** The next label. */
+        int nextLabel = 0;
+
+        /** The next check box. */
+        int nextCheckBox = 0;
+
+        /** The next scrollbar. */
+        int nextScrollbar = 0;
+
+        /** The next scroll pane. */
+        int nextScrollPane = 0;
+
+        /** The next list. */
+        int nextList = 0;
+
+        /** The next choice. */
+        int nextChoice = 0;
+
+        /** The next file dialog. */
+        int nextFileDialog = 0;
+
+        /** The next text area. */
+        int nextTextArea = 0;
+
+        /** The next text field. */
+        int nextTextField = 0;
+    }
+    
+    private class Lock {
+    }
+
+        /** The lock. */
+    private final Object lock = new Lock();
+        
+}
diff --git a/awt/java/awt/ToolkitImpl.java b/awt/java/awt/ToolkitImpl.java
new file mode 100644
index 0000000..5015aef
--- /dev/null
+++ b/awt/java/awt/ToolkitImpl.java
@@ -0,0 +1,255 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.peer.*;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.Hashtable;
+import java.util.Map;
+import org.apache.harmony.awt.gl.image.*;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+
+class ToolkitImpl extends Toolkit {
+	
+    static final Hashtable<Serializable, Image> imageCache = new Hashtable<Serializable, Image>();
+
+    @Override
+    public void sync() {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public int checkImage(Image image, int width, int height, ImageObserver observer) {
+        lockAWT();
+        try {
+            if (width == 0 || height == 0) {
+                return ImageObserver.ALLBITS;
+            }
+            if (!(image instanceof OffscreenImage)) {
+                return ImageObserver.ALLBITS;
+            }
+            OffscreenImage oi = (OffscreenImage) image;
+            return oi.checkImage(observer);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(ImageProducer producer) {
+        lockAWT();
+        try {
+            return new OffscreenImage(producer);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(byte[] imagedata, int imageoffset, int imagelength) {
+        lockAWT();
+        try {
+            return new OffscreenImage(new ByteArrayDecodingImageSource(imagedata, imageoffset,
+                    imagelength));
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(URL url) {
+        lockAWT();
+        try {
+            return new OffscreenImage(new URLDecodingImageSource(url));
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(String filename) {
+        lockAWT();
+        try {
+            return new OffscreenImage(new FileDecodingImageSource(filename));
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public ColorModel getColorModel() {
+        lockAWT();
+        try {
+            return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()
+                    .getDefaultConfiguration().getColorModel();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    @Deprecated
+    public FontMetrics getFontMetrics(Font font) {
+        lockAWT();
+        try {
+        	GraphicsFactory gf = getGraphicsFactory();
+            return gf.getFontMetrics(font);
+        } finally {
+            unlockAWT();
+        }
+    }
+    
+    @Override
+    public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
+        lockAWT();
+        try {
+            if (width == 0 || height == 0) {
+                return true;
+            }
+            if (!(image instanceof OffscreenImage)) {
+                return true;
+            }
+            OffscreenImage oi = (OffscreenImage) image;
+            return oi.prepareImage(observer);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public void beep() {
+        lockAWT();
+        try {
+        	// ???AWT: is there nothing to be implemented here?
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    @Deprecated
+    public String[] getFontList() {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        return null;
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    @Deprecated
+    protected FontPeer getFontPeer(String a0, int a1) {
+        lockAWT();
+        try {
+            return null;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image getImage(String filename) {
+        return getImage(filename, this);
+    }
+
+    static Image getImage(String filename, Toolkit toolkit) {
+        synchronized (imageCache) {
+            Image im = (filename == null ? null : imageCache.get(filename));
+
+            if (im == null) {
+                try {
+                    im = toolkit.createImage(filename);
+                    imageCache.put(filename, im);
+                } catch (Exception e) {
+                }
+            }
+
+            return im;
+        }
+    }
+
+    @Override
+    public Image getImage(URL url) {
+        return getImage(url, this);
+    }
+
+    static Image getImage(URL url, Toolkit toolkit) {
+        synchronized (imageCache) {
+            Image im = imageCache.get(url);
+            if (im == null) {
+                try {
+                    im = toolkit.createImage(url);
+                    imageCache.put(url, im);
+                } catch (Exception e) {
+                }
+            }
+            return im;
+        }
+    }
+
+    @Override
+    public int getScreenResolution() throws HeadlessException {
+        lockAWT();
+        try {
+        	return 62;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Dimension getScreenSize() {
+        lockAWT();
+        try {
+            DisplayMode dm = GraphicsEnvironment.getLocalGraphicsEnvironment()
+                    .getDefaultScreenDevice().getDisplayMode();
+            return new Dimension(dm.getWidth(), dm.getHeight());
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException {
+        lockAWT();
+        try {
+            return mapInputMethodHighlightImpl(highlight);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    protected EventQueue getSystemEventQueueImpl() {
+        return getSystemEventQueueCore().getActiveEventQueue();
+    }
+}
diff --git a/awt/java/awt/Transparency.java b/awt/java/awt/Transparency.java
new file mode 100644
index 0000000..9793114
--- /dev/null
+++ b/awt/java/awt/Transparency.java
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The Transparency interface defines transparency's general modes.
+ */
+public interface Transparency {
+
+    /** The Constant OPAQUE represents completely opaque data,
+     * all pixels have an alpha value of 1.0. 
+     */
+    public static final int OPAQUE = 1;
+
+    /** The Constant BITMASK represents data which can be either 
+     * completely opaque, with an alpha value of 1.0, or completely 
+     * transparent, with an alpha value of 0.0.
+     */
+    public static final int BITMASK = 2;
+
+    /** The Constant TRANSLUCENT represents data which alpha value
+     * can vary between and including 0.0 and 1.0. */
+    public static final int TRANSLUCENT = 3;
+
+    /**
+     * Gets the transparency mode.
+     * 
+     * @return the transparency mode: OPAQUE, BITMASK or TRANSLUCENT.  
+     */
+    public int getTransparency();
+
+}
+
diff --git a/awt/java/awt/color/CMMException.java b/awt/java/awt/color/CMMException.java
new file mode 100644
index 0000000..16fe76e
--- /dev/null
+++ b/awt/java/awt/color/CMMException.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The CMMException is thrown as soon as a native CMM error
+ * occures.
+ */
+public class CMMException extends java.lang.RuntimeException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 5775558044142994965L;
+
+    /**
+     * Instantiates a new CMM exception with detail message.
+     * 
+     * @param s the String - detail message.
+     */
+    public CMMException (String s) {
+        super (s);
+    }
+}
diff --git a/awt/java/awt/color/ColorSpace.java b/awt/java/awt/color/ColorSpace.java
new file mode 100644
index 0000000..f961514
--- /dev/null
+++ b/awt/java/awt/color/ColorSpace.java
@@ -0,0 +1,340 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import java.io.Serializable;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ColorSpace class defines a color space type for a Color and provides methods
+ * for arrays of color component operations.
+ */
+public abstract class ColorSpace implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -409452704308689724L;
+
+    /** The Constant TYPE_XYZ indicates XYZ color space type. */
+    public static final int TYPE_XYZ = 0;
+
+    /** The Constant TYPE_Lab indicates Lab color space type. */
+    public static final int TYPE_Lab = 1;
+
+    /** The Constant TYPE_Luv indicates Luv color space type. */
+    public static final int TYPE_Luv = 2;
+
+    /** The Constant TYPE_YCbCr indicates YCbCr color space type. */
+    public static final int TYPE_YCbCr = 3;
+
+    /** The Constant TYPE_Yxy indicates Yxy color space type. */
+    public static final int TYPE_Yxy = 4;
+
+    /** The Constant TYPE_RGB indicates RGB color space type. */
+    public static final int TYPE_RGB = 5;
+
+    /** The Constant TYPE_GRAY indicates Gray color space type. */
+    public static final int TYPE_GRAY = 6;
+
+    /** The Constant TYPE_HSV indicates HSV color space type. */
+    public static final int TYPE_HSV = 7;
+
+    /** The Constant TYPE_HLS indicates HLS color space type. */
+    public static final int TYPE_HLS = 8;
+
+    /** The Constant TYPE_CMYK indicates CMYK color space type. */
+    public static final int TYPE_CMYK = 9;
+
+    /** The Constant TYPE_CMY indicates CMY color space type. */
+    public static final int TYPE_CMY = 11;
+
+    /** The Constant TYPE_2CLR indicates color spaces with 2 components. */
+    public static final int TYPE_2CLR = 12;
+
+    /** The Constant TYPE_3CLR indicates color spaces with 3 components. */
+    public static final int TYPE_3CLR = 13;
+
+    /** The Constant TYPE_4CLR indicates color spaces with 4 components. */
+    public static final int TYPE_4CLR = 14;
+
+    /** The Constant TYPE_5CLR indicates color spaces with 5 components. */
+    public static final int TYPE_5CLR = 15;
+
+    /** The Constant TYPE_6CLR indicates color spaces with 6 components. */
+    public static final int TYPE_6CLR = 16;
+
+    /** The Constant TYPE_7CLR indicates color spaces with 7 components. */
+    public static final int TYPE_7CLR = 17;
+
+    /** The Constant TYPE_8CLR indicates color spaces with 8 components. */
+    public static final int TYPE_8CLR = 18;
+
+    /** The Constant TYPE_9CLR indicates color spaces with 9 components. */
+    public static final int TYPE_9CLR = 19;
+
+    /** The Constant TYPE_ACLR indicates color spaces with 10 components. */
+    public static final int TYPE_ACLR = 20;
+
+    /** The Constant TYPE_BCLR indicates color spaces with 11 components. */
+    public static final int TYPE_BCLR = 21;
+
+    /** The Constant TYPE_CCLR indicates color spaces with 12 components. */
+    public static final int TYPE_CCLR = 22;
+
+    /** The Constant TYPE_DCLR indicates color spaces with 13 components. */
+    public static final int TYPE_DCLR = 23;
+
+    /** The Constant TYPE_ECLR indicates color spaces with 14 components. */
+    public static final int TYPE_ECLR = 24;
+
+    /** The Constant TYPE_FCLR indicates color spaces with 15 components. */
+    public static final int TYPE_FCLR = 25;
+
+    /** The Constant CS_sRGB indicates standard RGB color space.*/
+    public static final int CS_sRGB = 1000;
+
+    /** The Constant CS_LINEAR_RGB indicates linear RGB color space. */
+    public static final int CS_LINEAR_RGB = 1004;
+
+    /** The Constant CS_CIEXYZ indicates CIEXYZ conversion color space. */
+    public static final int CS_CIEXYZ = 1001;
+
+    /** The Constant CS_PYCC indicates Photo YCC conversion color space. */
+    public static final int CS_PYCC = 1002;
+
+    /** The Constant CS_GRAY indicates linear gray scale color space. */
+    public static final int CS_GRAY = 1003;
+
+    /** The cs_ gray. */
+    private static ColorSpace cs_Gray = null;
+    
+    /** The cs_ pycc. */
+    private static ColorSpace cs_PYCC = null;
+    
+    /** The cs_ ciexyz. */
+    private static ColorSpace cs_CIEXYZ = null;
+    
+    /** The cs_ lrgb. */
+    private static ColorSpace cs_LRGB = null;
+    
+    /** The cs_s rgb. */
+    private static ColorSpace cs_sRGB = null;
+
+    /** The type. */
+    private int type;
+    
+    /** The num components. */
+    private int numComponents;
+
+    /**
+     * Instantiates a ColorSpace with the specified
+     * ColorSpace type and number of components.
+     * 
+     * @param type the type of color space.
+     * @param numcomponents the number of components.
+     */
+    protected ColorSpace(int type, int numcomponents) {
+        this.numComponents = numcomponents;
+        this.type = type;
+    }
+
+    /**
+     * Gets the name of the component for the specified component index.
+     * 
+     * @param idx the index of the component.
+     * 
+     * @return the name of the component.
+     */
+    public String getName(int idx) {
+        if (idx < 0 || idx > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", idx)); //$NON-NLS-1$
+        }
+
+      return "Unnamed color component #" + idx; //$NON-NLS-1$
+    }
+
+    /**
+     * Perform transformation a color from this ColorSpace 
+     * into the RGB color space.
+     * 
+     * @param colorvalue the color value in this ColorSpace.
+     * 
+     * @return the float array with color components in the 
+     * RGB color space.
+     */
+    public abstract float[] toRGB(float[] colorvalue);
+
+    /**
+     * Perform transformation a color from this ColorSpace 
+     * into the CS_CIEXYZ color space.
+     * 
+     * @param colorvalue the color value in this ColorSpace.
+     * 
+     * @return the float array with color components in the 
+     * CS_CIEXYZ color space. 
+     */
+    public abstract float[] toCIEXYZ(float[] colorvalue);
+
+    /**
+     * Performs color transformation from the RGB color space 
+     * into this ColorSpace.
+     * 
+     * @param rgbvalue a float array in the RGB color space.
+     * 
+     * @return the float[] an array of transformed color
+     * components. 
+     */
+    public abstract float[] fromRGB(float[] rgbvalue);
+
+    /**
+     * Performs color transformation from the CS_CIEXYZ color space 
+     * into this ColorSpace.
+     * 
+     * @param colorvalue a float array in the CS_CIEXYZ color space.
+     * 
+     * @return the float[] an array of transformed color
+     * components. 
+     */
+    public abstract float[] fromCIEXYZ(float[] colorvalue);
+
+    /**
+     * Gets the minimum normalized color component value for 
+     * the specified component.
+     * 
+     * @param component the component.
+     * 
+     * @return the miniimum normalized value of the component.
+     */
+    public float getMinValue(int component) {
+        if (component < 0 || component > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
+        }
+        return 0;
+    }
+
+    /**
+     * Gets the maximum normalized color component value for 
+     * the specified component.
+     * 
+     * @param component the component.
+     * 
+     * @return the maximum normalized value of the component.
+     */
+    public float getMaxValue(int component) {
+        if (component < 0 || component > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
+        }
+        return 1;
+    }
+
+    /**
+     * Checks if this ColorSpace has CS_sRGB type or not.
+     * 
+     * @return true, if this ColorSpace has CS_sRGB type, 
+     * false otherwise.
+     */
+    public boolean isCS_sRGB() {
+        // If our color space is sRGB, then cs_sRGB
+        // is already initialized
+        return (this == cs_sRGB);
+    }
+
+    /**
+     * Gets the type of the ColorSpace.
+     * 
+     * @return the type of the ColorSpace.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the number of components for this ColorSpace.
+     * 
+     * @return the number of components.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+
+    /**
+     * Gets the single instance of ColorSpace with the specified
+     * ColorSpace: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ, CS_GRAY, 
+     * or CS_PYCC.
+     * 
+     * @param colorspace the identifier of the specified Colorspace.
+     * 
+     * @return the single instance of the desired ColorSpace.
+     */
+    public static ColorSpace getInstance(int colorspace) {
+        switch (colorspace) {
+            case CS_sRGB:
+                if (cs_sRGB == null) {
+                    cs_sRGB = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_sRGB));
+                    LUTColorConverter.sRGB_CS = cs_sRGB;
+                            //ICC_Profile.getInstance (CS_sRGB));
+                }
+                return cs_sRGB;
+            case CS_CIEXYZ:
+                if (cs_CIEXYZ == null) {
+                    cs_CIEXYZ = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_CIEXYZ));
+                            //ICC_Profile.getInstance (CS_CIEXYZ));
+                }
+                return cs_CIEXYZ;
+            case CS_GRAY:
+                if (cs_Gray == null) {
+                    cs_Gray = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_GRAY));
+                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
+                            //ICC_Profile.getInstance (CS_GRAY));
+                }
+                return cs_Gray;
+            case CS_PYCC:
+                if (cs_PYCC == null) {
+                    cs_PYCC = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_PYCC));
+                            //ICC_Profile.getInstance (CS_PYCC));
+                }
+                return cs_PYCC;
+            case CS_LINEAR_RGB:
+                if (cs_LRGB == null) {
+                    cs_LRGB = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_LINEAR_RGB));
+                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
+                            //ICC_Profile.getInstance (CS_LINEAR_RGB));
+                }
+                return cs_LRGB;
+            default:
+        }
+
+        // Unknown argument passed
+        // awt.16B=Not a predefined colorspace
+        throw new IllegalArgumentException(Messages.getString("Not a predefined colorspace")); //$NON-NLS-1$
+    }
+
+}
\ No newline at end of file
diff --git a/awt/java/awt/color/ICC_ColorSpace.java b/awt/java/awt/color/ICC_ColorSpace.java
new file mode 100644
index 0000000..5ece2ef
--- /dev/null
+++ b/awt/java/awt/color/ICC_ColorSpace.java
@@ -0,0 +1,379 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import org.apache.harmony.awt.gl.color.ColorConverter;
+import org.apache.harmony.awt.gl.color.ColorScaler;
+import org.apache.harmony.awt.gl.color.ICC_Transform;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+import java.io.*;
+
+/**
+ * ICC_ColorSpace class implements ColorSpace abstract class and 
+ * represents device independent and device dependent color spaces.
+ * This color space is based on the International Color Consortium 
+ * Specification (ICC) File Format for Color Profiles: 
+ * <a href="http://www.color.org">http://www.color.org</a>
+ */
+public class ICC_ColorSpace extends ColorSpace {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 3455889114070431483L;
+
+    // Need to keep compatibility with serialized form
+    /** The Constant serialPersistentFields. */
+    private static final ObjectStreamField[]
+      serialPersistentFields = {
+        new ObjectStreamField("thisProfile", ICC_Profile.class), //$NON-NLS-1$
+        new ObjectStreamField("minVal", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("maxVal", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("diffMinMax", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("invDiffMinMax", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("needScaleInit", Boolean.TYPE) //$NON-NLS-1$
+    };
+
+
+   /**
+    * According to ICC specification (from http://www.color.org)
+    * "For the CIEXYZ encoding, each component (X, Y, and Z)
+    * is encoded as a u1Fixed15Number".
+    * This means that max value for this encoding is 1 + (32767/32768)
+    */
+    private static final float MAX_XYZ = 1f + (32767f/32768f);
+    
+    /** The Constant MAX_SHORT. */
+    private static final float MAX_SHORT = 65535f;
+    
+    /** The Constant INV_MAX_SHORT. */
+    private static final float INV_MAX_SHORT = 1f/MAX_SHORT;
+    
+    /** The Constant SHORT2XYZ_FACTOR. */
+    private static final float SHORT2XYZ_FACTOR = MAX_XYZ/MAX_SHORT;
+    
+    /** The Constant XYZ2SHORT_FACTOR. */
+    private static final float XYZ2SHORT_FACTOR = MAX_SHORT/MAX_XYZ;
+
+    /** The profile. */
+    private ICC_Profile profile = null;
+    
+    /** The min values. */
+    private float minValues[] = null;
+    
+    /** The max values. */
+    private float maxValues[] = null;
+
+    // cache transforms here - performance gain
+    /** The to rgb transform. */
+    private ICC_Transform toRGBTransform = null;
+    
+    /** The from rgb transform. */
+    private ICC_Transform fromRGBTransform = null;
+    
+    /** The to xyz transform. */
+    private ICC_Transform toXYZTransform = null;
+    
+    /** The from xyz transform. */
+    private ICC_Transform fromXYZTransform = null;
+
+    /** The converter. */
+    private final ColorConverter converter = new ColorConverter();
+    
+    /** The scaler. */
+    private final ColorScaler scaler = new ColorScaler();
+    
+    /** The scaling data loaded. */
+    private boolean scalingDataLoaded = false;
+
+    /** The resolved deserialized inst. */
+    private ICC_ColorSpace resolvedDeserializedInst;
+
+    /**
+     * Instantiates a new ICC color space from an ICC_Profile object.
+     * 
+     * @param pf the ICC_Profile object.
+     */
+    public ICC_ColorSpace(ICC_Profile pf) {
+        super(pf.getColorSpaceType(), pf.getNumComponents());
+
+        int pfClass = pf.getProfileClass();
+
+        switch (pfClass) {
+            case ICC_Profile.CLASS_COLORSPACECONVERSION:
+            case ICC_Profile.CLASS_DISPLAY:
+            case ICC_Profile.CLASS_OUTPUT:
+            case ICC_Profile.CLASS_INPUT:
+                break; // OK, it is color conversion profile
+            default:
+                // awt.168=Invalid profile class.
+                throw new IllegalArgumentException(Messages.getString("awt.168")); //$NON-NLS-1$
+        }
+
+        profile = pf;
+        fillMinMaxValues();
+    }
+
+    /**
+     * Returns the ICC_Profile for this ICC_ColorSpace.
+     * 
+     * @return the ICC_Profile for this ICC_ColorSpace.
+     */
+    public ICC_Profile getProfile() {
+        if (profile instanceof ICC_ProfileStub) {
+            profile = ((ICC_ProfileStub) profile).loadProfile();
+        }
+
+        return profile;
+    }
+
+    @Override
+    public float[] toRGB(float[] colorvalue) {
+        if (toRGBTransform == null) {
+            ICC_Profile sRGBProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
+            ICC_Profile[] profiles = {getProfile(), sRGBProfile};
+            toRGBTransform = new ICC_Transform(profiles);
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        short[] data = new short[getNumComponents()];
+
+        scaler.scale(colorvalue, data, 0);
+
+        short[] converted =
+            converter.translateColor(toRGBTransform, data, null);
+
+        // unscale to sRGB
+        float[] res = new float[3];
+
+        res[0] = ((converted[0] & 0xFFFF)) * INV_MAX_SHORT;
+        res[1] = ((converted[1] & 0xFFFF)) * INV_MAX_SHORT;
+        res[2] = ((converted[2] & 0xFFFF)) * INV_MAX_SHORT;
+
+        return res;
+    }
+
+    @Override
+    public float[] toCIEXYZ(float[] colorvalue) {
+        if (toXYZTransform == null) {
+            ICC_Profile xyzProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
+            ICC_Profile[] profiles = {getProfile(), xyzProfile};
+            try {
+                int[] intents = {
+                        ICC_Profile.icRelativeColorimetric,
+                        ICC_Profile.icPerceptual};
+                toXYZTransform = new ICC_Transform(profiles, intents);
+            } catch (CMMException e) { // No such tag, use what we can
+                toXYZTransform = new ICC_Transform(profiles);
+            }
+
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        short[] data = new short[getNumComponents()];
+
+        scaler.scale(colorvalue, data, 0);
+
+        short[] converted =
+            converter.translateColor(toXYZTransform, data, null);
+
+        // unscale to XYZ
+        float[] res = new float[3];
+
+        res[0] = ((converted[0] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+        res[1] = ((converted[1] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+        res[2] = ((converted[2] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+
+        return res;
+    }
+
+    @Override
+    public float[] fromRGB(float[] rgbvalue) {
+        if (fromRGBTransform == null) {
+            ICC_Profile sRGBProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
+            ICC_Profile[] profiles = {sRGBProfile, getProfile()};
+            fromRGBTransform = new ICC_Transform(profiles);
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        // scale rgb value to short
+        short[] scaledRGBValue = new short[3];
+        scaledRGBValue[0] = (short)(rgbvalue[0] * MAX_SHORT + 0.5f);
+        scaledRGBValue[1] = (short)(rgbvalue[1] * MAX_SHORT + 0.5f);
+        scaledRGBValue[2] = (short)(rgbvalue[2] * MAX_SHORT + 0.5f);
+
+        short[] converted =
+            converter.translateColor(fromRGBTransform, scaledRGBValue, null);
+
+        float[] res = new float[getNumComponents()];
+
+        scaler.unscale(res, converted, 0);
+
+        return res;
+    }
+
+    @Override
+    public float[] fromCIEXYZ(float[] xyzvalue) {
+        if (fromXYZTransform == null) {
+            ICC_Profile xyzProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
+            ICC_Profile[] profiles = {xyzProfile, getProfile()};
+            try {
+                int[] intents = {
+                        ICC_Profile.icPerceptual,
+                        ICC_Profile.icRelativeColorimetric};
+                fromXYZTransform = new ICC_Transform(profiles, intents);
+            } catch (CMMException e) { // No such tag, use what we can
+                fromXYZTransform = new ICC_Transform(profiles);
+            }
+
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+
+        }
+
+        // scale xyz value to short
+        short[] scaledXYZValue = new short[3];
+        scaledXYZValue[0] = (short)(xyzvalue[0] * XYZ2SHORT_FACTOR + 0.5f);
+        scaledXYZValue[1] = (short)(xyzvalue[1] * XYZ2SHORT_FACTOR + 0.5f);
+        scaledXYZValue[2] = (short)(xyzvalue[2] * XYZ2SHORT_FACTOR + 0.5f);
+
+        short[] converted =
+            converter.translateColor(fromXYZTransform, scaledXYZValue, null);
+
+        float[] res = new float[getNumComponents()];
+
+        scaler.unscale(res, converted, 0);
+
+        return res;
+    }
+
+    @Override
+    public float getMinValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            // awt.169=Component index out of range
+            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
+        }
+
+        return minValues[component];
+    }
+
+    @Override
+    public float getMaxValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            // awt.169=Component index out of range
+            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
+        }
+
+        return maxValues[component];
+    }
+
+    /**
+     * Fill min max values.
+     */
+    private void fillMinMaxValues() {
+        int n = getNumComponents();
+        maxValues = new float[n];
+        minValues = new float[n];
+        switch (getType()) {
+            case ColorSpace.TYPE_XYZ:
+                minValues[0] = 0;
+                minValues[1] = 0;
+                minValues[2] = 0;
+                maxValues[0] = MAX_XYZ;
+                maxValues[1] = MAX_XYZ;
+                maxValues[2] = MAX_XYZ;
+                break;
+            case ColorSpace.TYPE_Lab:
+                minValues[0] = 0;
+                minValues[1] = -128;
+                minValues[2] = -128;
+                maxValues[0] = 100;
+                maxValues[1] = 127;
+                maxValues[2] = 127;
+                break;
+            default:
+                for(int i=0; i<n; i++) {
+                    minValues[i] = 0;
+                    maxValues[i] = 1;
+                }
+        }
+    }
+
+    /**
+     * Write object.
+     * 
+     * @param out the out
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        ObjectOutputStream.PutField fields = out.putFields();
+
+        fields.put("thisProfile", profile); //$NON-NLS-1$
+        fields.put("minVal", null); //$NON-NLS-1$
+        fields.put("maxVal", null); //$NON-NLS-1$
+        fields.put("diffMinMax", null); //$NON-NLS-1$
+        fields.put("invDiffMinMax", null); //$NON-NLS-1$
+        fields.put("needScaleInit", true); //$NON-NLS-1$
+
+        out.writeFields();
+    }
+
+    /**
+     * Read object.
+     * 
+     * @param in the in
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        ObjectInputStream.GetField fields = in.readFields();
+        resolvedDeserializedInst =
+                new ICC_ColorSpace((ICC_Profile) fields.get("thisProfile", null)); //$NON-NLS-1$
+    }
+
+    /**
+     * Read resolve.
+     * 
+     * @return the object
+     * 
+     * @throws ObjectStreamException the object stream exception
+     */
+    Object readResolve() throws ObjectStreamException {
+        return resolvedDeserializedInst;
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_Profile.java b/awt/java/awt/color/ICC_Profile.java
new file mode 100644
index 0000000..ad704e0
--- /dev/null
+++ b/awt/java/awt/color/ICC_Profile.java
@@ -0,0 +1,1231 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.gl.color.ICC_ProfileHelper;
+import org.apache.harmony.awt.gl.color.NativeCMM;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ICC_Profile class represents a color profile data for color spaces 
+ * based on the International Color Consortium Specification ICC.1:2001-12, 
+ * File Format for Color Profiles.
+ */
+public class ICC_Profile implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -3938515861990936766L;
+
+    // NOTE: Constant field values are noted in 1.5 specification.
+
+    /**
+     * The Constant CLASS_INPUT indicates that profile class is input. 
+     */
+    public static final int CLASS_INPUT = 0;
+
+    /** 
+     * The Constant CLASS_DISPLAY indicates that profile class is display. 
+     */
+    public static final int CLASS_DISPLAY = 1;
+
+    /** 
+     * The Constant CLASS_OUTPUT indicates that profile class is output. 
+     */
+    public static final int CLASS_OUTPUT = 2;
+
+    /** 
+     * The Constant CLASS_DEVICELINK indicates that profile class 
+     * is device link. 
+     */
+    public static final int CLASS_DEVICELINK = 3;
+
+    /** 
+     * The Constant CLASS_COLORSPACECONVERSION indicates that profile class 
+     * is color space conversion.
+     */
+    public static final int CLASS_COLORSPACECONVERSION = 4;
+
+    /** The Constant CLASS_ABSTRACT indicates that profile class is abstract. */
+    public static final int CLASS_ABSTRACT = 5;
+
+    /** 
+     * The Constant CLASS_NAMEDCOLOR indicates that profile class 
+     * is named color. 
+     */
+    public static final int CLASS_NAMEDCOLOR = 6;
+
+    /** The Constant icSigXYZData - ICC Profile Color Space Type Signature. */
+    public static final int icSigXYZData = 1482250784;
+
+    /** The Constant icSigLabData - ICC Profile Color Space Type Signature. */
+    public static final int icSigLabData = 1281450528;
+
+    /** The Constant icSigLuvData - ICC Profile Color Space Type Signature. */
+    public static final int icSigLuvData = 1282766368;
+
+    /** The Constant icSigYCbCrData - ICC Profile Color Space Type Signature. */
+    public static final int icSigYCbCrData = 1497588338;
+
+    /** The Constant icSigYxyData - ICC Profile Color Space Type Signature. */
+    public static final int icSigYxyData = 1501067552;
+
+    /** The Constant icSigRgbData - ICC Profile Color Space Type Signature. */
+    public static final int icSigRgbData = 1380401696;
+
+    /** The Constant icSigGrayData - ICC Profile Color Space Type Signature. */
+    public static final int icSigGrayData = 1196573017;
+
+    /** The Constant icSigHsvData - ICC Profile Color Space Type Signature. */
+    public static final int icSigHsvData = 1213421088;
+
+    /** The Constant icSigHlsData - ICC Profile Color Space Type Signature. */
+    public static final int icSigHlsData = 1212961568;
+
+    /** The Constant icSigCmykData - ICC Profile Color Space Type Signature. */
+    public static final int icSigCmykData = 1129142603;
+
+    /** The Constant icSigCmyData - ICC Profile Color Space Type Signature. */
+    public static final int icSigCmyData = 1129142560;
+
+    /** The Constant icSigSpace2CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace2CLR = 843271250;
+
+    /** The Constant icSigSpace3CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace3CLR = 860048466;
+
+    /** The Constant icSigSpace4CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace4CLR = 876825682;
+
+    /** The Constant icSigSpace5CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace5CLR = 893602898;
+
+    /** The Constant icSigSpace6CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace6CLR = 910380114;
+
+    /** The Constant icSigSpace7CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace7CLR = 927157330;
+
+    /** The Constant icSigSpace8CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace8CLR = 943934546;
+
+    /** The Constant icSigSpace9CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace9CLR = 960711762;
+
+    /** The Constant icSigSpaceACLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceACLR = 1094929490;
+
+    /** The Constant icSigSpaceBCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceBCLR = 1111706706;
+
+    /** The Constant icSigSpaceCCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceCCLR = 1128483922;
+
+    /** The Constant icSigSpaceDCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceDCLR = 1145261138;
+
+    /** The Constant icSigSpaceECLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceECLR = 1162038354;
+
+    /** The Constant icSigSpaceFCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceFCLR = 1178815570;
+
+    /** The Constant icSigInputClass - ICC Profile Class Signature. */
+    public static final int icSigInputClass = 1935896178;
+
+    /** The Constant icSigDisplayClass - ICC Profile Class Signature. */
+    public static final int icSigDisplayClass = 1835955314;
+
+    /** The Constant icSigOutputClass - ICC Profile Class Signature. */
+    public static final int icSigOutputClass = 1886549106;
+
+    /** The Constant icSigLinkClass - ICC Profile Class Signature. */
+    public static final int icSigLinkClass = 1818848875;
+
+    /** The Constant icSigAbstractClass - ICC Profile Class Signature. */
+    public static final int icSigAbstractClass = 1633842036;
+
+    /** The Constant icSigColorantOrderTag - ICC Profile Tag Signature. */
+    public static final int icSigColorantOrderTag = 1668051567;
+
+    /** The Constant icSigColorantTableTag - ICC Profile Tag Signature. */
+    public static final int icSigColorantTableTag = 1668051572;
+
+    /** The Constant icSigColorSpaceClass - ICC Profile Tag Signature. */
+    public static final int icSigColorSpaceClass = 1936744803;
+
+    /** The Constant icSigNamedColorClass - ICC Profile Tag Signature. */
+    public static final int icSigNamedColorClass = 1852662636;
+
+    /** The Constant icPerceptual - ICC Profile Rendering Intent. */
+    public static final int icPerceptual = 0;
+
+    /** The Constant icRelativeColorimetric - ICC Profile Rendering Intent. */
+    public static final int icRelativeColorimetric = 1;
+
+    /** The Constant icSaturation - ICC Profile Rendering Intent. */
+    public static final int icSaturation = 2;
+
+    /** The Constant icAbsoluteColorimetric - ICC Profile Rendering Intent. */
+    public static final int icAbsoluteColorimetric = 3;
+
+    /** The Constant icSigHead - ICC Profile Tag Signature. */
+    public static final int icSigHead = 1751474532;
+
+    /** The Constant icSigAToB0Tag - ICC Profile Tag Signature. */
+    public static final int icSigAToB0Tag = 1093812784;
+
+    /** The Constant icSigAToB1Tag - ICC Profile Tag Signature. */
+    public static final int icSigAToB1Tag = 1093812785;
+
+    /** The Constant icSigAToB2Tag - ICC Profile Tag Signature. */
+    public static final int icSigAToB2Tag = 1093812786;
+
+    /** The Constant icSigBlueColorantTag - ICC Profile Tag Signature. */
+    public static final int icSigBlueColorantTag = 1649957210;
+
+    /** The Constant icSigBlueMatrixColumnTag - ICC Profile Tag Signature. */
+    public static final int icSigBlueMatrixColumnTag = 1649957210;
+
+    /** The Constant icSigBlueTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigBlueTRCTag = 1649693251;
+
+    /** The Constant icSigBToA0Tag - ICC Profile Tag Signature. */
+    public static final int icSigBToA0Tag = 1110589744;
+
+    /** The Constant icSigBToA1Tag - ICC Profile Tag Signature. */
+    public static final int icSigBToA1Tag = 1110589745;
+
+    /** The Constant icSigBToA2Tag - ICC Profile Tag Signature. */
+    public static final int icSigBToA2Tag = 1110589746;
+
+    /** The Constant icSigCalibrationDateTimeTag - ICC Profile Tag Signature. */
+    public static final int icSigCalibrationDateTimeTag = 1667329140;
+
+    /** The Constant icSigCharTargetTag - ICC Profile Tag Signature. */
+    public static final int icSigCharTargetTag = 1952543335;
+
+    /** The Constant icSigCopyrightTag - ICC Profile Tag Signature. */
+    public static final int icSigCopyrightTag = 1668313716;
+
+    /** The Constant icSigCrdInfoTag - ICC Profile Tag Signature. */
+    public static final int icSigCrdInfoTag = 1668441193;
+
+    /** The Constant icSigDeviceMfgDescTag - ICC Profile Tag Signature. */
+    public static final int icSigDeviceMfgDescTag = 1684893284;
+
+    /** The Constant icSigDeviceModelDescTag - ICC Profile Tag Signature. */
+    public static final int icSigDeviceModelDescTag = 1684890724;
+
+    /** The Constant icSigDeviceSettingsTag - ICC Profile Tag Signature. */
+    public static final int icSigDeviceSettingsTag = 1684371059;
+
+    /** The Constant icSigGamutTag - ICC Profile Tag Signature. */
+    public static final int icSigGamutTag = 1734438260;
+
+    /** The Constant icSigGrayTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigGrayTRCTag = 1800688195;
+
+    /** The Constant icSigGreenColorantTag - ICC Profile Tag Signature. */
+    public static final int icSigGreenColorantTag = 1733843290;
+
+    /** The Constant icSigGreenMatrixColumnTag - ICC Profile Tag Signature. */
+    public static final int icSigGreenMatrixColumnTag = 1733843290;
+
+    /** The Constant icSigGreenTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigGreenTRCTag = 1733579331;
+
+    /** The Constant icSigLuminanceTag - ICC Profile Tag Signature. */
+    public static final int icSigLuminanceTag = 1819635049;
+
+    /** The Constant icSigMeasurementTag - ICC Profile Tag Signature. */
+    public static final int icSigMeasurementTag = 1835360627;
+
+    /** The Constant icSigMediaBlackPointTag - ICC Profile Tag Signature. */
+    public static final int icSigMediaBlackPointTag = 1651208308;
+
+    /** The Constant icSigMediaWhitePointTag - ICC Profile Tag Signature. */
+    public static final int icSigMediaWhitePointTag = 2004119668;
+
+    /** The Constant icSigNamedColor2Tag - ICC Profile Tag Signature. */
+    public static final int icSigNamedColor2Tag = 1852009522;
+
+    /** The Constant icSigOutputResponseTag - ICC Profile Tag Signature. */
+    public static final int icSigOutputResponseTag = 1919251312;
+
+    /** The Constant icSigPreview0Tag - ICC Profile Tag Signature. */
+    public static final int icSigPreview0Tag = 1886545200;
+
+    /** The Constant icSigPreview1Tag - ICC Profile Tag Signature. */
+    public static final int icSigPreview1Tag = 1886545201;
+
+    /** The Constant icSigPreview2Tag - ICC Profile Tag Signature. */
+    public static final int icSigPreview2Tag = 1886545202;
+
+    /** The Constant icSigProfileDescriptionTag - ICC Profile Tag Signature. */
+    public static final int icSigProfileDescriptionTag = 1684370275;
+
+    /** The Constant icSigProfileSequenceDescTag - ICC Profile Tag Signature. */
+    public static final int icSigProfileSequenceDescTag = 1886610801;
+
+    /** The Constant icSigPs2CRD0Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD0Tag = 1886610480;
+
+    /** The Constant icSigPs2CRD1Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD1Tag = 1886610481;
+
+    /** The Constant icSigPs2CRD2Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD2Tag = 1886610482;
+
+    /** The Constant icSigPs2CRD3Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD3Tag = 1886610483;
+
+    /** The Constant icSigPs2CSATag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CSATag = 1886597747;
+
+    /** The Constant icSigPs2RenderingIntentTag - ICC Profile Tag Signature. */
+    public static final int icSigPs2RenderingIntentTag = 1886597737;
+
+    /** The Constant icSigRedColorantTag - ICC Profile Tag Signature. */
+    public static final int icSigRedColorantTag = 1918392666;
+
+    /** The Constant icSigRedMatrixColumnTag - ICC Profile Tag Signature. */
+    public static final int icSigRedMatrixColumnTag = 1918392666;
+
+    /** The Constant icSigRedTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigRedTRCTag = 1918128707;
+
+    /** The Constant icSigScreeningDescTag - ICC Profile Tag Signature. */
+    public static final int icSigScreeningDescTag = 1935897188;
+
+    /** The Constant icSigScreeningTag - ICC Profile Tag Signature. */
+    public static final int icSigScreeningTag = 1935897198;
+
+    /** The Constant icSigTechnologyTag - ICC Profile Tag Signature. */
+    public static final int icSigTechnologyTag = 1952801640;
+
+    /** The Constant icSigUcrBgTag - ICC Profile Tag Signature. */
+    public static final int icSigUcrBgTag = 1650877472;
+
+    /** The Constant icSigViewingCondDescTag - ICC Profile Tag Signature. */
+    public static final int icSigViewingCondDescTag = 1987405156;
+
+    /** The Constant icSigViewingConditionsTag - ICC Profile Tag Signature. */
+    public static final int icSigViewingConditionsTag = 1986618743;
+
+    /** The Constant icSigChromaticAdaptationTag - ICC Profile Tag Signature. */
+    public static final int icSigChromaticAdaptationTag = 1667785060;
+
+    /** The Constant icSigChromaticityTag - ICC Profile Tag Signature. */
+    public static final int icSigChromaticityTag = 1667789421;
+
+    /** The Constant icHdrSize - ICC Profile Header Location. */
+    public static final int icHdrSize = 0;
+
+    /** The Constant icHdrCmmId - ICC Profile Header Location. */
+    public static final int icHdrCmmId = 4;
+
+    /** The Constant icHdrVersion - ICC Profile Header Location. */
+    public static final int icHdrVersion = 8;
+
+    /** The Constant icHdrDeviceClass - ICC Profile Header Location. */
+    public static final int icHdrDeviceClass = 12;
+
+    /** The Constant icHdrColorSpace - ICC Profile Header Location. */
+    public static final int icHdrColorSpace = 16;
+
+    /** The Constant icHdrPcs - ICC Profile Header Location. */
+    public static final int icHdrPcs = 20;
+
+    /** The Constant icHdrDate - ICC Profile Header Location. */
+    public static final int icHdrDate = 24;
+
+    /** The Constant icHdrMagic - ICC Profile Header Location. */
+    public static final int icHdrMagic = 36;
+
+    /** The Constant icHdrPlatform - ICC Profile Header Location. */
+    public static final int icHdrPlatform = 40;
+
+    /** The Constant icHdrProfileID - ICC Profile Header Location. */
+    public static final int icHdrProfileID = 84;
+
+    /** The Constant icHdrFlags - ICC Profile Header Location. */
+    public static final int icHdrFlags = 44;
+
+    /** The Constant icHdrManufacturer - ICC Profile Header Location. */
+    public static final int icHdrManufacturer = 48;
+
+    /** The Constant icHdrModel - ICC Profile Header Location. */
+    public static final int icHdrModel = 52;
+
+    /** The Constant icHdrAttributes - ICC Profile Header Location. */
+    public static final int icHdrAttributes = 56;
+
+    /** The Constant icHdrRenderingIntent - ICC Profile Header Location. */
+    public static final int icHdrRenderingIntent = 64;
+
+    /** The Constant icHdrIlluminant - ICC Profile Header Location. */
+    public static final int icHdrIlluminant = 68;
+
+    /** The Constant icHdrCreator - ICC Profile Header Location. */
+    public static final int icHdrCreator = 80;
+
+    /** The Constant icICCAbsoluteColorimetric - ICC Profile Rendering Intent. */
+    public static final int icICCAbsoluteColorimetric = 3;
+
+    /** The Constant icMediaRelativeColorimetric - ICC Profile Rendering Intent. */
+    public static final int icMediaRelativeColorimetric = 1;
+
+    /** The Constant icTagType - ICC Profile Constant. */
+    public static final int icTagType = 0;
+
+    /** The Constant icTagReserved - ICC Profile Constant. */
+    public static final int icTagReserved = 4;
+
+    /** The Constant icCurveCount - ICC Profile Constant. */
+    public static final int icCurveCount = 8;
+
+    /** The Constant icCurveData - ICC Profile Constant. */
+    public static final int icCurveData = 12;
+
+    /** The Constant icXYZNumberX - ICC Profile Constant. */
+    public static final int icXYZNumberX = 8;
+
+    /** Size of a profile header. */
+    private static final int headerSize = 128;
+
+    /** header magic number. */
+    private static final int headerMagicNumber = 0x61637370;
+
+    // Cache of predefined profiles
+    /** The s rgb profile. */
+    private static ICC_Profile sRGBProfile;
+    
+    /** The xyz profile. */
+    private static ICC_Profile xyzProfile;
+    
+    /** The gray profile. */
+    private static ICC_Profile grayProfile;
+    
+    /** The pycc profile. */
+    private static ICC_Profile pyccProfile;
+    
+    /** The linear rgb profile. */
+    private static ICC_Profile linearRGBProfile;
+
+    /** Handle to the current profile. */
+    private transient long profileHandle = 0;
+
+    /** If handle is used by another class this object is not responsible for closing profile. */
+    private transient boolean handleStolen = false;
+
+    /** Cached header data. */
+    private transient byte[] headerData = null;
+
+    /** Serialization support. */
+    private transient ICC_Profile openedProfileObject;
+
+    /**
+     * Instantiates a new iC c_ profile.
+     * 
+     * @param data the data
+     */
+    private ICC_Profile(byte[] data) {
+        profileHandle = NativeCMM.cmmOpenProfile(data);
+        NativeCMM.addHandle(this, profileHandle);
+    }
+
+    /**
+     * Used to instantiate dummy ICC_ProfileStub objects.
+     */
+    ICC_Profile() {
+    }
+
+    /**
+     * Used to instantiate subclasses (ICC_ProfileGrey and ICC_ProfileRGB).
+     * 
+     * @param profileHandle - should be valid handle to opened color profile
+     */
+    ICC_Profile(long profileHandle) {
+        this.profileHandle = profileHandle;
+        // A new object reference, need to add it.
+        NativeCMM.addHandle(this, profileHandle);
+    }
+
+    /**
+     * Writes the ICC_Profile to a file with the specified name.
+     * 
+     * @param fileName the file name.
+     * 
+     * @throws IOException signals that an I/O exception has occurred during
+     * writing or opening the file.
+     */
+    public void write(String fileName) throws IOException {
+        FileOutputStream oStream = new FileOutputStream(fileName);
+        oStream.write(getData());
+        oStream.close();
+    }
+
+    /**
+     * Serializable implementation.
+     * 
+     * @param s the s
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private void writeObject(ObjectOutputStream s) throws IOException {
+        s.defaultWriteObject();
+        s.writeObject(null);
+        s.writeObject(getData());
+    }
+
+    /**
+     * Serializable implementation.
+     * 
+     * @param s the s
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        String colorSpaceStr = (String)s.readObject();
+        byte[] data = (byte[])s.readObject();
+
+        if (colorSpaceStr != null) {
+            if (colorSpaceStr.equals("CS_sRGB")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_sRGB);
+            } else if (colorSpaceStr.equals("CS_GRAY")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_GRAY);
+            } else if (colorSpaceStr.equals("CS_LINEAR_RGB")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_LINEAR_RGB);
+            } else if (colorSpaceStr.equals("CS_CIEXYZ")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_CIEXYZ);
+            } else if (colorSpaceStr.equals("CS_PYCC")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_PYCC);
+            } else {
+                openedProfileObject = ICC_Profile.getInstance(data);
+            }
+        } else {
+            openedProfileObject = ICC_Profile.getInstance(data);
+        }
+    }
+
+    /**
+     * Resolves instances being deserialized into instances registered with CMM.
+     * 
+     * @return ICC_Profile object for profile registered with CMM.
+     * 
+     * @throws ObjectStreamException if there is an error in the serialized 
+     * files or during the process of reading them.
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        return openedProfileObject;
+    }
+
+    /**
+     * Writes the ICC_Profile to an OutputStream.
+     * 
+     * @param s the OutputStream.
+     * 
+     * @throws IOException signals that an I/O exception has occurred during
+     * writing or opening OutputStream.
+     */
+    public void write(OutputStream s) throws IOException {
+        s.write(getData());
+    }
+
+    /**
+     * Sets a tagged data element in the profile from a byte array. 
+     * 
+     * @param tagSignature the ICC tag signature for the data element to be set. 
+     * @param tagData the data to be set for the specified tag signature.
+     */
+    public void setData(int tagSignature, byte[] tagData) {
+        NativeCMM.cmmSetProfileElement(profileHandle, tagSignature, tagData);
+        // Remove cached header data if header is modified
+        if (tagSignature == icSigHead) {
+            headerData = null;
+        }
+    }
+
+    /**
+     * Gets a tagged data element from the profile as a byte array. 
+     * Elements are identified by tag signatures as defined in 
+     * the ICC specification. 
+     * 
+     * @param tagSignature the ICC tag signature for the data element to get.
+     * 
+     * @return a byte array that contains the tagged data element.
+     */
+    public byte[] getData(int tagSignature) {
+        int tagSize = 0;
+        try {
+            tagSize = NativeCMM.cmmGetProfileElementSize(
+                    profileHandle,
+                    tagSignature
+                );
+        } catch (CMMException e) {
+            // We'll get this exception if there's no element with
+            // the specified tag signature
+            return null;
+        }
+
+        byte[] data = new byte[tagSize];
+        NativeCMM.cmmGetProfileElement(profileHandle, tagSignature, data);
+        return data;
+    }
+
+    /**
+     * Gets a data byte array of this ICC_Profile.
+     * 
+     * @return a byte array that contains the ICC Profile data.
+     */
+    public byte[] getData() {
+        int profileSize = NativeCMM.cmmGetProfileSize(profileHandle);
+        byte[] data = new byte[profileSize];
+        NativeCMM.cmmGetProfile(profileHandle, data);
+        return data;
+    }
+
+    /**
+     * Frees the resources associated with an ICC_Profile object.
+     */
+    @Override
+    protected void finalize() {
+        if (profileHandle!=0 && !handleStolen) {
+            NativeCMM.cmmCloseProfile(profileHandle);
+        }
+
+        // Always remove because key no more exist
+        // when object is destroyed
+        NativeCMM.removeHandle(this);
+    }
+
+    /**
+     * Gets the profile class.
+     * 
+     * @return the profile class constant.
+     */
+    public int getProfileClass() {
+        int deviceClassSignature = getIntFromHeader(icHdrDeviceClass);
+
+        switch (deviceClassSignature) {
+            case icSigColorSpaceClass:
+                return CLASS_COLORSPACECONVERSION;
+            case icSigDisplayClass:
+                return CLASS_DISPLAY;
+            case icSigOutputClass:
+                return CLASS_OUTPUT;
+            case icSigInputClass:
+                return CLASS_INPUT;
+            case icSigLinkClass:
+                return CLASS_DEVICELINK;
+            case icSigAbstractClass:
+                return CLASS_ABSTRACT;
+            case icSigNamedColorClass:
+                return CLASS_NAMEDCOLOR;
+            default:
+        }
+
+        // Not an ICC profile class
+        // awt.15F=Profile class does not comply with ICC specification
+        throw new IllegalArgumentException(Messages.getString("awt.15F")); //$NON-NLS-1$
+        
+    }
+
+    /**
+     * Returns the color space type of the Profile Connection Space (PCS).
+     * 
+     * @return the PCS type.
+     */
+    public int getPCSType() {
+         return csFromSignature(getIntFromHeader(icHdrPcs));
+    }
+
+    /**
+     * Gets the number of components of this ICC Profile.
+     * 
+     * @return the number of components of this ICC Profile.
+     */
+    public int getNumComponents() {
+        switch (getIntFromHeader(icHdrColorSpace)) {
+            // The most common cases go first to increase speed
+            case icSigRgbData:
+            case icSigXYZData:
+            case icSigLabData:
+                return 3;
+            case icSigCmykData:
+                return 4;
+                // Then all other
+            case icSigGrayData:
+                return 1;
+            case icSigSpace2CLR:
+                return 2;
+            case icSigYCbCrData:
+            case icSigLuvData:
+            case icSigYxyData:
+            case icSigHlsData:
+            case icSigHsvData:
+            case icSigCmyData:
+            case icSigSpace3CLR:
+                return 3;
+            case icSigSpace4CLR:
+                return 4;
+            case icSigSpace5CLR:
+                return 5;
+            case icSigSpace6CLR:
+                return 6;
+            case icSigSpace7CLR:
+                return 7;
+            case icSigSpace8CLR:
+                return 8;
+            case icSigSpace9CLR:
+                return 9;
+            case icSigSpaceACLR:
+                return 10;
+            case icSigSpaceBCLR:
+                return 11;
+            case icSigSpaceCCLR:
+                return 12;
+            case icSigSpaceDCLR:
+                return 13;
+            case icSigSpaceECLR:
+                return 14;
+            case icSigSpaceFCLR:
+                return 15;
+            default:
+        }
+
+        // awt.160=Color space doesn't comply with ICC specification
+        throw new ProfileDataException(Messages.getString("awt.160") //$NON-NLS-1$
+        );
+    }
+
+    /**
+     * Gets the minor version of this ICC profile.
+     * 
+     * @return the minor version of this ICC profile.
+     */
+    public int getMinorVersion() {
+        return getByteFromHeader(icHdrVersion+1);
+    }
+
+    /**
+     * Gets the major version of this ICC profile.
+     * 
+     * @return the major version of this ICC profile.
+     */
+    public int getMajorVersion() {
+        return getByteFromHeader(icHdrVersion);
+    }
+
+    /**
+     * Gets the color space type of this ICC_Profile.
+     * 
+     * @return the color space type.
+     */
+    public int getColorSpaceType() {
+        return csFromSignature(getIntFromHeader(icHdrColorSpace));
+    }
+
+    /**
+     * Tries to open file at the specified path. Path entries can be 
+     * divided by a separator character.
+     * 
+     * @param path the path
+     * @param fileName the file name
+     * 
+     * @return the file input stream
+     */
+    private static FileInputStream tryPath(String path, String fileName) {
+        FileInputStream fiStream = null;
+
+        if (path == null) {
+            return null;
+        }
+
+        StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
+
+        while (st.hasMoreTokens()) {
+            String pathEntry = st.nextToken();
+            try {
+                fiStream = new FileInputStream(pathEntry + File.separatorChar + fileName);
+                if (fiStream != null) {
+                    return fiStream;
+                }
+            } catch (FileNotFoundException e) {}
+        }
+
+        return fiStream;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile from data in the specified file.
+     * 
+     * @param fileName the specified name of file with ICC profile data.
+     * 
+     * @return single instance of ICC_Profile.
+     * 
+     * @throws IOException signals that an I/O error occured while reading the file
+     * or the file doesn't exist.
+     */
+    public static ICC_Profile getInstance(String fileName) throws IOException {
+        final String fName = fileName; // to use in the privileged block
+
+        FileInputStream fiStream = (FileInputStream) AccessController.doPrivileged(
+                new PrivilegedAction<FileInputStream>() {
+                    public FileInputStream run() {
+                        FileInputStream fiStream = null;
+
+                        // Open absolute path
+                        try {
+                            fiStream = new FileInputStream(fName);
+                            if (fiStream != null) {
+                                return fiStream;
+                            }
+                        } catch (FileNotFoundException e) {}
+
+                        // Check java.iccprofile.path entries
+                        fiStream = tryPath(System.getProperty("java.iccprofile.path"), fName); //$NON-NLS-1$
+                        if (fiStream != null) {
+                            return fiStream;
+                        }
+
+                        // Check java.class.path entries
+                        fiStream = tryPath(System.getProperty("java.class.path"), fName); //$NON-NLS-1$
+                        if (fiStream != null) {
+                            return fiStream;
+                        }
+
+                        // Check directory with java sample profiles
+                        String home = System.getProperty("java.home"); //$NON-NLS-1$
+                        if (home != null) {
+                            fiStream = tryPath(
+                                    home + File.separatorChar +
+                                    "lib" + File.separatorChar + "cmm", fName //$NON-NLS-1$ //$NON-NLS-2$
+                            );
+                        }
+
+                        return fiStream;
+                    }
+                });
+
+        if (fiStream == null) {
+            // awt.161=Unable to open file {0}
+            throw new IOException(Messages.getString("awt.161", fileName)); //$NON-NLS-1$
+        }
+
+        ICC_Profile pf = getInstance(fiStream);
+        fiStream.close();
+        return pf;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile with data in
+     * the specified InputStream.
+     * 
+     * @param s the InputStream with ICC profile data.
+     * 
+     * @return single instance of ICC_Profile.
+     * 
+     * @throws IOException if an I/O exception has occurred during reading 
+     * from InputStream.
+     * @throws IllegalArgumentException if the file does not contain valid 
+     * ICC Profile data.
+     */
+    public static ICC_Profile getInstance(InputStream s) throws IOException {
+        byte[] header = new byte[headerSize];
+        // awt.162=Invalid ICC Profile Data
+        String invalidDataMessage = Messages.getString("awt.162"); //$NON-NLS-1$
+
+        // Get header from the input stream
+        if (s.read(header) != headerSize) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        // Check the profile data for consistency
+        if (
+                ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrMagic) !=
+                headerMagicNumber
+        ) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        // Get profile size from header, create an array for profile data
+        int profileSize = ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrSize);
+        byte[] profileData = new byte[profileSize];
+
+        // Copy header into it
+        System.arraycopy(header, 0, profileData, 0, headerSize);
+
+        // Read the profile itself
+        if (
+                s.read(profileData, headerSize, profileSize - headerSize) !=
+                profileSize - headerSize
+        ) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        return getInstance(profileData);
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile from the specified data in 
+     * a byte array.
+     * 
+     * @param data the byte array of ICC profile.
+     * 
+     * @return single instance of ICC_Profile from the specified data in 
+     * a byte array.
+     * 
+     * @throws IllegalArgumentException if the file does not contain valid 
+     * ICC Profile data.
+     */
+    public static ICC_Profile getInstance(byte[] data) {
+        ICC_Profile res = null;
+
+        try {
+            res = new ICC_Profile(data);
+        } catch (CMMException e) {
+            // awt.162=Invalid ICC Profile Data
+            throw new IllegalArgumentException(Messages.getString("awt.162")); //$NON-NLS-1$
+        }
+
+      if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$
+        try {
+            if ( res.getColorSpaceType () == ColorSpace.TYPE_RGB &&
+                 res.getDataSize(icSigMediaWhitePointTag) > 0 &&
+                 res.getDataSize(icSigRedColorantTag) > 0 &&
+                 res.getDataSize(icSigGreenColorantTag) > 0 &&
+                 res.getDataSize(icSigBlueColorantTag) > 0 &&
+                 res.getDataSize(icSigRedTRCTag) > 0 &&
+                 res.getDataSize(icSigGreenTRCTag) > 0 &&
+                 res.getDataSize(icSigBlueTRCTag) > 0
+                ) {
+                res = new ICC_ProfileRGB(res.getProfileHandle());
+            } else if ( res.getColorSpaceType () == ColorSpace.TYPE_GRAY &&
+                        res.getDataSize(icSigMediaWhitePointTag) > 0 &&
+                        res.getDataSize(icSigGrayTRCTag) > 0
+                ) {
+                res = new ICC_ProfileGray (res.getProfileHandle());
+            }
+
+        } catch (CMMException e) { /* return res in this case */ }
+      }
+
+      return res;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile with the specific color space
+     * defined by the ColorSpace class: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ,
+     * CS_PYCC, CS_GRAY.
+     * 
+     * @param cspace the type of color space defined in the ColorSpace class.
+     * 
+     * @return single instance of ICC_Profile.
+     * 
+     * @throws IllegalArgumentException is not one of the defined color 
+     * space types.
+     */
+    public static ICC_Profile getInstance(int cspace) {
+    try {
+      switch (cspace) {
+
+      case ColorSpace.CS_sRGB:
+        if (sRGBProfile == null) {
+            sRGBProfile = getInstance("sRGB.pf"); //$NON-NLS-1$
+        }
+        return sRGBProfile;
+
+      case ColorSpace.CS_CIEXYZ:
+        if (xyzProfile == null) {
+            xyzProfile = getInstance("CIEXYZ.pf"); //$NON-NLS-1$
+        }
+        return xyzProfile;
+
+      case ColorSpace.CS_GRAY:
+        if (grayProfile == null) {
+            grayProfile = getInstance("GRAY.pf"); //$NON-NLS-1$
+        }
+        return grayProfile;
+
+      case ColorSpace.CS_PYCC:
+        if (pyccProfile == null) {
+            pyccProfile = getInstance("PYCC.pf"); //$NON-NLS-1$
+        }
+        return pyccProfile;
+
+      case ColorSpace.CS_LINEAR_RGB:
+        if (linearRGBProfile == null) {
+            linearRGBProfile = getInstance("LINEAR_RGB.pf"); //$NON-NLS-1$
+        }
+        return linearRGBProfile;
+      }
+
+    } catch (IOException e) {
+        // awt.163=Can't open color profile 
+        throw new IllegalArgumentException(Messages.getString("Can't open color profile")); //$NON-NLS-1$
+    }
+
+    // awt.164=Not a predefined color space
+    throw new IllegalArgumentException(Messages.getString("Not a predefined color space")); //$NON-NLS-1$
+  }
+
+    /**
+     * Reads an integer from the profile header at the specified position.
+     * 
+     * @param idx - offset in bytes from the beginning of the header
+     * 
+     * @return the int from header
+     */
+    private int getIntFromHeader(int idx) {
+        if (headerData == null) {
+            headerData = getData(icSigHead);
+        }
+
+        return  ((headerData[idx]   & 0xFF) << 24)|
+                  ((headerData[idx+1] & 0xFF) << 16)|
+                  ((headerData[idx+2] & 0xFF) << 8) |
+                  ((headerData[idx+3] & 0xFF));
+    }
+
+    /**
+     * Reads byte from the profile header at the specified position.
+     * 
+     * @param idx - offset in bytes from the beginning of the header
+     * 
+     * @return the byte from header
+     */
+    private byte getByteFromHeader(int idx) {
+        if (headerData == null) {
+            headerData = getData(icSigHead);
+        }
+
+        return headerData[idx];
+    }
+
+    /**
+     * Converts ICC color space signature to the java predefined
+     * color space type.
+     * 
+     * @param signature the signature
+     * 
+     * @return the int
+     */
+    private int csFromSignature(int signature) {
+        switch (signature) {
+            case icSigRgbData:
+                return ColorSpace.TYPE_RGB;
+            case icSigXYZData:
+                return ColorSpace.TYPE_XYZ;
+            case icSigCmykData:
+                return ColorSpace.TYPE_CMYK;
+            case icSigLabData:
+                return ColorSpace.TYPE_Lab;
+            case icSigGrayData:
+                return ColorSpace.TYPE_GRAY;
+            case icSigHlsData:
+                return ColorSpace.TYPE_HLS;
+            case icSigLuvData:
+                return ColorSpace.TYPE_Luv;
+            case icSigYCbCrData:
+                return ColorSpace.TYPE_YCbCr;
+            case icSigYxyData:
+                return ColorSpace.TYPE_Yxy;
+            case icSigHsvData:
+                return ColorSpace.TYPE_HSV;
+            case icSigCmyData:
+                return ColorSpace.TYPE_CMY;
+            case icSigSpace2CLR:
+                return ColorSpace.TYPE_2CLR;
+            case icSigSpace3CLR:
+                return ColorSpace.TYPE_3CLR;
+            case icSigSpace4CLR:
+                return ColorSpace.TYPE_4CLR;
+            case icSigSpace5CLR:
+                return ColorSpace.TYPE_5CLR;
+            case icSigSpace6CLR:
+                return ColorSpace.TYPE_6CLR;
+            case icSigSpace7CLR:
+                return ColorSpace.TYPE_7CLR;
+            case icSigSpace8CLR:
+                return ColorSpace.TYPE_8CLR;
+            case icSigSpace9CLR:
+                return ColorSpace.TYPE_9CLR;
+            case icSigSpaceACLR:
+                return ColorSpace.TYPE_ACLR;
+            case icSigSpaceBCLR:
+                return ColorSpace.TYPE_BCLR;
+            case icSigSpaceCCLR:
+                return ColorSpace.TYPE_CCLR;
+            case icSigSpaceDCLR:
+                return ColorSpace.TYPE_DCLR;
+            case icSigSpaceECLR:
+                return ColorSpace.TYPE_ECLR;
+            case icSigSpaceFCLR:
+                return ColorSpace.TYPE_FCLR;
+            default:
+        }
+
+        // awt.165=Color space doesn't comply with ICC specification
+        throw new IllegalArgumentException (Messages.getString("awt.165")); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the profile handle.
+     * 
+     * @return the profile handle
+     */
+    private long getProfileHandle() {
+        handleStolen = true;
+        return profileHandle;
+    }
+
+    /**
+     * Gets the data size.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the data size
+     */
+    private int getDataSize(int tagSignature) {
+        return NativeCMM.cmmGetProfileElementSize(
+                profileHandle,
+                tagSignature
+            );
+    }
+
+    /**
+     * Reads XYZ value from the tag data.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the XYZ value
+     */
+    float[] getXYZValue(int tagSignature) {
+        float[] res = new float[3];
+        byte[] data = getData(tagSignature);
+
+        // Convert from ICC s15Fixed16Number type
+        // 1 (float) = 0x10000 (s15Fixed16Number),
+        // hence dividing by 0x10000
+        res[0] = ICC_ProfileHelper.getIntFromByteArray(data, 0) / 65536.f;
+        res[1] = ICC_ProfileHelper.getIntFromByteArray(data, 4) / 65536.f;
+        res[2] = ICC_ProfileHelper.getIntFromByteArray(data, 8) / 65536.f;
+
+        return res;
+    }
+
+    /**
+     * Gets the media white point.
+     * 
+     * @return the media white point
+     */
+    float[] getMediaWhitePoint() {
+        return getXYZValue(icSigMediaWhitePointTag);
+    }
+
+    /**
+     * If TRC is not a table returns gamma via return value
+     * and sets dataTRC to null. If TRC is a table returns 0
+     * and fills dataTRC with values.
+     * 
+     * @param tagSignature the tag signature
+     * @param dataTRC the data trc
+     * 
+     * @return - gamma or zero if TRC is a table
+     */
+    private float getGammaOrTRC(int tagSignature, short[] dataTRC) {
+        byte[] data = getData(tagSignature);
+        int trcSize = ICC_ProfileHelper.getIntFromByteArray(data, icCurveCount);
+
+        dataTRC = null;
+
+        if (trcSize == 0) {
+            return 1.0f;
+        }
+
+        if (trcSize == 1) {
+            // Cast from ICC u8Fixed8Number to float
+            return ICC_ProfileHelper.getShortFromByteArray(data, icCurveData) / 256.f;
+        }
+
+        // TRC is a table
+        dataTRC = new short[trcSize];
+        for (int i = 0, pos = icCurveData; i < trcSize; i++, pos += 2) {
+            dataTRC[i] = ICC_ProfileHelper.getShortFromByteArray(data, pos);
+        }
+        return 0;
+    }
+
+    /**
+     * Gets the gamma.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the gamma
+     */
+    float getGamma(int tagSignature) {
+        short[] dataTRC = null;
+        float gamma = getGammaOrTRC(tagSignature, dataTRC);
+
+        if (dataTRC == null) {
+            return gamma;
+        }
+        // awt.166=TRC is not a simple gamma value.
+        throw new ProfileDataException(Messages.getString("awt.166")); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the tRC.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the tRC
+     */
+    short[] getTRC(int tagSignature) {
+        short[] dataTRC = null;
+        getGammaOrTRC(tagSignature, dataTRC);
+
+        if (dataTRC == null) {
+            // awt.167=TRC is a gamma value, not a table.
+            throw new ProfileDataException(Messages.getString("awt.167")); //$NON-NLS-1$
+        }
+        return dataTRC;
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileGray.java b/awt/java/awt/color/ICC_ProfileGray.java
new file mode 100644
index 0000000..f009b18
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileGray.java
@@ -0,0 +1,68 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The ICC_ProfileGray class represent profiles with TYPE_GRAY color space type,
+ * and includes the grayTRCTag and mediaWhitePointTag tags. 
+ * 
+ * The gray component can be transformed from a GRAY device profile color space 
+ * to the CIEXYZ Profile through the tone reproduction curve (TRC): 
+ * <p>PCSY = grayTRC[deviceGray]
+ */
+public class ICC_ProfileGray extends ICC_Profile {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1124721290732002649L;
+
+    /**
+     * Instantiates a new iC c_ profile gray.
+     * 
+     * @param profileHandle the profile handle
+     */
+    ICC_ProfileGray(long profileHandle) {
+        super(profileHandle);
+    }
+
+    /**
+     * Gets the TRC as an array of shorts.
+     * 
+     * @return a short array of the TRC.
+     */
+    public short[] getTRC() {
+        return super.getTRC(icSigGrayTRCTag);
+    }
+
+    @Override
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+
+    /**
+     * Gets a gamma value representing the tone reproduction curve (TRC).
+     * 
+     * @return the gamma value representing the tone reproduction curve (TRC).
+     */
+    public float getGamma() {
+        return super.getGamma(icSigGrayTRCTag);
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileRGB.java b/awt/java/awt/color/ICC_ProfileRGB.java
new file mode 100644
index 0000000..beb1a0c
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileRGB.java
@@ -0,0 +1,122 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ICC_ProfileRGB class represents profiles with RGB color space type and 
+ * contains the redColorantTag, greenColorantTag, blueColorantTag, redTRCTag, 
+ * greenTRCTag, blueTRCTag, and mediaWhitePointTag tags.
+ */
+public class ICC_ProfileRGB extends ICC_Profile {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8505067385152579334L;
+
+    /**
+     * Instantiates a new iC c_ profile rgb.
+     * 
+     * @param profileHandle the profile handle
+     */
+    ICC_ProfileRGB(long profileHandle) {
+        super(profileHandle);
+    }
+
+    /** The Constant REDCOMPONENT indicates the red component. */
+    public static final int REDCOMPONENT = 0;
+
+    /** The Constant GREENCOMPONENT indicates the green component. */
+    public static final int GREENCOMPONENT = 1;
+
+    /** The Constant BLUECOMPONENT indicates the blue component. */
+    public static final int BLUECOMPONENT = 2;
+
+    // awt.15E=Unknown component. Must be REDCOMPONENT, GREENCOMPONENT or BLUECOMPONENT.
+    /** The Constant UNKNOWN_COMPONENT_MSG. */
+    private static final String UNKNOWN_COMPONENT_MSG = Messages
+            .getString("awt.15E"); //$NON-NLS-1$
+
+    @Override
+    public short[] getTRC(int component) {
+        switch (component) {
+            case REDCOMPONENT:
+                return super.getTRC(icSigRedTRCTag);
+            case GREENCOMPONENT:
+                return super.getTRC(icSigGreenTRCTag);
+            case BLUECOMPONENT:
+                return super.getTRC(icSigBlueTRCTag);
+            default:
+        }
+
+        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
+    }
+
+    @Override
+    public float getGamma(int component) {
+        switch (component) {
+            case REDCOMPONENT:
+                return super.getGamma(icSigRedTRCTag);
+            case GREENCOMPONENT:
+                return super.getGamma(icSigGreenTRCTag);
+            case BLUECOMPONENT:
+                return super.getGamma(icSigBlueTRCTag);
+            default:
+        }
+
+        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
+    }
+
+    /**
+     * Gets a float matrix which contains the X, Y, and Z components of 
+     * the profile's redColorantTag, greenColorantTag, and blueColorantTag.
+     * 
+     * @return a float matrix which contains the X, Y, and Z components of 
+     * the profile's redColorantTag, greenColorantTag, and blueColorantTag.
+     */
+    public float[][] getMatrix() {
+        float [][] m = new float[3][3]; // The matrix
+
+        float[] redXYZ = getXYZValue(icSigRedColorantTag);
+        float[] greenXYZ = getXYZValue(icSigGreenColorantTag);
+        float[] blueXYZ = getXYZValue(icSigBlueColorantTag);
+
+        m[0][0] = redXYZ[0];
+        m[1][0] = redXYZ[1];
+        m[2][0] = redXYZ[2];
+
+        m[0][1] = greenXYZ[0];
+        m[1][1] = greenXYZ[1];
+        m[2][1] = greenXYZ[2];
+
+        m[0][2] = blueXYZ[0];
+        m[1][2] = blueXYZ[1];
+        m[2][2] = blueXYZ[2];
+
+        return m;
+    }
+
+    @Override
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileStub.java b/awt/java/awt/color/ICC_ProfileStub.java
new file mode 100644
index 0000000..bc04c8a
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileStub.java
@@ -0,0 +1,173 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.color;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectStreamException;
+import java.io.OutputStream;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+final class ICC_ProfileStub extends ICC_Profile {
+    private static final long serialVersionUID = 501389760875253507L;
+
+    transient int colorspace;
+
+    public ICC_ProfileStub(int csSpecifier) {
+        switch (csSpecifier) {
+            case ColorSpace.CS_sRGB:
+            case ColorSpace.CS_CIEXYZ:
+            case ColorSpace.CS_LINEAR_RGB:
+            case ColorSpace.CS_PYCC:
+            case ColorSpace.CS_GRAY:
+                break;
+            default:
+                // awt.15D=Invalid colorspace
+                throw new IllegalArgumentException(Messages.getString("awt.15D")); //$NON-NLS-1$
+        }
+        colorspace = csSpecifier;
+    }
+
+    @Override
+    public void write(String fileName) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    /**
+     * Serializable implementation
+     *
+     * @throws ObjectStreamException
+     */
+    private Object writeReplace() throws ObjectStreamException {
+        return loadProfile();
+    }
+
+    @Override
+    public void write(OutputStream s) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public void setData(int tagSignature, byte[] tagData) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public byte[] getData(int tagSignature) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public byte[] getData() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    protected void finalize() {
+    }
+
+    @Override
+    public int getProfileClass() {
+        return CLASS_COLORSPACECONVERSION;
+    }
+
+    @Override
+    public int getPCSType() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getNumComponents() {
+        switch (colorspace) {
+            case ColorSpace.CS_sRGB:
+            case ColorSpace.CS_CIEXYZ:
+            case ColorSpace.CS_LINEAR_RGB:
+            case ColorSpace.CS_PYCC:
+                return 3;
+            case ColorSpace.CS_GRAY:
+                return 1;
+            default:
+                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public int getMinorVersion() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getMajorVersion() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getColorSpaceType() {
+        switch (colorspace) {
+            case ColorSpace.CS_sRGB:
+            case ColorSpace.CS_LINEAR_RGB:
+                return ColorSpace.TYPE_RGB;
+            case ColorSpace.CS_CIEXYZ:
+                return ColorSpace.TYPE_XYZ;
+            case ColorSpace.CS_PYCC:
+                return ColorSpace.TYPE_3CLR;
+            case ColorSpace.CS_GRAY:
+                return ColorSpace.TYPE_GRAY;
+            default:
+                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+        }
+    }
+
+    public static ICC_Profile getInstance(String fileName) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public static ICC_Profile getInstance(InputStream s) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public static ICC_Profile getInstance(byte[] data) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public static ICC_Profile getInstance(int cspace) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public ICC_Profile loadProfile() {
+        switch (colorspace) {
+            case ColorSpace.CS_sRGB:
+                return ICC_Profile.getInstance(ColorSpace.CS_sRGB);
+            case ColorSpace.CS_GRAY:
+                return ICC_Profile.getInstance(ColorSpace.CS_GRAY);
+            case ColorSpace.CS_CIEXYZ:
+                return ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
+            case ColorSpace.CS_LINEAR_RGB:
+                return ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB);
+            case ColorSpace.CS_PYCC:
+                return ICC_Profile.getInstance(ColorSpace.CS_PYCC);
+            default:
+                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+        }
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/color/ProfileDataException.java b/awt/java/awt/color/ProfileDataException.java
new file mode 100644
index 0000000..ca169fe
--- /dev/null
+++ b/awt/java/awt/color/ProfileDataException.java
@@ -0,0 +1,42 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The ProfileDataException class represents an error which occurs 
+ * while accessing or processing an ICC_Profile object.
+ */
+public class ProfileDataException extends RuntimeException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 7286140888240322498L;
+
+    /**
+     * Instantiates a new profile data exception with detailed message.
+     * 
+     * @param s the detailed message.
+     */
+    public ProfileDataException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/event/AWTEventListener.java b/awt/java/awt/event/AWTEventListener.java
new file mode 100644
index 0000000..f621c9b
--- /dev/null
+++ b/awt/java/awt/event/AWTEventListener.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.util.EventListener;
+
+public interface AWTEventListener extends EventListener {
+
+    public void eventDispatched(AWTEvent event);
+
+}
diff --git a/awt/java/awt/event/AWTEventListenerProxy.java b/awt/java/awt/event/AWTEventListenerProxy.java
new file mode 100644
index 0000000..5ee5e59
--- /dev/null
+++ b/awt/java/awt/event/AWTEventListenerProxy.java
@@ -0,0 +1,52 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+import java.util.EventListenerProxy;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class AWTEventListenerProxy extends EventListenerProxy implements AWTEventListener {
+
+    private AWTEventListener listener;
+    private long eventMask;
+
+    public AWTEventListenerProxy(long eventMask, AWTEventListener listener) {
+        super(listener);
+
+        // awt.193=Listener can't be zero
+        assert listener != null : Messages.getString("awt.193"); //$NON-NLS-1$
+
+        this.listener = listener;
+        this.eventMask = eventMask;
+    }
+
+    public void eventDispatched(AWTEvent evt) {
+        listener.eventDispatched(evt);
+    }
+
+    public long getEventMask() {
+        return eventMask;
+    }
+
+}
diff --git a/awt/java/awt/event/ActionEvent.java b/awt/java/awt/event/ActionEvent.java
new file mode 100644
index 0000000..c32fc4b
--- /dev/null
+++ b/awt/java/awt/event/ActionEvent.java
@@ -0,0 +1,108 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+public class ActionEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -7671078796273832149L;
+
+    public static final int SHIFT_MASK = 1;
+
+    public static final int CTRL_MASK = 2;
+
+    public static final int META_MASK = 4;
+
+    public static final int ALT_MASK = 8;
+
+    public static final int ACTION_FIRST = 1001;
+
+    public static final int ACTION_LAST = 1001;
+
+    public static final int ACTION_PERFORMED = 1001;
+
+    private long when;
+    private int modifiers;
+    private String command;
+
+    public ActionEvent(Object source, int id, String command) {
+        this(source, id, command, 0);
+    }
+
+    public ActionEvent(Object source, int id, String command, int modifiers) {
+        this(source, id, command, 0l, modifiers);
+    }
+
+    public ActionEvent(Object source, int id, String command, long when, int modifiers) {
+        super(source, id);
+
+        this.command = command;
+        this.when = when;
+        this.modifiers = modifiers;
+    }
+
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    public String getActionCommand() {
+        return command;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ActionEvent e = new ActionEvent(new Component(){},
+         *       ActionEvent.ACTION_PERFORMED, "Command",
+         *       ActionEvent.SHIFT_MASK|ActionEvent.CTRL_MASK|
+         *       ActionEvent.META_MASK|ActionEvent.ALT_MASK);
+         * System.out.println(e);
+         */
+
+        String idString = (id == ACTION_PERFORMED) ? 
+                          "ACTION_PERFORMED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
+        String modifiersString = ""; //$NON-NLS-1$
+
+        if ((modifiers & SHIFT_MASK) > 0) {
+            modifiersString += "Shift"; //$NON-NLS-1$
+        }
+        if ((modifiers & CTRL_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Ctrl" : "+Ctrl"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiers & META_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Meta" : "+Meta"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiers & ALT_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Alt" : "+Alt"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return (idString + ",cmd=" + command + ",when=" + when +  //$NON-NLS-1$ //$NON-NLS-2$
+                ",modifiers=" + modifiersString); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ActionListener.java b/awt/java/awt/event/ActionListener.java
new file mode 100644
index 0000000..473d2b6
--- /dev/null
+++ b/awt/java/awt/event/ActionListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ActionListener extends EventListener {
+
+    public void actionPerformed(ActionEvent e);
+
+}
diff --git a/awt/java/awt/event/AdjustmentEvent.java b/awt/java/awt/event/AdjustmentEvent.java
new file mode 100644
index 0000000..a2b11a8
--- /dev/null
+++ b/awt/java/awt/event/AdjustmentEvent.java
@@ -0,0 +1,117 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Adjustable;
+
+public class AdjustmentEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 5700290645205279921L;
+
+    public static final int ADJUSTMENT_FIRST = 601;
+
+    public static final int ADJUSTMENT_LAST = 601;
+
+    public static final int ADJUSTMENT_VALUE_CHANGED = 601;
+
+    public static final int UNIT_INCREMENT = 1;
+
+    public static final int UNIT_DECREMENT = 2;
+
+    public static final int BLOCK_DECREMENT = 3;
+
+    public static final int BLOCK_INCREMENT = 4;
+
+    public static final int TRACK = 5;
+
+    private int type;
+    private int value;
+    private boolean isAdjusting;
+
+    public AdjustmentEvent(Adjustable source, int id, int type, int value) {
+        this(source, id, type, value, false);
+    }
+
+    public AdjustmentEvent(Adjustable source, int id, int type, int value, 
+                           boolean isAdjusting) {
+        super(source, id);
+        this.type = type;
+        this.value = value;
+        this.isAdjusting = isAdjusting;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public int getAdjustmentType() {
+        return type;
+    }
+
+    public boolean getValueIsAdjusting() {
+        return isAdjusting;
+    }
+
+    public Adjustable getAdjustable() {
+        return (Adjustable) source;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * AdjustmentEvent e = new AdjustmentEvent(new Scrollbar(), 
+         *       AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 
+         *       AdjustmentEvent.UNIT_INCREMENT, 1);
+         * System.out.println(e);
+         */
+
+        String idString = (id == ADJUSTMENT_VALUE_CHANGED ?
+                "ADJUSTMENT_VALUE_CHANGED" : "unknown type"); //$NON-NLS-1$ //$NON-NLS-2$
+        String adjType = null;
+
+        switch (type) {
+        case UNIT_INCREMENT:
+            adjType = "UNIT_INCREMENT"; //$NON-NLS-1$
+            break;
+        case UNIT_DECREMENT:
+            adjType = "UNIT_DECREMENT"; //$NON-NLS-1$
+            break;
+        case BLOCK_INCREMENT:
+            adjType = "BLOCK_INCREMENT"; //$NON-NLS-1$
+            break;
+        case BLOCK_DECREMENT:
+            adjType = "BLOCK_DECREMENT"; //$NON-NLS-1$
+            break;
+        case TRACK:
+            adjType = "TRACK"; //$NON-NLS-1$
+            break;
+        default:
+            adjType = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + ",adjType=" + adjType + ",value=" + value + //$NON-NLS-1$ //$NON-NLS-2$
+                ",isAdjusting=" + isAdjusting); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/AdjustmentListener.java b/awt/java/awt/event/AdjustmentListener.java
new file mode 100644
index 0000000..ef7c378
--- /dev/null
+++ b/awt/java/awt/event/AdjustmentListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface AdjustmentListener extends EventListener {
+
+    public void adjustmentValueChanged(AdjustmentEvent e);
+
+}
diff --git a/awt/java/awt/event/ComponentAdapter.java b/awt/java/awt/event/ComponentAdapter.java
new file mode 100644
index 0000000..4f0bd90
--- /dev/null
+++ b/awt/java/awt/event/ComponentAdapter.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class ComponentAdapter implements ComponentListener {
+
+    public ComponentAdapter() {
+    }
+
+    public void componentHidden(ComponentEvent e) {
+    }
+
+    public void componentMoved(ComponentEvent e) {
+    }
+
+    public void componentResized(ComponentEvent e) {
+    }
+
+    public void componentShown(ComponentEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/ComponentEvent.java b/awt/java/awt/event/ComponentEvent.java
new file mode 100644
index 0000000..d0bca54
--- /dev/null
+++ b/awt/java/awt/event/ComponentEvent.java
@@ -0,0 +1,82 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+
+public class ComponentEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 8101406823902992965L;
+
+    public static final int COMPONENT_FIRST = 100;
+
+    public static final int COMPONENT_LAST = 103;
+
+    public static final int COMPONENT_MOVED = 100;
+
+    public static final int COMPONENT_RESIZED = 101;
+
+    public static final int COMPONENT_SHOWN = 102;
+
+    public static final int COMPONENT_HIDDEN = 103;
+
+    public ComponentEvent(Component source, int id) {
+        super(source, id);
+    }
+
+    public Component getComponent() {
+        return (Component) source;
+    }
+    
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ComponentEvent e = new ComponentEvent(new Button("Button"), 
+         *          ComponentEvent.COMPONENT_SHOWN);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        Component c = getComponent();
+
+        switch (id) {
+        case COMPONENT_MOVED:
+            idString = "COMPONENT_MOVED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_RESIZED:
+            idString = "COMPONENT_RESIZED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_SHOWN:
+            return "COMPONENT_SHOWN"; //$NON-NLS-1$
+        case COMPONENT_HIDDEN:
+            return "COMPONENT_HIDDEN"; //$NON-NLS-1$
+        default:
+            return "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + " (" + c.getX() + "," + c.getY() +  //$NON-NLS-1$ //$NON-NLS-2$
+                " " + c.getWidth()+ "x" + c.getHeight() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+}
diff --git a/awt/java/awt/event/ComponentListener.java b/awt/java/awt/event/ComponentListener.java
new file mode 100644
index 0000000..147e9e0
--- /dev/null
+++ b/awt/java/awt/event/ComponentListener.java
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ComponentListener extends EventListener {
+
+    public void componentHidden(ComponentEvent e);
+
+    public void componentMoved(ComponentEvent e);
+
+    public void componentResized(ComponentEvent e);
+
+    public void componentShown(ComponentEvent e);
+
+}
diff --git a/awt/java/awt/event/ContainerAdapter.java b/awt/java/awt/event/ContainerAdapter.java
new file mode 100644
index 0000000..12dc3de
--- /dev/null
+++ b/awt/java/awt/event/ContainerAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class ContainerAdapter implements ContainerListener {
+
+    public ContainerAdapter() {
+    }
+
+    public void componentAdded(ContainerEvent e) {
+    }
+
+    public void componentRemoved(ContainerEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/ContainerEvent.java b/awt/java/awt/event/ContainerEvent.java
new file mode 100644
index 0000000..1a1055c
--- /dev/null
+++ b/awt/java/awt/event/ContainerEvent.java
@@ -0,0 +1,83 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+//???AWT: import java.awt.Container;
+
+public class ContainerEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -4114942250539772041L;
+
+    public static final int CONTAINER_FIRST = 300;
+
+    public static final int CONTAINER_LAST = 301;
+
+    public static final int COMPONENT_ADDED = 300;
+
+    public static final int COMPONENT_REMOVED = 301;
+
+    private Component child;
+
+    public ContainerEvent(Component src, int id, Component child) {
+        super(src, id);
+        this.child = child;
+    }
+
+    public Component getChild() {
+        return child;
+    }
+
+    //???AWT
+    /*
+    public Container getContainer() {
+        return (Container) source;
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ContainerEvent e = new ContainerEvent(new Panel(),
+         *          ContainerEvent.COMPONENT_ADDED,
+         *          new Button("Button"));
+         * System.out.println(e);
+         */
+
+        String idString = null;
+
+        switch (id) {
+        case COMPONENT_ADDED:
+            idString = "COMPONENT_ADDED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_REMOVED:
+            idString = "COMPONENT_REMOVED"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + ",child=" + child.getName()); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ContainerListener.java b/awt/java/awt/event/ContainerListener.java
new file mode 100644
index 0000000..bf47664
--- /dev/null
+++ b/awt/java/awt/event/ContainerListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ContainerListener extends EventListener {
+
+    public void componentAdded(ContainerEvent e);
+
+    public void componentRemoved(ContainerEvent e);
+
+}
diff --git a/awt/java/awt/event/FocusAdapter.java b/awt/java/awt/event/FocusAdapter.java
new file mode 100644
index 0000000..3489e11
--- /dev/null
+++ b/awt/java/awt/event/FocusAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class FocusAdapter implements FocusListener {
+
+    public FocusAdapter() {
+    }
+
+    public void focusGained(FocusEvent e) {
+    }
+
+    public void focusLost(FocusEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/FocusEvent.java b/awt/java/awt/event/FocusEvent.java
new file mode 100644
index 0000000..1db5263
--- /dev/null
+++ b/awt/java/awt/event/FocusEvent.java
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+public class FocusEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = 523753786457416396L;
+
+    public static final int FOCUS_FIRST = 1004;
+
+    public static final int FOCUS_LAST = 1005;
+
+    public static final int FOCUS_GAINED = 1004;
+
+    public static final int FOCUS_LOST = 1005;
+
+    private boolean temporary;
+    private Component opposite;
+
+    public FocusEvent(Component source, int id) {
+        this(source, id, false);
+    }
+
+    public FocusEvent(Component source, int id, boolean temporary) {
+        this(source, id, temporary, null);
+    }
+
+    public FocusEvent(Component source, int id, boolean temporary, Component opposite) {
+        super(source, id);
+        this.temporary = temporary;
+        this.opposite = opposite;
+    }
+
+    public Component getOppositeComponent() {
+        return opposite;
+    }
+
+    public boolean isTemporary() {
+        return temporary;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * FocusEvent e = new FocusEvent(new Button("Button0"),
+         *       FocusEvent.FOCUS_GAINED, false, new Button("Button1"));
+         * System.out.println(e);
+         */
+
+        String idString = null;
+
+        switch (id) {
+        case FOCUS_GAINED:
+            idString = "FOCUS_GAINED"; //$NON-NLS-1$
+            break;
+        case FOCUS_LOST:
+            idString = "FOCUS_LOST"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString +
+                (temporary ? ",temporary" : ",permanent") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",opposite=" + opposite); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/FocusListener.java b/awt/java/awt/event/FocusListener.java
new file mode 100644
index 0000000..ee98d90
--- /dev/null
+++ b/awt/java/awt/event/FocusListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface FocusListener extends EventListener {
+
+    public void focusGained(FocusEvent e);
+
+    public void focusLost(FocusEvent e);
+
+}
diff --git a/awt/java/awt/event/HierarchyBoundsAdapter.java b/awt/java/awt/event/HierarchyBoundsAdapter.java
new file mode 100644
index 0000000..24e3d9d
--- /dev/null
+++ b/awt/java/awt/event/HierarchyBoundsAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class HierarchyBoundsAdapter implements HierarchyBoundsListener {
+
+    public HierarchyBoundsAdapter() {
+    }
+
+    public void ancestorMoved(HierarchyEvent e) {
+    }
+
+    public void ancestorResized(HierarchyEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/HierarchyBoundsListener.java b/awt/java/awt/event/HierarchyBoundsListener.java
new file mode 100644
index 0000000..4288f52
--- /dev/null
+++ b/awt/java/awt/event/HierarchyBoundsListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface HierarchyBoundsListener extends EventListener {
+
+    public void ancestorMoved(HierarchyEvent e);
+
+    public void ancestorResized(HierarchyEvent e);
+
+}
diff --git a/awt/java/awt/event/HierarchyEvent.java b/awt/java/awt/event/HierarchyEvent.java
new file mode 100644
index 0000000..1881667
--- /dev/null
+++ b/awt/java/awt/event/HierarchyEvent.java
@@ -0,0 +1,148 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+//???AWT: import java.awt.Container;
+
+public class HierarchyEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -5337576970038043990L;
+
+    public static final int HIERARCHY_FIRST = 1400;
+
+    public static final int HIERARCHY_CHANGED = 1400;
+
+    public static final int ANCESTOR_MOVED = 1401;
+
+    public static final int ANCESTOR_RESIZED = 1402;
+
+    public static final int HIERARCHY_LAST = 1402;
+
+    public static final int PARENT_CHANGED = 1;
+
+    public static final int DISPLAYABILITY_CHANGED = 2;
+
+    public static final int SHOWING_CHANGED = 4;
+
+    //???AWT: private Container changedParent;
+    private Component changed;
+    private long changeFlag;
+
+    //???AWT
+    /*
+    public HierarchyEvent(Component source, int id, Component changed, 
+                          Container changedParent) {
+        this(source, id, changed, changedParent, 0l);
+    }
+    */
+
+    //???AWT
+    /*
+    public HierarchyEvent(Component source, int id, Component changed,
+            Container changedParent, long changeFlags) {
+        super(source, id);
+
+        this.changed = changed;
+        this.changedParent = changedParent;
+        this.changeFlag = changeFlags;
+    }
+    */
+    //???AWT: Fake constructor, should be as above.
+    public HierarchyEvent(Component source, int id, Component changed,
+            Object changedParent, long changeFlags) {
+        super(source, id);
+
+//        this.changed = changed;
+//        this.changedParent = changedParent;
+//        this.changeFlag = changeFlags;
+    }
+    
+    public Component getComponent() {
+        return (Component) source;
+    }
+
+    public long getChangeFlags() {
+        return changeFlag;
+    }
+
+    public Component getChanged() {
+        return changed;
+    }
+
+    //???AWT
+    /*
+    public Container getChangedParent() {
+        return changedParent;
+
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * HierarchyEvent e = new HierarchyEvent(new Button("Button"),
+         *          HierarchyEvent.HIERARCHY_CHANGED,
+         *          new Panel(), new Container());
+         * System.out.println(e);
+         */
+        String paramString = null;
+
+        switch (id) {
+        case HIERARCHY_CHANGED:
+            paramString = "HIERARCHY_CHANGED"; //$NON-NLS-1$
+            break;
+        case ANCESTOR_MOVED:
+            paramString = "ANCESTOR_MOVED"; //$NON-NLS-1$
+            break;
+        case ANCESTOR_RESIZED:
+            paramString = "ANCESTOR_RESIZED"; //$NON-NLS-1$
+            break;
+        default:
+            paramString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString += " ("; //$NON-NLS-1$
+
+        if (id == HIERARCHY_CHANGED) {
+            if ((changeFlag & PARENT_CHANGED) > 0) {
+                paramString += "PARENT_CHANGED,"; //$NON-NLS-1$
+            }
+            if ((changeFlag & DISPLAYABILITY_CHANGED) > 0) {
+                paramString += "DISPLAYABILITY_CHANGED,"; //$NON-NLS-1$
+            }
+            if ((changeFlag & SHOWING_CHANGED) > 0) {
+                paramString += "SHOWING_CHANGED,"; //$NON-NLS-1$
+            }
+        }
+
+        //???AWT
+        /*
+        return paramString + "changed=" + changed +  //$NON-NLS-1$
+                ",changedParent=" + changedParent + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+        */
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/HierarchyListener.java b/awt/java/awt/event/HierarchyListener.java
new file mode 100644
index 0000000..e01ba11
--- /dev/null
+++ b/awt/java/awt/event/HierarchyListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface HierarchyListener extends EventListener {
+
+    public void hierarchyChanged(HierarchyEvent e);
+
+}
diff --git a/awt/java/awt/event/InputEvent.java b/awt/java/awt/event/InputEvent.java
new file mode 100644
index 0000000..c98382d
--- /dev/null
+++ b/awt/java/awt/event/InputEvent.java
@@ -0,0 +1,184 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+public abstract class InputEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -2482525981698309786L;
+
+    public static final int SHIFT_MASK = 1;
+
+    public static final int CTRL_MASK = 2;
+
+    public static final int META_MASK = 4;
+
+    public static final int ALT_MASK = 8;
+
+    public static final int ALT_GRAPH_MASK = 32;
+
+    public static final int BUTTON1_MASK = 16;
+
+    public static final int BUTTON2_MASK = 8;
+
+    public static final int BUTTON3_MASK = 4;
+
+    public static final int SHIFT_DOWN_MASK = 64;
+
+    public static final int CTRL_DOWN_MASK = 128;
+
+    public static final int META_DOWN_MASK = 256;
+
+    public static final int ALT_DOWN_MASK = 512;
+
+    public static final int BUTTON1_DOWN_MASK = 1024;
+
+    public static final int BUTTON2_DOWN_MASK = 2048;
+
+    public static final int BUTTON3_DOWN_MASK = 4096;
+
+    public static final int ALT_GRAPH_DOWN_MASK = 8192;
+
+    private static final int DOWN_MASKS = SHIFT_DOWN_MASK | CTRL_DOWN_MASK |
+            META_DOWN_MASK | ALT_DOWN_MASK | BUTTON1_DOWN_MASK |
+            BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK | ALT_GRAPH_DOWN_MASK;
+
+    private long when;
+    private int modifiersEx;
+
+    public static String getModifiersExText(int modifiers/*Ex*/) {
+        return MouseEvent.addMouseModifiersExText(
+                KeyEvent.getKeyModifiersExText(modifiers), modifiers);
+    }
+
+    static int extractExFlags(int modifiers) {
+        int exFlags = modifiers & DOWN_MASKS;
+
+        if ((modifiers & SHIFT_MASK) != 0) {
+            exFlags |= SHIFT_DOWN_MASK;
+        }
+        if ((modifiers & CTRL_MASK) != 0) {
+            exFlags |= CTRL_DOWN_MASK;
+        }
+        if ((modifiers & META_MASK) != 0) {
+            exFlags |= META_DOWN_MASK;
+        }
+        if ((modifiers & ALT_MASK) != 0) {
+            exFlags |= ALT_DOWN_MASK;
+        }
+        if ((modifiers & ALT_GRAPH_MASK) != 0) {
+            exFlags |= ALT_GRAPH_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON1_MASK) != 0) {
+            exFlags |= BUTTON1_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON2_MASK) != 0) {
+            exFlags |= BUTTON2_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON3_MASK) != 0) {
+            exFlags |= BUTTON3_DOWN_MASK;
+        }
+
+        return exFlags;
+    }
+
+    InputEvent(Component source, int id, long when, int modifiers) {
+        super(source, id);
+
+        this.when = when;
+        modifiersEx = extractExFlags(modifiers);
+    }
+
+    public int getModifiers() {
+        int modifiers = 0;
+
+        if ((modifiersEx & SHIFT_DOWN_MASK) != 0) {
+            modifiers |= SHIFT_MASK;
+        }
+        if ((modifiersEx & CTRL_DOWN_MASK) != 0) {
+            modifiers |= CTRL_MASK;
+        }
+        if ((modifiersEx & META_DOWN_MASK) != 0) {
+            modifiers |= META_MASK;
+        }
+        if ((modifiersEx & ALT_DOWN_MASK) != 0) {
+            modifiers |= ALT_MASK;
+        }
+        if ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0) {
+            modifiers |= ALT_GRAPH_MASK;
+        }
+        if ((modifiersEx & BUTTON1_DOWN_MASK) != 0) {
+            modifiers |= BUTTON1_MASK;
+        }
+        if ((modifiersEx & BUTTON2_DOWN_MASK) != 0) {
+            modifiers |= BUTTON2_MASK;
+        }
+        if ((modifiersEx & BUTTON3_DOWN_MASK) != 0) {
+            modifiers |= BUTTON3_MASK;
+        }
+
+        return modifiers;
+    }
+
+    public int getModifiersEx() {
+        return modifiersEx;
+    }
+
+    void setModifiers(int modifiers) {
+        modifiersEx = extractExFlags(modifiers);
+    }
+
+    public boolean isAltDown() {
+        return ((modifiersEx & ALT_DOWN_MASK) != 0);
+    }
+
+    public boolean isAltGraphDown() {
+        return ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0);
+    }
+
+    public boolean isControlDown() {
+        return ((modifiersEx & CTRL_DOWN_MASK) != 0);
+    }
+
+    public boolean isMetaDown() {
+        return ((modifiersEx & META_DOWN_MASK) != 0);
+    }
+
+    public boolean isShiftDown() {
+        return ((modifiersEx & SHIFT_DOWN_MASK) != 0);
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public void consume() {
+        super.consume();
+    }
+
+    @Override
+    public boolean isConsumed() {
+        return super.isConsumed();
+    }
+
+}
diff --git a/awt/java/awt/event/InputMethodEvent.java b/awt/java/awt/event/InputMethodEvent.java
new file mode 100644
index 0000000..a5cac4e
--- /dev/null
+++ b/awt/java/awt/event/InputMethodEvent.java
@@ -0,0 +1,150 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.font.TextHitInfo;
+import java.text.AttributedCharacterIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class InputMethodEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 4727190874778922661L;
+
+    public static final int INPUT_METHOD_FIRST = 1100;
+
+    public static final int INPUT_METHOD_TEXT_CHANGED = 1100;
+
+    public static final int CARET_POSITION_CHANGED = 1101;
+
+    public static final int INPUT_METHOD_LAST = 1101;
+
+    private AttributedCharacterIterator text;
+    private TextHitInfo visiblePosition;
+    private TextHitInfo caret;
+    private int committedCharacterCount;
+    private long when;
+
+    public InputMethodEvent(Component src, int id,
+                            TextHitInfo caret, 
+                            TextHitInfo visiblePos) {
+        this(src, id, null, 0, caret, visiblePos);
+    }
+
+    public InputMethodEvent(Component src, int id, 
+                            AttributedCharacterIterator text,
+                            int commitedCharCount,
+                            TextHitInfo caret, 
+                            TextHitInfo visiblePos) {
+        this(src, id, 0l, text, commitedCharCount, caret, visiblePos);
+    }
+
+    public InputMethodEvent(Component src, int id, long when,
+                            AttributedCharacterIterator text, 
+                            int committedCharacterCount,
+                            TextHitInfo caret,
+                            TextHitInfo visiblePos) {
+        super(src, id);
+
+        if ((id < INPUT_METHOD_FIRST) || (id > INPUT_METHOD_LAST)) {
+            // awt.18E=Wrong event id
+            throw new IllegalArgumentException(Messages.getString("awt.18E")); //$NON-NLS-1$
+        }
+        if ((id == CARET_POSITION_CHANGED) && (text != null)) {
+            // awt.18F=Text must be null for CARET_POSITION_CHANGED
+            throw new IllegalArgumentException(Messages.getString("awt.18F")); //$NON-NLS-1$
+        }
+        if ((text != null) &&
+                ((committedCharacterCount < 0) ||
+                 (committedCharacterCount > 
+                        (text.getEndIndex() - text.getBeginIndex())))) {
+            // awt.190=Wrong committedCharacterCount
+            throw new IllegalArgumentException(Messages.getString("awt.190")); //$NON-NLS-1$
+        }
+
+        this.when = when;
+        this.text = text;
+        this.caret = caret;
+        this.visiblePosition = visiblePos;
+        this.committedCharacterCount = committedCharacterCount;
+    }
+
+    public TextHitInfo getCaret() {
+        return caret;
+    }
+
+    public int getCommittedCharacterCount() {
+        return committedCharacterCount;
+    }
+
+    public AttributedCharacterIterator getText() {
+        return text;
+    }
+
+    public TextHitInfo getVisiblePosition() {
+        return visiblePosition;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public void consume() {
+        super.consume();
+    }
+
+    @Override
+    public boolean isConsumed() {
+        return super.isConsumed();
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * InputMethodEvent e = new InputMethodEvent(new Component(){},
+         *          InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+         *          TextHitInfo.leading(1), TextHitInfo.trailing(2));
+         * System.out.println(e);
+         */
+        String typeString = null;
+
+        switch (id) {
+        case INPUT_METHOD_TEXT_CHANGED:
+            typeString = "INPUT_METHOD_TEXT_CHANGED"; //$NON-NLS-1$
+            break;
+        case CARET_POSITION_CHANGED:
+            typeString = "CARET_POSITION_CHANGED"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return typeString + ",text=" + text +  //$NON-NLS-1$
+                ",commitedCharCount=" + committedCharacterCount + //$NON-NLS-1$
+                ",caret=" + caret + ",visiblePosition=" + visiblePosition; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/InputMethodListener.java b/awt/java/awt/event/InputMethodListener.java
new file mode 100644
index 0000000..0ab6918
--- /dev/null
+++ b/awt/java/awt/event/InputMethodListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface InputMethodListener extends EventListener {
+
+    public void caretPositionChanged(InputMethodEvent e);
+
+    public void inputMethodTextChanged(InputMethodEvent e);
+
+}
diff --git a/awt/java/awt/event/InvocationEvent.java b/awt/java/awt/event/InvocationEvent.java
new file mode 100644
index 0000000..59346ed
--- /dev/null
+++ b/awt/java/awt/event/InvocationEvent.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ActiveEvent;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class InvocationEvent extends AWTEvent implements ActiveEvent {
+
+    private static final long serialVersionUID = 436056344909459450L;
+
+    public static final int INVOCATION_FIRST = 1200;
+
+    public static final int INVOCATION_DEFAULT = 1200;
+
+    public static final int INVOCATION_LAST = 1200;
+
+    protected Runnable runnable;
+
+    protected Object notifier;
+
+    protected boolean catchExceptions;
+
+    private long when;
+    private Throwable throwable;
+
+    public InvocationEvent(Object source, Runnable runnable) {
+        this(source, runnable, null, false);
+    }
+
+    public InvocationEvent(Object source, Runnable runnable, 
+                           Object notifier, boolean catchExceptions) {
+        this(source, INVOCATION_DEFAULT, runnable, notifier, catchExceptions);
+    }
+
+    protected InvocationEvent(Object source, int id, Runnable runnable,
+            Object notifier, boolean catchExceptions)
+    {
+        super(source, id);
+
+        // awt.18C=Cannot invoke null runnable
+        assert runnable != null : Messages.getString("awt.18C"); //$NON-NLS-1$
+
+        if (source == null) {
+            // awt.18D=Source is null
+            throw new IllegalArgumentException(Messages.getString("awt.18D")); //$NON-NLS-1$
+        }
+        this.runnable = runnable;
+        this.notifier = notifier;
+        this.catchExceptions = catchExceptions;
+
+        throwable = null;
+        when = System.currentTimeMillis();
+    }
+
+    public void dispatch() {
+        if (!catchExceptions) {
+            runAndNotify();
+        } else {
+            try {
+                runAndNotify();
+            } catch (Throwable t) {
+                throwable = t;
+            }
+        }
+    }
+
+    private void runAndNotify() {
+        if (notifier != null) {
+            synchronized(notifier) {
+                try {
+                    runnable.run();
+                } finally {
+                    notifier.notifyAll();
+                }
+            }
+        } else {
+            runnable.run();
+        }
+    }
+
+    public Exception getException() {
+        return (throwable != null && throwable instanceof Exception) ?
+                (Exception)throwable : null;
+    }
+
+    public Throwable getThrowable() {
+        return throwable;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * InvocationEvent e = new InvocationEvent(new Component(){},
+         *       new Runnable() { public void run(){} });
+         * System.out.println(e);
+         */
+
+        return ((id == INVOCATION_DEFAULT ? "INVOCATION_DEFAULT" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",runnable=" + runnable + //$NON-NLS-1$
+                ",notifier=" + notifier + //$NON-NLS-1$
+                ",catchExceptions=" + catchExceptions + //$NON-NLS-1$
+                ",when=" + when); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ItemEvent.java b/awt/java/awt/event/ItemEvent.java
new file mode 100644
index 0000000..842da14
--- /dev/null
+++ b/awt/java/awt/event/ItemEvent.java
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ItemSelectable;
+
+public class ItemEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -608708132447206933L;
+
+    public static final int ITEM_FIRST = 701;
+
+    public static final int ITEM_LAST = 701;
+
+    public static final int ITEM_STATE_CHANGED = 701;
+
+    public static final int SELECTED = 1;
+
+    public static final int DESELECTED = 2;
+
+    private Object item;
+    private int stateChange;
+
+    public ItemEvent(ItemSelectable source, int id, Object item, int stateChange) {
+        super(source, id);
+
+        this.item = item;
+        this.stateChange = stateChange;
+    }
+
+    public Object getItem() {
+        return item;
+    }
+
+    public int getStateChange() {
+        return stateChange;
+    }
+
+    public ItemSelectable getItemSelectable() {
+        return (ItemSelectable) source;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * Checkbox c = new Checkbox("Checkbox", true);
+         * ItemEvent e = new ItemEvent(c, ItemEvent.ITEM_STATE_CHANGED, 
+         *                             c, ItemEvent.SELECTED);
+         * System.out.println(e);
+         */
+
+        String stateString = null;
+
+        switch (stateChange) {
+        case SELECTED:
+            stateString = "SELECTED"; //$NON-NLS-1$
+            break;
+        case DESELECTED:
+            stateString = "DESELECTED"; //$NON-NLS-1$
+            break;
+        default:
+            stateString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return ((id == ITEM_STATE_CHANGED ? "ITEM_STATE_CHANGED" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",item=" + item + ",stateChange=" + stateString); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/ItemListener.java b/awt/java/awt/event/ItemListener.java
new file mode 100644
index 0000000..33633be
--- /dev/null
+++ b/awt/java/awt/event/ItemListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ItemListener extends EventListener {
+
+    public void itemStateChanged(ItemEvent e);
+
+}
diff --git a/awt/java/awt/event/KeyAdapter.java b/awt/java/awt/event/KeyAdapter.java
new file mode 100644
index 0000000..423b5c9
--- /dev/null
+++ b/awt/java/awt/event/KeyAdapter.java
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class KeyAdapter implements KeyListener {
+
+    public KeyAdapter() {
+    }
+
+    public void keyPressed(KeyEvent e) {
+    }
+
+    public void keyReleased(KeyEvent e) {
+    }
+
+    public void keyTyped(KeyEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/KeyEvent.java b/awt/java/awt/event/KeyEvent.java
new file mode 100644
index 0000000..056c64c
--- /dev/null
+++ b/awt/java/awt/event/KeyEvent.java
@@ -0,0 +1,681 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Toolkit;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class KeyEvent extends InputEvent {
+
+    private static final long serialVersionUID = -2352130953028126954L;
+
+    public static final int KEY_FIRST = 400;
+
+    public static final int KEY_LAST = 402;
+
+    public static final int KEY_TYPED = 400;
+
+    public static final int KEY_PRESSED = 401;
+
+    public static final int KEY_RELEASED = 402;
+
+    public static final int VK_ENTER = 10;
+
+    public static final int VK_BACK_SPACE = 8;
+
+    public static final int VK_TAB = 9;
+
+    public static final int VK_CANCEL = 3;
+
+    public static final int VK_CLEAR = 12;
+
+    public static final int VK_SHIFT = 16;
+
+    public static final int VK_CONTROL = 17;
+
+    public static final int VK_ALT = 18;
+
+    public static final int VK_PAUSE = 19;
+
+    public static final int VK_CAPS_LOCK = 20;
+
+    public static final int VK_ESCAPE = 27;
+
+    public static final int VK_SPACE = 32;
+
+    public static final int VK_PAGE_UP = 33;
+
+    public static final int VK_PAGE_DOWN = 34;
+
+    public static final int VK_END = 35;
+
+    public static final int VK_HOME = 36;
+
+    public static final int VK_LEFT = 37;
+
+    public static final int VK_UP = 38;
+
+    public static final int VK_RIGHT = 39;
+
+    public static final int VK_DOWN = 40;
+
+    public static final int VK_COMMA = 44;
+
+    public static final int VK_MINUS = 45;
+
+    public static final int VK_PERIOD = 46;
+
+    public static final int VK_SLASH = 47;
+
+    public static final int VK_0 = 48;
+
+    public static final int VK_1 = 49;
+
+    public static final int VK_2 = 50;
+
+    public static final int VK_3 = 51;
+
+    public static final int VK_4 = 52;
+
+    public static final int VK_5 = 53;
+
+    public static final int VK_6 = 54;
+
+    public static final int VK_7 = 55;
+
+    public static final int VK_8 = 56;
+
+    public static final int VK_9 = 57;
+
+    public static final int VK_SEMICOLON = 59;
+
+    public static final int VK_EQUALS = 61;
+
+    public static final int VK_A = 65;
+
+    public static final int VK_B = 66;
+
+    public static final int VK_C = 67;
+
+    public static final int VK_D = 68;
+
+    public static final int VK_E = 69;
+
+    public static final int VK_F = 70;
+
+    public static final int VK_G = 71;
+
+    public static final int VK_H = 72;
+
+    public static final int VK_I = 73;
+
+    public static final int VK_J = 74;
+
+    public static final int VK_K = 75;
+
+    public static final int VK_L = 76;
+
+    public static final int VK_M = 77;
+
+    public static final int VK_N = 78;
+
+    public static final int VK_O = 79;
+
+    public static final int VK_P = 80;
+
+    public static final int VK_Q = 81;
+
+    public static final int VK_R = 82;
+
+    public static final int VK_S = 83;
+
+    public static final int VK_T = 84;
+
+    public static final int VK_U = 85;
+
+    public static final int VK_V = 86;
+
+    public static final int VK_W = 87;
+
+    public static final int VK_X = 88;
+
+    public static final int VK_Y = 89;
+
+    public static final int VK_Z = 90;
+
+    public static final int VK_OPEN_BRACKET = 91;
+
+    public static final int VK_BACK_SLASH = 92;
+
+    public static final int VK_CLOSE_BRACKET = 93;
+
+    public static final int VK_NUMPAD0 = 96;
+
+    public static final int VK_NUMPAD1 = 97;
+
+    public static final int VK_NUMPAD2 = 98;
+
+    public static final int VK_NUMPAD3 = 99;
+
+    public static final int VK_NUMPAD4 = 100;
+
+    public static final int VK_NUMPAD5 = 101;
+
+    public static final int VK_NUMPAD6 = 102;
+
+    public static final int VK_NUMPAD7 = 103;
+
+    public static final int VK_NUMPAD8 = 104;
+
+    public static final int VK_NUMPAD9 = 105;
+
+    public static final int VK_MULTIPLY = 106;
+
+    public static final int VK_ADD = 107;
+
+    public static final int VK_SEPARATER = 108;
+
+    public static final int VK_SEPARATOR = 108;
+
+    public static final int VK_SUBTRACT = 109;
+
+    public static final int VK_DECIMAL = 110;
+
+    public static final int VK_DIVIDE = 111;
+
+    public static final int VK_DELETE = 127;
+
+    public static final int VK_NUM_LOCK = 144;
+
+    public static final int VK_SCROLL_LOCK = 145;
+
+    public static final int VK_F1 = 112;
+
+    public static final int VK_F2 = 113;
+
+    public static final int VK_F3 = 114;
+
+    public static final int VK_F4 = 115;
+
+    public static final int VK_F5 = 116;
+
+    public static final int VK_F6 = 117;
+
+    public static final int VK_F7 = 118;
+
+    public static final int VK_F8 = 119;
+
+    public static final int VK_F9 = 120;
+
+    public static final int VK_F10 = 121;
+
+    public static final int VK_F11 = 122;
+
+    public static final int VK_F12 = 123;
+
+    public static final int VK_F13 = 61440;
+
+    public static final int VK_F14 = 61441;
+
+    public static final int VK_F15 = 61442;
+
+    public static final int VK_F16 = 61443;
+
+    public static final int VK_F17 = 61444;
+
+    public static final int VK_F18 = 61445;
+
+    public static final int VK_F19 = 61446;
+
+    public static final int VK_F20 = 61447;
+
+    public static final int VK_F21 = 61448;
+
+    public static final int VK_F22 = 61449;
+
+    public static final int VK_F23 = 61450;
+
+    public static final int VK_F24 = 61451;
+
+    public static final int VK_PRINTSCREEN = 154;
+
+    public static final int VK_INSERT = 155;
+
+    public static final int VK_HELP = 156;
+
+    public static final int VK_META = 157;
+
+    public static final int VK_BACK_QUOTE = 192;
+
+    public static final int VK_QUOTE = 222;
+
+    public static final int VK_KP_UP = 224;
+
+    public static final int VK_KP_DOWN = 225;
+
+    public static final int VK_KP_LEFT = 226;
+
+    public static final int VK_KP_RIGHT = 227;
+
+    public static final int VK_DEAD_GRAVE = 128;
+
+    public static final int VK_DEAD_ACUTE = 129;
+
+    public static final int VK_DEAD_CIRCUMFLEX = 130;
+
+    public static final int VK_DEAD_TILDE = 131;
+
+    public static final int VK_DEAD_MACRON = 132;
+
+    public static final int VK_DEAD_BREVE = 133;
+
+    public static final int VK_DEAD_ABOVEDOT = 134;
+
+    public static final int VK_DEAD_DIAERESIS = 135;
+
+    public static final int VK_DEAD_ABOVERING = 136;
+
+    public static final int VK_DEAD_DOUBLEACUTE = 137;
+
+    public static final int VK_DEAD_CARON = 138;
+
+    public static final int VK_DEAD_CEDILLA = 139;
+
+    public static final int VK_DEAD_OGONEK = 140;
+
+    public static final int VK_DEAD_IOTA = 141;
+
+    public static final int VK_DEAD_VOICED_SOUND = 142;
+
+    public static final int VK_DEAD_SEMIVOICED_SOUND = 143;
+
+    public static final int VK_AMPERSAND = 150;
+
+    public static final int VK_ASTERISK = 151;
+
+    public static final int VK_QUOTEDBL = 152;
+
+    public static final int VK_LESS = 153;
+
+    public static final int VK_GREATER = 160;
+
+    public static final int VK_BRACELEFT = 161;
+
+    public static final int VK_BRACERIGHT = 162;
+
+    public static final int VK_AT = 512;
+
+    public static final int VK_COLON = 513;
+
+    public static final int VK_CIRCUMFLEX = 514;
+
+    public static final int VK_DOLLAR = 515;
+
+    public static final int VK_EURO_SIGN = 516;
+
+    public static final int VK_EXCLAMATION_MARK = 517;
+
+    public static final int VK_INVERTED_EXCLAMATION_MARK = 518;
+
+    public static final int VK_LEFT_PARENTHESIS = 519;
+
+    public static final int VK_NUMBER_SIGN = 520;
+
+    public static final int VK_PLUS = 521;
+
+    public static final int VK_RIGHT_PARENTHESIS = 522;
+
+    public static final int VK_UNDERSCORE = 523;
+
+    public static final int VK_FINAL = 24;
+
+    public static final int VK_WINDOWS = 524; 
+
+    public static final int VK_CONTEXT_MENU = 525;
+
+    public static final int VK_CONVERT = 28;
+
+    public static final int VK_NONCONVERT = 29;
+
+    public static final int VK_ACCEPT = 30;
+
+    public static final int VK_MODECHANGE = 31;
+
+    public static final int VK_KANA = 21;
+
+    public static final int VK_KANJI = 25;
+
+    public static final int VK_ALPHANUMERIC = 240;
+
+    public static final int VK_KATAKANA = 241;
+
+    public static final int VK_HIRAGANA = 242;
+
+    public static final int VK_FULL_WIDTH = 243;
+
+    public static final int VK_HALF_WIDTH = 244;
+
+    public static final int VK_ROMAN_CHARACTERS = 245;
+
+    public static final int VK_ALL_CANDIDATES = 256;
+
+    public static final int VK_PREVIOUS_CANDIDATE = 257;
+
+    public static final int VK_CODE_INPUT = 258;
+
+    public static final int VK_JAPANESE_KATAKANA = 259;
+
+    public static final int VK_JAPANESE_HIRAGANA = 260;
+
+    public static final int VK_JAPANESE_ROMAN = 261;
+
+    public static final int VK_KANA_LOCK = 262;
+
+    public static final int VK_INPUT_METHOD_ON_OFF = 263;
+
+    public static final int VK_CUT = 65489;
+
+    public static final int VK_COPY = 65485;
+
+    public static final int VK_PASTE = 65487;
+
+    public static final int VK_UNDO = 65483;
+
+    public static final int VK_AGAIN = 65481;
+
+    public static final int VK_FIND = 65488;
+
+    public static final int VK_PROPS = 65482;
+
+    public static final int VK_STOP = 65480;
+
+    public static final int VK_COMPOSE = 65312;
+
+    public static final int VK_ALT_GRAPH = 65406;
+
+    public static final int VK_BEGIN = 65368;
+
+    public static final int VK_UNDEFINED = 0;
+
+    public static final char CHAR_UNDEFINED = (char)(-1);
+
+    public static final int KEY_LOCATION_UNKNOWN = 0;
+
+    public static final int KEY_LOCATION_STANDARD = 1;
+
+    public static final int KEY_LOCATION_LEFT = 2;
+
+    public static final int KEY_LOCATION_RIGHT = 3;
+
+    public static final int KEY_LOCATION_NUMPAD = 4;
+
+    private int keyCode;
+    private char keyChar;
+    private int keyLocation;
+
+    public static String getKeyModifiersText(int modifiers) {
+        return getKeyModifiersExText(extractExFlags(modifiers));
+    }
+
+    static String getKeyModifiersExText(int modifiersEx) {
+        String text = ""; //$NON-NLS-1$
+
+        if ((modifiersEx & InputEvent.META_DOWN_MASK) != 0) {
+            text += Toolkit.getProperty("AWT.meta", "Meta"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.CTRL_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.control", "Ctrl"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.ALT_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.alt", "Alt"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.SHIFT_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.shift", "Shift"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.altGraph", "Alt Graph"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return text;
+    }
+
+    public static String getKeyText(int keyCode) {
+        String[] rawName = getPublicStaticFinalIntFieldName(keyCode); //$NON-NLS-1$
+
+        if ((rawName == null) || (rawName.length == 0)) {
+            return ("Unknown keyCode: " + (keyCode >= 0 ? "0x" : "-0x") + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    Integer.toHexString(Math.abs(keyCode)));
+        }
+
+        String propertyName = getPropertyName(rawName);
+        String defaultName = getDefaultName(rawName);
+
+        return Toolkit.getProperty(propertyName, defaultName);
+    }
+
+    private static String getDefaultName(String[] rawName) {
+        String name = ""; //$NON-NLS-1$
+
+        for (int i = 0; true; i++) {
+            String part = rawName[i];
+
+            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
+                    part.substring(1).toLowerCase();
+
+            if (i == (rawName.length - 1)) {
+                break;
+            }
+            name += " "; //$NON-NLS-1$
+        }
+
+        return name;
+    }
+
+    private static String getPropertyName(String[] rawName) {
+        String name = rawName[0].toLowerCase();
+
+        for (int i = 1; i < rawName.length; i++) {
+            String part = rawName[i];
+
+            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
+                    part.substring(1).toLowerCase();
+        }
+
+        return ("AWT." + name); //$NON-NLS-1$
+    }
+
+    private static String[] getPublicStaticFinalIntFieldName(int value) {
+        Field[] allFields = KeyEvent.class.getDeclaredFields();
+
+        try {
+            for (Field field : allFields) {
+                Class<?> ssalc = field.getType();
+                int modifiers = field.getModifiers();
+
+                if (ssalc.isPrimitive() && ssalc.getName().equals("int") && //$NON-NLS-1$
+                        Modifier.isFinal(modifiers) && Modifier.isPublic(modifiers) &&
+                        Modifier.isStatic(modifiers))
+                {
+                    if (field.getInt(null) == value){
+                        final String name = field.getName();
+                        final int prefixLength = name.indexOf("_") + 1;
+                        return name.substring(prefixLength).split("_"); //$NON-NLS-1$
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return null;
+    }
+
+    @Deprecated
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode) {
+        this(src, id, when, modifiers, keyCode,
+                (keyCode > (2 << 7) - 1) ? CHAR_UNDEFINED : (char) keyCode);
+    }
+
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode, char keyChar) {
+        this(src, id, when, modifiers, keyCode, keyChar, KEY_LOCATION_UNKNOWN);
+    }
+
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode, char keyChar,
+                    int keyLocation) {
+        super(src, id, when, modifiers);
+
+        if (id == KEY_TYPED) {
+            if (keyCode != VK_UNDEFINED) {
+                // awt.191=Invalid keyCode for KEY_TYPED event, must be VK_UNDEFINED
+                throw new IllegalArgumentException(Messages.getString("awt.191")); //$NON-NLS-1$
+            }
+            if (keyChar == CHAR_UNDEFINED) {
+                // awt.192=Invalid keyChar for KEY_TYPED event, can't be CHAR_UNDEFINED
+                throw new IllegalArgumentException(Messages.getString("awt.192")); //$NON-NLS-1$
+            }
+        }
+        
+        if ((keyLocation < KEY_LOCATION_UNKNOWN)
+                || (keyLocation > KEY_LOCATION_NUMPAD)) {
+            // awt.297=Invalid keyLocation
+            throw new IllegalArgumentException(Messages.getString("awt.297")); //$NON-NLS-1$
+        }
+
+        this.keyChar = keyChar;
+        this.keyLocation = keyLocation;
+        this.keyCode = keyCode;
+    }
+
+    public int getKeyCode() {
+        return keyCode;
+    }
+
+    public void setKeyCode(int keyCode) {
+        this.keyCode = keyCode;
+    }
+
+    public char getKeyChar() {
+        return keyChar;
+    }
+
+    public void setKeyChar(char keyChar) {
+        this.keyChar = keyChar;
+    }
+
+    public int getKeyLocation() {
+        return keyLocation;
+    }
+
+    @Override
+    @Deprecated
+    public void setModifiers(int modifiers) {
+        super.setModifiers(modifiers);
+    }
+
+    public boolean isActionKey() {
+        return ((keyChar == CHAR_UNDEFINED) && (keyCode != VK_UNDEFINED) &&
+                !((keyCode == VK_ALT) || (keyCode == VK_ALT_GRAPH) ||
+                    (keyCode == VK_CONTROL) || (keyCode == VK_META) || (keyCode == VK_SHIFT)));
+    }
+
+    @Override
+    public String paramString() {
+        /*
+         * The format is based on 1.5 release behavior
+         * which can be revealed by the following code:
+         *
+         * KeyEvent e = new KeyEvent(new Component() {}, 
+         *       KeyEvent.KEY_PRESSED, 0, 
+         *       KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK, 
+         *       KeyEvent.VK_A, 'A', KeyEvent.KEY_LOCATION_STANDARD);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        String locString = null;
+        String paramString = null;
+        String keyCharString = (keyChar == '\n') ?
+                keyCharString = getKeyText(VK_ENTER) : "'" + keyChar + "'"; //$NON-NLS-1$ //$NON-NLS-2$
+
+        switch (id) {
+        case KEY_PRESSED:
+            idString = "KEY_PRESSED"; //$NON-NLS-1$
+            break;
+        case KEY_RELEASED:
+            idString = "KEY_RELEASED"; //$NON-NLS-1$
+            break;
+        case KEY_TYPED:
+            idString = "KEY_TYPED"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        switch(keyLocation){
+        case KEY_LOCATION_STANDARD:
+            locString = "KEY_LOCATION_STANDARD"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_LEFT:
+            locString = "KEY_LOCATION_LEFT"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_RIGHT:
+            locString = "KEY_LOCATION_RIGHT"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_NUMPAD:
+            locString = "KEY_LOCATION_NUMPAD"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_UNKNOWN:
+            locString = "KEY_LOCATION_UNKNOWN"; //$NON-NLS-1$
+            break;
+        default:
+            locString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString = idString + ",keyCode=" + keyCode; //$NON-NLS-1$
+        if (isActionKey()) {
+            paramString += "," + getKeyText(keyCode); //$NON-NLS-1$
+        } else {
+            paramString += ",keyChar=" + keyCharString; //$NON-NLS-1$
+        }
+        if (getModifiersEx() > 0) {
+            paramString += ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
+                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
+        }
+        paramString += ",keyLocation=" + locString; //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/KeyListener.java b/awt/java/awt/event/KeyListener.java
new file mode 100644
index 0000000..f20fc90
--- /dev/null
+++ b/awt/java/awt/event/KeyListener.java
@@ -0,0 +1,33 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface KeyListener extends EventListener {
+
+    public void keyPressed(KeyEvent e);
+
+    public void keyReleased(KeyEvent e);
+
+    public void keyTyped(KeyEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseAdapter.java b/awt/java/awt/event/MouseAdapter.java
new file mode 100644
index 0000000..4973956
--- /dev/null
+++ b/awt/java/awt/event/MouseAdapter.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class MouseAdapter implements MouseListener {
+
+    public MouseAdapter() {
+    }
+
+    public void mouseClicked(MouseEvent e) {
+    }
+
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    public void mouseExited(MouseEvent e) {
+    }
+
+    public void mousePressed(MouseEvent e) {
+    }
+
+    public void mouseReleased(MouseEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/MouseEvent.java b/awt/java/awt/event/MouseEvent.java
new file mode 100644
index 0000000..0b776f9
--- /dev/null
+++ b/awt/java/awt/event/MouseEvent.java
@@ -0,0 +1,226 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.Toolkit;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class MouseEvent extends InputEvent {
+
+    private static final long serialVersionUID = -991214153494842848L;
+
+    public static final int MOUSE_FIRST = 500;
+
+    public static final int MOUSE_LAST = 507;
+
+    public static final int MOUSE_CLICKED = 500;
+
+    public static final int MOUSE_PRESSED = 501;
+
+    public static final int MOUSE_RELEASED = 502;
+
+    public static final int MOUSE_MOVED = 503;
+
+    public static final int MOUSE_ENTERED = 504;
+
+    public static final int MOUSE_EXITED = 505;
+
+    public static final int MOUSE_DRAGGED = 506;
+
+    public static final int MOUSE_WHEEL = 507;
+
+    public static final int NOBUTTON = 0;
+
+    public static final int BUTTON1 = 1;
+
+    public static final int BUTTON2 = 2;
+
+    public static final int BUTTON3 = 3;
+
+    private boolean popupTrigger;
+    private int clickCount;
+    private int button;
+    private int x;
+    private int y;
+
+    public static String getMouseModifiersText(int modifiers) {
+        final StringBuffer text = new StringBuffer();
+
+        if ((modifiers & META_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.meta", "Meta")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & SHIFT_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.shift", "Shift")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & CTRL_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.control", "Ctrl")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & ALT_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.alt", "Alt")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & ALT_GRAPH_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON1_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button1", "Button1")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON2_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button2", "Button2")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON3_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button3", "Button3")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        return text.length() == 0 ? text.toString() : text.substring(0, text
+                .length() - 1);
+    }
+
+    static String addMouseModifiersExText(String text, int modifiersEx) {
+        if ((modifiersEx & InputEvent.BUTTON1_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button1", "Button1"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.BUTTON2_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button2", "Button2"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.BUTTON3_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button3", "Button3"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return text;
+    }
+
+    public MouseEvent(Component source, int id, long when,
+                      int modifiers, int x, int y,
+                      int clickCount, boolean popupTrigger) {
+        this(source, id, when, modifiers, x, y,
+             clickCount, popupTrigger, NOBUTTON);
+    }
+
+    public MouseEvent(Component source, int id, long when,
+                      int modifiers, int x, int y,
+                      int clickCount, boolean popupTrigger, int button) {
+        super(source, id, when, modifiers);
+
+        if ((button != NOBUTTON) && (button != BUTTON1) &&
+                (button != BUTTON2) && (button != BUTTON3)) {
+            // awt.18B=Invalid button value
+            throw new IllegalArgumentException(Messages.getString("awt.18B")); //$NON-NLS-1$
+        }
+
+        this.popupTrigger = popupTrigger;
+        this.clickCount = clickCount;
+        this.button = button;
+        this.x = x;
+        this.y = y;
+    }
+
+    public int getButton() {
+        return button;
+    }
+
+    public int getClickCount() {
+        return clickCount;
+    }
+
+    public Point getPoint() {
+        return new Point(x, y);
+    }
+
+    public int getX() {
+        return x;
+    }
+
+    public int getY() {
+        return y;
+    }
+
+    public boolean isPopupTrigger() {
+        return popupTrigger;
+    }
+
+    public void translatePoint(int x, int y) {
+        this.x += x;
+        this.y += y;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * MouseEvent e = new MouseEvent(new Component(){}, 
+         *          MouseEvent.MOUSE_PRESSED, 0, 
+         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
+         *          10, 20, 1, false, MouseEvent.BUTTON1);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        String paramString = null;
+
+        switch (id) {
+        case MOUSE_MOVED:
+            idString = "MOUSE_MOVED"; //$NON-NLS-1$
+            break;
+        case MOUSE_CLICKED:
+            idString = "MOUSE_CLICKED"; //$NON-NLS-1$
+            break;
+        case MOUSE_PRESSED:
+            idString = "MOUSE_PRESSED"; //$NON-NLS-1$
+            break;
+        case MOUSE_RELEASED:
+            idString = "MOUSE_RELEASED"; //$NON-NLS-1$
+            break;
+        case MOUSE_DRAGGED:
+            idString = "MOUSE_DRAGGED"; //$NON-NLS-1$
+            break;
+        case MOUSE_ENTERED:
+            idString = "MOUSE_ENTERED"; //$NON-NLS-1$
+            break;
+        case MOUSE_EXITED:
+            idString = "MOUSE_EXITED"; //$NON-NLS-1$
+            break;
+        case MOUSE_WHEEL:
+            idString = "MOUSE_WHEEL"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString = idString + ",(" + getX() + "," + getY() + ")" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                ",button=" + button; //$NON-NLS-1$
+        if (getModifiersEx() > 0) {
+            paramString += 
+                    ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
+                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
+        }
+        paramString += ",clickCount=" + getClickCount(); //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/MouseListener.java b/awt/java/awt/event/MouseListener.java
new file mode 100644
index 0000000..5d32b0f
--- /dev/null
+++ b/awt/java/awt/event/MouseListener.java
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface MouseListener extends EventListener {
+
+    public void mouseClicked(MouseEvent e);
+
+    public void mouseEntered(MouseEvent e);
+
+    public void mouseExited(MouseEvent e);
+
+    public void mousePressed(MouseEvent e);
+
+    public void mouseReleased(MouseEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseMotionAdapter.java b/awt/java/awt/event/MouseMotionAdapter.java
new file mode 100644
index 0000000..a4bebcc
--- /dev/null
+++ b/awt/java/awt/event/MouseMotionAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class MouseMotionAdapter implements MouseMotionListener {
+
+    public MouseMotionAdapter() {
+    }
+
+    public void mouseDragged(MouseEvent e) {
+    }
+
+    public void mouseMoved(MouseEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/MouseMotionListener.java b/awt/java/awt/event/MouseMotionListener.java
new file mode 100644
index 0000000..a5c11da
--- /dev/null
+++ b/awt/java/awt/event/MouseMotionListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface MouseMotionListener extends EventListener {
+
+    public void mouseDragged(MouseEvent e);
+
+    public void mouseMoved(MouseEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseWheelEvent.java b/awt/java/awt/event/MouseWheelEvent.java
new file mode 100644
index 0000000..d3ac9d8
--- /dev/null
+++ b/awt/java/awt/event/MouseWheelEvent.java
@@ -0,0 +1,97 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+public class MouseWheelEvent extends MouseEvent {
+
+    private static final long serialVersionUID = -9187413581993563929L;
+
+    public static final int WHEEL_UNIT_SCROLL = 0;
+
+    public static final int WHEEL_BLOCK_SCROLL = 1;
+
+    private int wheelRotation;
+    private int scrollAmount;
+    private int scrollType;
+
+    public MouseWheelEvent(Component source, int id, long when, int modifiers,
+            int x, int y, int clickCount, boolean popupTrigger, int scrollType,
+            int scrollAmount, int wheelRotation) {
+        super(source, id, when, modifiers, x, y, clickCount, popupTrigger);
+
+        this.scrollType = scrollType;
+        this.scrollAmount = scrollAmount;
+        this.wheelRotation = wheelRotation;
+    }
+
+    public int getScrollAmount() {
+        return scrollAmount;
+    }
+
+    public int getScrollType() {
+        return scrollType;
+    }
+
+    public int getWheelRotation() {
+        return wheelRotation;
+    }
+
+    public int getUnitsToScroll() {
+        return (scrollAmount * wheelRotation);
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * MouseWheelEvent e = new MouseWheelEvent(new Component(){}, 
+         *          MouseWheelEvent.MOUSE_WHEEL, 0, 
+         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
+         *          10, 20, 1, false, MouseWheelEvent.WHEEL_UNIT_SCROLL,
+         *          1, 3);
+         * System.out.println(e);
+         */
+
+        String paramString = super.paramString();
+        String typeString = null;
+
+        switch (scrollType) {
+        case WHEEL_UNIT_SCROLL:
+            typeString = "WHEEL_UNIT_SCROLL"; //$NON-NLS-1$
+            break;
+        case WHEEL_BLOCK_SCROLL:
+            typeString = "WHEEL_BLOCK_SCROLL"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString += ",scrollType=" + typeString + //$NON-NLS-1$
+                ",scrollAmount=" + scrollAmount +  //$NON-NLS-1$
+                ",wheelRotation=" + wheelRotation; //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/MouseWheelListener.java b/awt/java/awt/event/MouseWheelListener.java
new file mode 100644
index 0000000..8ca1c8b
--- /dev/null
+++ b/awt/java/awt/event/MouseWheelListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface MouseWheelListener extends EventListener {
+
+    public void mouseWheelMoved(MouseWheelEvent e);
+
+}
diff --git a/awt/java/awt/event/PaintEvent.java b/awt/java/awt/event/PaintEvent.java
new file mode 100644
index 0000000..d0573e1
--- /dev/null
+++ b/awt/java/awt/event/PaintEvent.java
@@ -0,0 +1,80 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Rectangle;
+
+public class PaintEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = 1267492026433337593L;
+
+    public static final int PAINT_FIRST = 800;
+
+    public static final int PAINT_LAST = 801;
+
+    public static final int PAINT = 800;
+
+    public static final int UPDATE = 801;
+
+    private Rectangle updateRect;
+
+    public PaintEvent(Component source, int id, Rectangle updateRect) {
+        super(source, id);
+
+        this.updateRect = updateRect;
+    }
+
+    public Rectangle getUpdateRect() {
+        return updateRect;
+    }
+
+    public void setUpdateRect(Rectangle updateRect) {
+        this.updateRect = updateRect;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * PaintEvent e = new PaintEvent(new Component(){}, 
+         *          PaintEvent.PAINT, new Rectangle(0, 0, 10, 20)); 
+         * System.out.println(e);
+         */
+
+        String typeString = null;
+
+        switch (id) {
+        case PAINT:
+            typeString = "PAINT"; //$NON-NLS-1$
+            break;
+        case UPDATE:
+            typeString = "UPDATE"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return typeString + ",updateRect=" + updateRect; //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/TextEvent.java b/awt/java/awt/event/TextEvent.java
new file mode 100644
index 0000000..e2bfd96
--- /dev/null
+++ b/awt/java/awt/event/TextEvent.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+public class TextEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 6269902291250941179L;
+
+    public static final int TEXT_FIRST = 900;
+
+    public static final int TEXT_LAST = 900;
+
+    public static final int TEXT_VALUE_CHANGED = 900;
+
+    public TextEvent(Object src, int id) {
+        super(src, id);
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * TextEvent e = new TextEvent(new Component(){}, 
+         *          TextEvent.TEXT_VALUE_CHANGED); 
+         * System.out.println(e);
+         */
+
+        return (id == TEXT_VALUE_CHANGED) ? 
+                "TEXT_VALUE_CHANGED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/TextListener.java b/awt/java/awt/event/TextListener.java
new file mode 100644
index 0000000..6c5a671
--- /dev/null
+++ b/awt/java/awt/event/TextListener.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface TextListener extends EventListener {
+
+    public void textValueChanged(TextEvent e);
+
+}
+
diff --git a/awt/java/awt/event/WindowAdapter.java b/awt/java/awt/event/WindowAdapter.java
new file mode 100644
index 0000000..9d4b377
--- /dev/null
+++ b/awt/java/awt/event/WindowAdapter.java
@@ -0,0 +1,58 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class WindowAdapter implements WindowListener, WindowStateListener, WindowFocusListener {
+
+    public WindowAdapter() {
+    }
+
+    public void windowActivated(WindowEvent e) {
+    }
+
+    public void windowClosed(WindowEvent e) {
+    }
+
+    public void windowClosing(WindowEvent e) {
+    }
+
+    public void windowDeactivated(WindowEvent e) {
+    }
+
+    public void windowDeiconified(WindowEvent e) {
+    }
+
+    public void windowGainedFocus(WindowEvent e) {
+    }
+
+    public void windowIconified(WindowEvent e) {
+    }
+
+    public void windowLostFocus(WindowEvent e) {
+    }
+
+    public void windowOpened(WindowEvent e) {
+    }
+
+    public void windowStateChanged(WindowEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/WindowEvent.java b/awt/java/awt/event/WindowEvent.java
new file mode 100644
index 0000000..65a30e4
--- /dev/null
+++ b/awt/java/awt/event/WindowEvent.java
@@ -0,0 +1,162 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+
+//???AWT
+//import java.awt.Window;
+//import java.awt.Frame;
+
+public class WindowEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -1567959133147912127L;
+
+    public static final int WINDOW_FIRST = 200;
+
+    public static final int WINDOW_OPENED = 200;
+
+    public static final int WINDOW_CLOSING = 201;
+
+    public static final int WINDOW_CLOSED = 202;
+
+    public static final int WINDOW_ICONIFIED = 203;
+
+    public static final int WINDOW_DEICONIFIED = 204;
+
+    public static final int WINDOW_ACTIVATED = 205;
+
+    public static final int WINDOW_DEACTIVATED = 206;
+
+    public static final int WINDOW_GAINED_FOCUS = 207;
+
+    public static final int WINDOW_LOST_FOCUS = 208;
+
+    public static final int WINDOW_STATE_CHANGED = 209;
+
+    public static final int WINDOW_LAST = 209;
+
+    //???AWT: private Window oppositeWindow;
+    private int oldState;
+    private int newState;
+
+    //???AWT
+    /*
+    public WindowEvent(Window source, int id) {
+        this(source, id, null);
+    }
+
+    public WindowEvent(Window source, int id, Window opposite) {
+        this(source, id, opposite, Frame.NORMAL, Frame.NORMAL);
+    }
+
+    public WindowEvent(Window source, int id, int oldState, int newState) {
+        this(source, id, null, oldState, newState);
+    }
+
+    public WindowEvent(Window source, int id, Window opposite, 
+                       int oldState, int newState) {
+        super(source, id);
+
+        oppositeWindow = opposite;
+        this.oldState = oldState;
+        this.newState = newState;
+    }
+    */
+    //???AWT: Fake constructor
+    public WindowEvent() {
+        super(null, 0);
+    }
+    
+    public int getNewState() {
+        return newState;
+    }
+
+    public int getOldState() {
+        return oldState;
+    }
+
+    //???AWT
+    /*
+    public Window getOppositeWindow() {
+        return oppositeWindow;
+    }
+
+    public Window getWindow() {
+        return (Window) source;
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * WindowEvent e = new WindowEvent(new Frame(), 
+         *          WindowEvent.WINDOW_OPENED); 
+         * System.out.println(e);
+         */
+
+        String typeString = null;
+
+        switch (id) {
+        case WINDOW_OPENED:
+            typeString = "WINDOW_OPENED"; //$NON-NLS-1$
+            break;
+        case WINDOW_CLOSING:
+            typeString = "WINDOW_CLOSING"; //$NON-NLS-1$
+            break;
+        case WINDOW_CLOSED:
+            typeString = "WINDOW_CLOSED"; //$NON-NLS-1$
+            break;
+        case WINDOW_ICONIFIED:
+            typeString = "WINDOW_ICONIFIED"; //$NON-NLS-1$
+            break;
+        case WINDOW_DEICONIFIED:
+            typeString = "WINDOW_DEICONIFIED"; //$NON-NLS-1$
+            break;
+        case WINDOW_ACTIVATED:
+            typeString = "WINDOW_ACTIVATED"; //$NON-NLS-1$
+            break;
+        case WINDOW_DEACTIVATED:
+            typeString = "WINDOW_DEACTIVATED"; //$NON-NLS-1$
+            break;
+        case WINDOW_GAINED_FOCUS:
+            typeString = "WINDOW_GAINED_FOCUS"; //$NON-NLS-1$
+            break;
+        case WINDOW_LOST_FOCUS:
+            typeString = "WINDOW_LOST_FOCUS"; //$NON-NLS-1$
+            break;
+        case WINDOW_STATE_CHANGED:
+            typeString = "WINDOW_STATE_CHANGED"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        //???AWT
+        /*
+        return typeString + ",opposite=" + oppositeWindow + //$NON-NLS-1$
+                ",oldState=" + oldState + ",newState=" + newState; //$NON-NLS-1$ //$NON-NLS-2$
+        */
+        return typeString;
+    }
+
+}
diff --git a/awt/java/awt/event/WindowFocusListener.java b/awt/java/awt/event/WindowFocusListener.java
new file mode 100644
index 0000000..e0200f2
--- /dev/null
+++ b/awt/java/awt/event/WindowFocusListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface WindowFocusListener extends EventListener {
+
+    public void windowGainedFocus(WindowEvent e);
+
+    public void windowLostFocus(WindowEvent e);
+
+}
diff --git a/awt/java/awt/event/WindowListener.java b/awt/java/awt/event/WindowListener.java
new file mode 100644
index 0000000..20a2b08
--- /dev/null
+++ b/awt/java/awt/event/WindowListener.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface WindowListener extends EventListener {
+
+    public void windowActivated(WindowEvent e);
+
+    public void windowClosed(WindowEvent e);
+
+    public void windowClosing(WindowEvent e);
+
+    public void windowDeactivated(WindowEvent e);
+
+    public void windowDeiconified(WindowEvent e);
+
+    public void windowIconified(WindowEvent e);
+
+    public void windowOpened(WindowEvent e);
+
+}
diff --git a/awt/java/awt/event/WindowStateListener.java b/awt/java/awt/event/WindowStateListener.java
new file mode 100644
index 0000000..12dbc20
--- /dev/null
+++ b/awt/java/awt/event/WindowStateListener.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface WindowStateListener extends EventListener {
+
+    public void windowStateChanged(WindowEvent e);
+
+}
+
diff --git a/awt/java/awt/font/FontRenderContext.java b/awt/java/awt/font/FontRenderContext.java
new file mode 100644
index 0000000..766300d
--- /dev/null
+++ b/awt/java/awt/font/FontRenderContext.java
@@ -0,0 +1,168 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * The FontRenderContext class contains the information 
+ * about text measurement. Anti-aliasing and fractional-metrics
+ * modes are defined by an application and affect the size of
+ * a character.
+ */
+public class FontRenderContext {
+
+    // Affine transform of this mode
+    /** The transform. */
+    private AffineTransform transform;
+
+    // Is the anti-aliased mode used
+    /** The anti aliased. */
+    private boolean fAntiAliased;
+
+    // Is the fractional metrics used
+    /** The fractional metrics. */
+    private boolean fFractionalMetrics;
+
+
+    /**
+     * Instantiates a new FontRenderContext object with the specified
+     * AffineTransform, anti-aliasing and fractional metrics flags.
+     * 
+     * @param trans the AffineTransform.
+     * @param antiAliased the anti-aliasing flag.
+     * @param usesFractionalMetrics the fractional metrics flag.
+     */
+    public FontRenderContext(AffineTransform trans, boolean antiAliased, 
+            boolean usesFractionalMetrics) {
+        if (trans != null){
+            transform = new AffineTransform(trans);
+        }
+        fAntiAliased = antiAliased;
+        fFractionalMetrics = usesFractionalMetrics;
+    }
+
+    /**
+     * Instantiates a new FontRenderContext object.
+     */
+    protected FontRenderContext() {
+    }
+
+    /**
+     * Compares the specified Object with current FontRenderContext object. 
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is equal to current
+     * FontRenderContext object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+            try {
+                return equals((FontRenderContext) obj);
+            } catch (ClassCastException e) {
+                return false;
+            }
+        }
+        return false;
+
+    }
+
+    /**
+     * Gets the transform which is used for scaling typographical points 
+     * to pixels in this FontRenderContext.
+     * 
+     * @return the AffineTransform which is used for scaling typographical 
+     * points to pixels in this FontRenderContext.
+     */
+    public AffineTransform getTransform() {
+        if (transform != null){
+            return new AffineTransform(transform);
+        }
+        return new AffineTransform();
+    }
+
+    /**
+     * Compares the specified FontRenderContext object with current 
+     * FontRenderContext.
+     * 
+     * @param frc the FontRenderContext object to be compared.
+     * 
+     * @return true, if the specified FontRenderContext object is
+     * equal to current FontRenderContext.
+     */
+    public boolean equals(FontRenderContext frc) {
+        if (this == frc){
+            return true;
+        }
+
+        if (frc == null){
+            return false;
+        }
+
+        if (!frc.getTransform().equals(this.getTransform()) &&
+            !frc.isAntiAliased() == this.fAntiAliased &&
+            !frc.usesFractionalMetrics() == this.fFractionalMetrics){
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the text fractional metrics are used in 
+     * this FontRenderContext.
+     * 
+     * @return true, if the text fractional metrics are used in 
+     * this FontRenderContext, false otherwise.
+     */
+    public boolean usesFractionalMetrics() {
+        return this.fFractionalMetrics;
+    }
+
+    /**
+     * Returns true if anti-aliasing is used in this FontRenderContext.
+     * 
+     * @return true, if is anti-aliasing is used in this FontRenderContext,
+     * false otherwise.
+     */
+    public boolean isAntiAliased() {
+        return this.fAntiAliased;
+    }
+
+    /**
+     * Returns hash code of the FontRenderContext object.
+     * 
+     * @return the hash code of the FontRenderContext object.
+     */
+    @Override
+    public int hashCode() {
+        return this.getTransform().hashCode() ^
+                new Boolean(this.fFractionalMetrics).hashCode() ^
+                new Boolean(this.fAntiAliased).hashCode();
+    }
+
+}
+
diff --git a/awt/java/awt/font/GlyphJustificationInfo.java b/awt/java/awt/font/GlyphJustificationInfo.java
new file mode 100644
index 0000000..4c3e02e
--- /dev/null
+++ b/awt/java/awt/font/GlyphJustificationInfo.java
@@ -0,0 +1,185 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GlyphJustificationInfo class provides information about 
+ * the glyph's justification properties. There are four justification 
+ * properties: weight, priority, absorb, and limit.
+ * <p>
+ * There are two sets of metrics: growing and shrinking. 
+ * Growing metrics are used when the glyphs are to be spread apart 
+ * to fit a larger width. Shrinking metrics are used when the glyphs 
+ * are to be moved together to fit a smaller width.
+ */
+public final class GlyphJustificationInfo {
+
+    /** 
+     * The Constant PRIORITY_KASHIDA indicates the highest 
+     * justification priority.
+     */
+    public static final int PRIORITY_KASHIDA = 0;
+
+    /**
+     * The Constant PRIORITY_WHITESPACE indicates the second highest 
+     * justification priority. 
+     */
+    public static final int PRIORITY_WHITESPACE = 1;
+
+    /** 
+     * The Constant PRIORITY_INTERCHAR indicates the second lowest 
+     * justification priority. 
+     */
+    public static final int PRIORITY_INTERCHAR = 2;
+
+    /**
+     * The Constant PRIORITY_NONE indicates the lowest justification 
+     * priority.
+     */
+    public static final int PRIORITY_NONE = 3;
+
+    /** 
+     * The grow absorb flag indicates if this glyph absorbs all extra 
+     * space at this and lower priority levels when it grows.
+     */
+    public final boolean growAbsorb;
+
+    /** 
+     * The grow left limit value represents the maximum value by which 
+     * the left side of this glyph grows. 
+     */
+    public final float growLeftLimit;
+
+    /** 
+     * The grow right limit value repesents the maximum value by which 
+     * the right side of this glyph grows.
+     */
+    public final float growRightLimit;
+
+    /** 
+     * The grow priority value represents the priority level of this 
+     * glyph as it is growing. 
+     */
+    public final int growPriority;
+
+    /** 
+     * The shrink absorb fleg indicates this glyph absorbs all remaining 
+     * shrinkage at this and lower priority levels as it shrinks. 
+     */
+    public final boolean shrinkAbsorb;
+
+    /** 
+     * The shrink left limit value represents the maximum value by which 
+     * the left side of this glyph shrinks. 
+     */
+    public final float shrinkLeftLimit;
+
+    /** 
+     * The shrink right limit value represents the maximum value by which 
+     * the right side of this glyph shrinks. 
+     */
+    public final float shrinkRightLimit;
+
+    /**
+     * The shrink priority represents the glyth's priority level 
+     * as it is shrinking.
+     */
+    public final int shrinkPriority;
+
+    /** 
+     * The weight of the glyph. 
+     */
+    public final float weight;
+
+    /**
+     * Instantiates a new GlyphJustificationInfo object which contains
+     * glyph's justification properties.
+     * 
+     * @param weight the weight of glyph.
+     * @param growAbsorb indicates if this glyph contais all space 
+     * at this priority and lower priority levels when it grows.
+     * @param growPriority indicates the priority level of this glyph 
+     * when it grows.
+     * @param growLeftLimit indicates the maximum value of which the 
+     * left side of this glyph can grow.
+     * @param growRightLimit the maximum value of which the right side of 
+     * this glyph can grow.
+     * @param shrinkAbsorb indicates if this glyph contains all remaining
+     * shrinkage at this and lower priority levels when it shrinks.
+     * @param shrinkPriority indicates the glyph's priority level when 
+     * it shrinks.
+     * @param shrinkLeftLimit indicates the maximum value of which 
+     * the left side of this glyph can shrink. 
+     * @param shrinkRightLimit indicates the maximum amount by which 
+     * the right side of this glyph can shrink.
+     */
+    public GlyphJustificationInfo(float weight, boolean growAbsorb, int growPriority,
+            float growLeftLimit, float growRightLimit, boolean shrinkAbsorb,
+            int shrinkPriority, float shrinkLeftLimit, float shrinkRightLimit) {
+
+        if (weight < 0) {
+            // awt.19C=weight must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19C")); //$NON-NLS-1$
+        }
+        this.weight = weight;
+
+        if (growLeftLimit < 0) {
+            // awt.19D=growLeftLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19D")); //$NON-NLS-1$
+        }
+        this.growLeftLimit = growLeftLimit;
+
+        if (growRightLimit < 0) {
+            // awt.19E=growRightLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19E")); //$NON-NLS-1$
+        }
+        this.growRightLimit = growRightLimit;
+
+        if ((shrinkPriority < 0) || (shrinkPriority > PRIORITY_NONE)) {
+            // awt.19F=incorrect value for shrinkPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+            throw new IllegalArgumentException(Messages.getString("awt.19F")); //$NON-NLS-1$
+        }
+        this.shrinkPriority = shrinkPriority;
+
+        if ((growPriority < 0) || (growPriority > PRIORITY_NONE)) {
+            // awt.200=incorrect value for growPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+            throw new IllegalArgumentException(Messages.getString("awt.200")); //$NON-NLS-1$
+        }
+        this.growPriority = growPriority;
+
+        if (shrinkLeftLimit < 0) {
+            // awt.201=shrinkLeftLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.201")); //$NON-NLS-1$
+        }
+        this.shrinkLeftLimit = shrinkLeftLimit;
+
+        if (shrinkRightLimit < 0) {
+            // awt.202=shrinkRightLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.202")); //$NON-NLS-1$
+        }
+        this.shrinkRightLimit = shrinkRightLimit;
+
+        this.shrinkAbsorb = shrinkAbsorb;
+        this.growAbsorb = growAbsorb;
+    }
+}
diff --git a/awt/java/awt/font/GlyphMetrics.java b/awt/java/awt/font/GlyphMetrics.java
new file mode 100644
index 0000000..d96ef18
--- /dev/null
+++ b/awt/java/awt/font/GlyphMetrics.java
@@ -0,0 +1,248 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphMetrics class provides information about the size and shape 
+ * of a single glyph. 
+ * Each glyph has information to specify whether its baseline is horizontal 
+ * or vertical as well as information on how it interacts with 
+ * other characters in a text, given as one of the
+ * following types: STANDARD, LIGATURE, COMBINING, or COMPONENT.
+ */
+public final class GlyphMetrics {
+
+    // advance width of the glyph character cell
+    /** The advance x. */
+    private float advanceX;
+    
+    // advance height of the glyph character cell
+    /** The advance y. */
+    private float advanceY;
+
+    // flag if the glyph horizontal
+    /** The horizontal. */
+    private boolean horizontal;
+
+    // glyph type code 
+    /** The glyph type. */
+    private byte glyphType;
+    
+    // bounding box for outline of the glyph
+    /** The bounds. */
+    private Rectangle2D.Float bounds;
+
+    /** 
+     * The Constant STANDARD indicates a glyph that represents a single 
+     * character. 
+     */
+    public static final byte STANDARD = 0;
+
+    /** 
+     * The Constant LIGATURE indicates a glyph that represents multiple 
+     * characters as a ligature. 
+     */
+    public static final byte LIGATURE = 1;
+
+    /** 
+     * The Constant COMBINING indicates a glyph which has no caret position 
+     * between glyphs (for example umlaut).
+     */
+    public static final byte COMBINING = 2;
+
+    /** 
+     * The Constant COMPONENT indicates a glyph with no corresponding character 
+     * in the backing store.
+     */
+    public static final byte COMPONENT = 3;
+
+    /** 
+     * The Constant WHITESPACE indicates a glyph without visual 
+     * representation. 
+     */
+    public static final byte WHITESPACE = 4;
+
+    /**
+     * Instantiates a new GlyphMetrics object with the specified parameters.
+     * 
+     * @param horizontal specifies if metrics are for a horizontal baseline 
+     * (true value), or a vertical baseline (false value).
+     * @param advanceX the X component of the glyph's advance.
+     * @param advanceY the Y component of the glyph's advance.
+     * @param bounds the glyph's bounds.
+     * @param glyphType the glyph's type.
+     */
+    public GlyphMetrics(boolean horizontal, float advanceX, float advanceY, 
+            Rectangle2D bounds, byte glyphType) {
+        this.horizontal = horizontal;
+        this.advanceX = advanceX;
+        this.advanceY = advanceY;
+
+        this.bounds = new Rectangle2D.Float();
+        this.bounds.setRect(bounds);
+
+        this.glyphType = glyphType;
+    }
+
+    /**
+     * Instantiates a new horizontal GlyphMetrics with the specified parameters.
+     * 
+     * @param advanceX the X component of the glyph's advance.
+     * @param bounds the glyph's bounds.
+     * @param glyphType the glyph's type.
+     */
+    public GlyphMetrics(float advanceX, Rectangle2D bounds, byte glyphType) {
+        this.advanceX = advanceX;
+        this.advanceY = 0;
+
+        this.horizontal = true;
+
+        this.bounds = new Rectangle2D.Float();
+        this.bounds.setRect(bounds);
+
+        this.glyphType = glyphType;
+    }
+
+    /**
+     * Gets the glyph's bounds.
+     * 
+     * @return glyph's bounds.
+     */
+    public Rectangle2D getBounds2D() {
+        return (Rectangle2D.Float) this.bounds.clone();
+    }
+
+    /**
+     * Checks if this glyph is whitespace or not.
+     * 
+     * @return true, if this glyph is whitespace, false otherwise.
+     */
+    public boolean isWhitespace() {
+        return ((this.glyphType & 4) == WHITESPACE);
+    }
+
+    /**
+     * Checks if this glyph is standard or not.
+     * 
+     * @return true, if this glyph is standard, false otherwise.
+     */
+    public boolean isStandard() {
+        return ((this.glyphType & 3) == STANDARD);
+    }
+
+    /**
+     * Checks if this glyph is ligature or not.
+     * 
+     * @return true, if this glyph is ligature, false otherwise.
+     */
+    public boolean isLigature() {
+        return ((this.glyphType & 3) == LIGATURE);
+    }
+
+    /**
+     * Checks if this glyph is component or not.
+     * 
+     * @return true, if this glyph is component, false otherwise.
+     */
+    public boolean isComponent() {
+        return ((this.glyphType & 3) == COMPONENT);
+    }
+
+    /**
+     * Checks if this glyph is combining or not.
+     * 
+     * @return true, if this glyph is combining, false otherwise.
+     */
+    public boolean isCombining() {
+        return ((this.glyphType & 3) == COMBINING);
+    }
+
+    /**
+     * Gets the glyph's type.
+     * 
+     * @return the glyph's type.
+     */
+    public int getType() {
+        return this.glyphType;
+    }
+
+    /**
+     * Gets the distance from the right (for horizontal) or 
+     * bottom (for vertical) of the glyph bounds to the advance.
+     * 
+     * @return the distance from the right (for horizontal) or 
+     * bottom (for vertical) of the glyph bounds to the advance.
+     */
+    public float getRSB() {
+        if (this.horizontal) {
+            return this.advanceX - this.bounds.x - (float)this.bounds.getWidth();
+        }
+        return this.advanceY - this.bounds.y - (float)this.bounds.getHeight();
+    }
+
+    /**
+     * Gets the distance from 0, 0 to the left (for horizontal) 
+     * or top (for vertical) of the glyph bounds.
+     * 
+     * @return the distance from 0, 0 to the left (for horizontal) 
+     * or top (for vertical) of the glyph bounds.
+     */
+    public float getLSB() {
+        if (this.horizontal) {
+            return this.bounds.x;
+        }
+        return this.bounds.y;
+    }
+
+    /**
+     * Gets the Y component of the glyph's advance.
+     * 
+     * @return the Y component of the glyph's advance.
+     */
+    public float getAdvanceY() {
+        return this.advanceY;
+    }
+
+    /**
+     * Gets the X component of the glyph's advance.
+     * 
+     * @return the X component of the glyph's advance.
+     */
+    public float getAdvanceX() {
+        return this.advanceX;
+    }
+
+    /**
+     * Gets the glyph's advance along the baseline.
+     * 
+     * @return the glyph's advance.
+     */
+    public float getAdvance() {
+        if (this.horizontal) {
+            return this.advanceX;
+        }
+        return this.advanceY;
+    }
+
+}
+
diff --git a/awt/java/awt/font/GlyphVector.java b/awt/java/awt/font/GlyphVector.java
new file mode 100644
index 0000000..b3c9406
--- /dev/null
+++ b/awt/java/awt/font/GlyphVector.java
@@ -0,0 +1,394 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphVector class contains a collection of glyphs with geometric 
+ * information and each glyph's location. Each GlyphVector can be associated 
+ * with only one Font. GlyphVector contains the following properties for 
+ * each glyph:
+ * <ul>
+ * <li>the glyph position;</li>
+ * <li>the transform of the glyph;</li>
+ * <li>the metrics of the glyph in the context of the GlyphVector.</li>
+ * </ul>
+ */
+public abstract class GlyphVector implements Cloneable {
+
+    /** 
+     * The Constant FLAG_HAS_TRANSFORMS indicates that this GlyphVector 
+     * has per-glyph transforms.
+     */
+    public static final int FLAG_HAS_TRANSFORMS = 1;
+
+    /** 
+     * The Constant FLAG_HAS_POSITION_ADJUSTMENTS indicates that 
+     * the GlyphVector has per-glyph position adjustments. 
+     */
+    public static final int FLAG_HAS_POSITION_ADJUSTMENTS = 2;
+
+    /** 
+     * The Constant FLAG_RUN_RTL indicates that this GlyphVector has a 
+     * right to left run direction.
+     */
+    public static final int FLAG_RUN_RTL = 4;
+
+    /** 
+     * The Constant FLAG_COMPLEX_GLYPHS indicates that this GlyphVector 
+     * has a complex glyph to char mapping.
+     */
+    public static final int FLAG_COMPLEX_GLYPHS = 8;
+
+    /** 
+     * The Constant FLAG_MASK indicates a mask for supported flags 
+     * from getLayoutFlags.
+     */
+    public static final int FLAG_MASK = 15; // (|) mask of other flags
+
+    /**
+     * Instantiates a new GlyphVector.
+     */
+    public GlyphVector() {
+    }
+
+    /**
+     * Gets the pixel bounds of the GlyphVector when rendered
+     * at the specified location with the specified FontRenderContext.
+     * 
+     * @param frc the FontRenderContext.
+     * @param x the X coordinate of the GlyphVector's location.
+     * @param y the Y coordinate of the GlyphVector's location.
+     * 
+     * @return the pixel bounds
+     */
+    public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
+        // default implementation - integer Rectangle, that encloses visual 
+        // bounds rectangle
+        Rectangle2D visualRect = getVisualBounds();
+
+        int minX = (int)Math.floor(visualRect.getMinX() + x);
+        int minY = (int)Math.floor(visualRect.getMinY() + y);
+        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the pixel bounds of the glyph with the specified index in
+     * this GlyphVector which is rendered with the specified
+     * FontRenderContext at the specified location.
+     * 
+     * @param index the glyph index in this GlyphVector.
+     * @param frc the FontRenderContext.
+     * @param x the X coordinate of the GlyphVector's location.
+     * @param y the Y coordinate of the GlyphVector's location.
+     * 
+     * @return a Rectangle bounds.
+     */
+    public Rectangle getGlyphPixelBounds(int index, FontRenderContext frc, 
+            float x, float y) {
+        Rectangle2D visualRect = getGlyphVisualBounds(index).getBounds2D();
+
+        int minX = (int)Math.floor(visualRect.getMinX() + x);
+        int minY = (int)Math.floor(visualRect.getMinY() + y);
+        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the visual bounds of the GlyphVector. 
+     * 
+     * @return the visual bounds of the GlyphVector.
+     */
+    public abstract Rectangle2D getVisualBounds();
+
+    /**
+     * Gets the logical bounds of the GlyphVector. 
+     * 
+     * @return the logical bounds of the GlyphVector.
+     */
+    public abstract Rectangle2D getLogicalBounds();
+
+    /**
+     * Sets the position of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * @param newPos the new position of the glyph at the specified glyphIndex.
+     */
+    public abstract void setGlyphPosition(int glyphIndex, Point2D newPos);
+
+    /**
+     * Gets the position of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * 
+     * @return the position of the specified glyph in this GlyphVector.
+     */
+    public abstract Point2D getGlyphPosition(int glyphIndex);
+
+    /**
+     * Sets the affine transform to a glyph with the specified index
+     * in this GlyphVector.
+     * 
+     * @param glyphIndex the glyth index in this GlyphVector.
+     * @param trans the AffineTransform to be assigned to the
+     * specified glyph.
+     */
+    public abstract void setGlyphTransform(int glyphIndex, 
+            AffineTransform trans);
+
+    /**
+     * Gets the transform of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * 
+     * @return the new transform of the glyph.
+     */
+    public abstract AffineTransform getGlyphTransform(int glyphIndex);
+
+    /**
+     * Compares this GlyphVector with the specified GlyphVector objects.
+     * 
+     * @param glyphVector the GlyphVector object to be compared.
+     * 
+     * @return true, if this GlyphVector is equal to the specified GlyphVector
+     * object, false otherwise.
+     */
+    public abstract boolean equals(GlyphVector glyphVector);
+
+    /**
+     * Gets the metrics of the glyph with the specified index
+     * in this GlyphVector.
+     * 
+     * @param glyphIndex index in this GlyphVector.
+     * 
+     * @return the metrics of the glyph with the specified index
+     * in this GlyphVector.
+     */
+    public abstract GlyphMetrics getGlyphMetrics(int glyphIndex);
+
+    /**
+     * Gets the justification information of the glyph 
+     * whose index is specified.
+     * 
+     * @param glyphIndex the glyph index.
+     * 
+     * @return the GlyphJustificationInfo for the specified glyph. 
+     */
+    public abstract GlyphJustificationInfo getGlyphJustificationInfo(
+            int glyphIndex);
+
+    /**
+     * Gets the FontRenderContext of this GlyphVector.
+     * 
+     * @return the FontRenderContext of this GlyphVector.
+     */
+    public abstract FontRenderContext getFontRenderContext();
+
+    /**
+     * Gets a Shape object which defines the visual representation 
+     * of the specified glyph in this GlyphVector, translated a 
+     * distance of x in the X direction and y in the Y direction. 
+     * 
+     * @param glyphIndex the glyth index in this GlyphVector.
+     * @param x the distance in the X direction to translate the 
+     * shape object before returning it.
+     * @param y the distance in the Y direction to translate the 
+     * shape object before returning it.
+     * 
+     * @return a Shape object which represents the visual representation 
+     * of the specified glyph in this GlyphVector - glyph outline. 
+     */
+    public Shape getGlyphOutline(int glyphIndex, float x, float y) {
+        Shape initialShape = getGlyphOutline(glyphIndex);
+        AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
+        return trans.createTransformedShape(initialShape);
+    }
+
+    /**
+     * Gets the visual bounds of the specified glyph in the GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * 
+     * @return the glyph visual bounds of the glyph with the specified
+     * index in the GlyphVector.
+     */
+    public abstract Shape getGlyphVisualBounds(int glyphIndex);
+
+    /**
+     * Gets a Shape object which defines the visual representation 
+     * of the specified glyph in this GlyphVector. 
+     *  
+     * @param glyphIndex the glyth index in this GlyphVector.
+     * 
+     * @return a Shape object which represents the visual representation 
+     * of the specified glyph in this GlyphVector - glyph outline. 
+     */
+    public abstract Shape getGlyphOutline(int glyphIndex);
+
+    /**
+     * Gets the logical bounds of the specified glyph in 
+     * the GlyphVector. 
+     * 
+     * @param glyphIndex the index in this GlyphVector of the glyph from which 
+     * to retrieve its logical bounds
+     * 
+     * @return the logical bounds of the specified glyph in 
+     * the GlyphVector.
+     */
+    public abstract Shape getGlyphLogicalBounds(int glyphIndex);
+
+    /**
+     * Gets the visual representation of this GlyphVector rendered in
+     * x, y location as a Shape object.
+     * 
+     * @param x the x coordinate of the GlyphVector.
+     * @param y the y coordinate of the GlyphVector.
+     * 
+     * @return the visual representation of this GlyphVector as a Shape object.
+     */
+    public abstract Shape getOutline(float x, float y);
+
+    /**
+     * Gets the visual representation of this GlyphVector as a Shape object.
+     * 
+     * @return the visual representation of this GlyphVector as a Shape object.
+     */
+    public abstract Shape getOutline();
+
+    /**
+     * Gets the font of this GlyphVector.
+     * 
+     * @return the font of this GlyphVector.
+     */
+    public abstract Font getFont();
+
+    /**
+     * Gets an array of the glyph codes of the specified glyphs.
+     * 
+     * @param beginGlyphIndex the index into this GlyphVector at which 
+     * to start retrieving glyph codes.
+     * @param numEntries the number of glyph codes.
+     * @param codeReturn the array into which the resulting 
+     * glyphcodes will be written.
+     * 
+     * @return the array of the glyph codes.
+     */
+    public abstract int[] getGlyphCodes(int beginGlyphIndex, int numEntries, 
+            int[] codeReturn);
+
+    /**
+     * Gets an array of the character indices of 
+     * the specified glyphs.
+     * 
+     * @param beginGlyphIndex the index of the first glyph to return information for.
+     * @param numEntries the number of glyph indices to return.
+     * @param codeReturn the array into which the resulting character 
+     * indices will be written.
+     * 
+     * @return an array of character indices for the specifies glyphs.
+     */
+    public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries, 
+            int[] codeReturn) {
+        if (codeReturn == null) {
+            codeReturn = new int[numEntries];
+        }
+
+        for (int i = 0; i < numEntries; i++){
+            codeReturn[i] = getGlyphCharIndex(i+beginGlyphIndex);
+        }
+        return codeReturn;
+    }
+
+    /**
+     * Gets an array of the positions of the specified glyphs in 
+     * this GlyphVector.
+     * 
+     * @param beginGlyphIndex the index of the first glyph to return information for.
+     * @param numEntries the number of glyphs to return information for.
+     * @param positionReturn the array where the result will be stored. 
+     * 
+     * @return an array of glyph positions.
+     */
+    public abstract float[] getGlyphPositions(int beginGlyphIndex, 
+            int numEntries, float[] positionReturn);
+
+    /**
+     * Gets the glyph code of the specified glyph.
+     * 
+     * @param glyphIndex the index in this GlyphVector which corresponds 
+     * to the glyph from which to retrieve the glyphcode.
+     * 
+     * @return the glyphcode of the specified glyph.
+     */
+    public abstract int getGlyphCode(int glyphIndex);
+
+    /**
+     * Gets the first logical character's index of the specified glyph. 
+     *  
+     * @param glyphIndex the glyph index.
+     * 
+     * @return the the first logical character's index.
+     */
+    public int getGlyphCharIndex(int glyphIndex){
+        // default implemetation one-to-one
+        return glyphIndex;
+    }
+
+    /**
+     * Sets default layout to this GlyphVector. 
+     */
+    public abstract void performDefaultLayout();
+
+    /**
+     * Gets the number of glyphs in the GlyphVector.
+     * 
+     * @return the number of glyphs in the GlyphVector.
+     */
+    public abstract int getNumGlyphs();
+
+    /**
+     * Gets flags which describe the global state of the GlyphVector. 
+     * The default implementation returns 0.
+     * 
+     * @return the layout flags
+     */
+    public int getLayoutFlags(){
+        // default implementation - returned value is 0
+        return 0;
+    }
+
+}
+
diff --git a/awt/java/awt/font/GraphicAttribute.java b/awt/java/awt/font/GraphicAttribute.java
new file mode 100644
index 0000000..2f41951
--- /dev/null
+++ b/awt/java/awt/font/GraphicAttribute.java
@@ -0,0 +1,196 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicAttribute abstract class provides an opportunity to
+ * insert graphical elements in printed text.   
+ */
+public abstract class GraphicAttribute {
+
+    /** 
+     * The Constant TOP_ALIGNMENT indicates using the top line to 
+     * calculate placement of graphics.
+     */
+    public static final int TOP_ALIGNMENT = -1;
+
+    /** 
+     * The Constant BOTTOM_ALIGNMENT indicates using the bottom line to 
+     * calculate placement of graphics. 
+     */
+    public static final int BOTTOM_ALIGNMENT = -2;
+
+    /** 
+     * The Constant ROMAN_BASELINE indicates the placement of the roman 
+     * baseline with respect to the graphics origin.
+     */
+    public static final int ROMAN_BASELINE = 0;
+
+    /** 
+     * The Constant CENTER_BASELINE indicates the placement of the center 
+     * baseline with respect to the graphics origin.
+     */
+    public static final int CENTER_BASELINE = 1;
+
+    /** 
+     * The Constant HANGING_BASELINE indicates the placement of the hanging 
+     * baseline with respect to the graphics origin. 
+     */
+    public static final int HANGING_BASELINE = 2;
+
+    // the alignment of this GraphicAttribute
+    /** The alignment. */
+    private int alignment;
+
+    /**
+     * Instantiates a new graphic attribute with the specified alignment.
+     * 
+     * @param align the specified alignment.
+     */
+    protected GraphicAttribute(int align) {
+        if ((align < BOTTOM_ALIGNMENT) || (align > HANGING_BASELINE)) {
+            // awt.198=Illegal alignment argument
+            throw new IllegalArgumentException(Messages.getString("awt.198")); //$NON-NLS-1$
+        }
+        this.alignment = align;
+    }
+
+    /**
+     * Draws the GraphicAttribute at the specified location.
+     * 
+     * @param graphics the Graphics.
+     * @param x the X coordinate of GraphicAttribute location.
+     * @param y the Y coordinate of GraphicAttribute location.
+     */
+    public abstract void draw(Graphics2D graphics, float x, float y);
+
+    /**
+     * Gets the GraphicAttribute's advance. It's the distance from the point 
+     * at which the graphic is rendered and the point where the next character 
+     * or graphic is rendered.
+     * 
+     * @return the GraphicAttribute's advance.
+     */
+    public abstract float getAdvance();
+
+    /**
+     * Gets the alignment of this GraphicAttribute.
+     * 
+     * @return the alignment of this GraphicAttribute.
+     */
+    public final int getAlignment() {
+        return this.alignment;
+    }
+
+    /**
+     * Gets the ascent of this GraphicAttribute.
+     * 
+     * @return the ascent of this GraphicAttribute.
+     */
+    public abstract float getAscent();
+
+    /**
+     * Gets the bounds of this GraphicAttribute.
+     * 
+     * @return the bounds of this GraphicAttribute.
+     */
+    public Rectangle2D getBounds() {
+        float ascent = getAscent();
+        float advance = getAdvance();
+        float descent = getDescent();
+
+        // Default implementation - see API documentation.
+        return new Rectangle2D.Float(0, -ascent, advance, ascent + descent);
+    }
+
+    /**
+     * Gets the descent of this GraphicAttribute.
+     * 
+     * @return the descent of this GraphicAttribute.
+     */
+    public abstract float getDescent();
+
+    /**
+     * Gets the GlyphJustificationInfo of this GraphicAttribute.
+     * 
+     * @return the GlyphJustificationInfo of this GraphicAttribute.
+     */
+    public GlyphJustificationInfo getJustificationInfo() {
+        
+        /* Default implementation.
+         * Since documentation doesn't describe default values,
+         * they were calculated based on 1.5 release 
+         * behavior and can be obtained using next test sample:
+         * 
+         *    // Create GraphicAttribute class implementation
+         *    public class MyGraphicAttribute extends GraphicAttribute {
+         *        protected MyGraphicAttribute(int align) {
+         *            super(align);
+         *        }
+         *
+         *        public float getDescent() {
+         *           return 0;
+         *        }
+         *
+         *        public float getAdvance() {
+         *           return 1;
+         *        }
+         *
+         *        public void draw(Graphics2D g2, float x, float y) {
+         *        }
+         *
+         *        public float getAscent() {
+         *            return 0;
+         *        }
+         *    }
+         *
+         *    MyGraphicAttribute myGA = gat.new MyGraphicAttribute(0);
+         *    // print justification parameters
+         *    System.out.println(myGA.getJustificationInfo().growAbsorb);
+         *    System.out.println(myGA.getJustificationInfo().shrinkAbsorb);
+         *    System.out.println(myGA.getJustificationInfo().growLeftLimit);
+         *    System.out.println(myGA.getJustificationInfo().growPriority);
+         *    System.out.println(myGA.getJustificationInfo().growRightLimit);
+         *    System.out.println(myGA.getJustificationInfo().shrinkLeftLimit);
+         *    System.out.println(myGA.getJustificationInfo().shrinkPriority);
+         *    System.out.println(myGA.getJustificationInfo().shrinkRightLimit);
+         *    System.out.println(myGA.getJustificationInfo().weight);
+         */
+        float advance = getAdvance();
+        return new GlyphJustificationInfo(
+                                    advance,
+                                    false,
+                                    GlyphJustificationInfo.PRIORITY_INTERCHAR,
+                                    advance / 3,
+                                    advance / 3,
+                                    false,
+                                    GlyphJustificationInfo.PRIORITY_WHITESPACE,
+                                    0,
+                                    0);
+    }
+
+}
+
diff --git a/awt/java/awt/font/ImageGraphicAttribute.java b/awt/java/awt/font/ImageGraphicAttribute.java
new file mode 100644
index 0000000..41f90b8
--- /dev/null
+++ b/awt/java/awt/font/ImageGraphicAttribute.java
@@ -0,0 +1,179 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The ImageGraphicAttribute class provides an opportunity to insert 
+ * images to a text.
+ */
+public final class ImageGraphicAttribute extends GraphicAttribute {
+
+    // Image object rendered by this ImageGraphicAttribute
+    /** The image. */
+    private Image fImage;
+
+    // X coordinate of the origin point
+    /** The origin x. */
+    private float fOriginX;
+
+    // Y coordinate of the origin point
+    /** The origin y. */
+    private float fOriginY;
+
+    // the width of the image object
+    /** The img width. */
+    private float fImgWidth;
+
+    // the height of the image object
+    /** The img height. */
+    private float fImgHeight;
+
+    /**
+     * Instantiates a new ImageGraphicAttribute with the specified image,
+     * alignment and origins.
+     * 
+     * @param image the Image to be rendered by ImageGraphicAttribute.
+     * @param alignment the alignment of the ImageGraphicAttribute.
+     * @param originX the origin X coordinate in the image of
+     * ImageGraphicAttribute.  
+     * @param originY the origin Y coordinate in the image of
+     * ImageGraphicAttribute.  
+     */
+    public ImageGraphicAttribute(Image image, int alignment, float originX, 
+            float originY) {
+        super(alignment);
+
+        this.fImage = image;
+        this.fOriginX = originX;
+        this.fOriginY = originY;
+
+        this.fImgWidth = fImage.getWidth(null);
+        this.fImgHeight = fImage.getHeight(null);
+
+    }
+
+    /**
+     * Instantiates a new ImageGraphicAttribute with the specified image and
+     * alignment.
+     * 
+     * @param image the Image to be rendered by ImageGraphicAttribute.
+     * @param alignment the alignment of the ImageGraphicAttribute.
+     */
+    public ImageGraphicAttribute(Image image, int alignment) {
+        this(image, alignment, 0, 0);
+    }
+
+    /**
+     * Returns a hash code of this ImageGraphicAttribute object.
+     * 
+     * @return the hash code of this ImageGraphicAttribute object.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(fImage.hashCode());
+        hash.append(getAlignment());
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares the specified ImageGraphicAttribute object with this
+     * ImageGraphicAttribute object.
+     * 
+     * @param iga the ImageGraphicAttribute object to be compared.
+     * 
+     * @return true, if the specified ImageGraphicAttribute object is equal to
+     * this ImageGraphicAttribute object, false otherwise.
+     */
+    public boolean equals(ImageGraphicAttribute iga) {
+        if (iga == null) {
+            return false;
+        }
+
+        if (iga == this) {
+            return true;
+        }
+
+        return (fOriginX == iga.fOriginX &&
+                fOriginY == iga.fOriginY &&
+                getAlignment() == iga.getAlignment() &&
+                fImage.equals(iga.fImage));
+    }
+
+    /**
+     * Compares the specified Object with this ImageGraphicAttribute object.
+     *  
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is equal to this
+     * ImageGraphicAttribute object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        try {
+            return equals((ImageGraphicAttribute) obj);
+        }
+        catch(ClassCastException e) {
+            return false;
+        }
+
+    }
+
+    @Override
+    public void draw(Graphics2D g2, float x, float y) {
+        g2.drawImage(fImage, (int)(x - fOriginX), (int)(y - fOriginY), null);
+    }
+
+    /** 
+     * @see java.awt.font.GraphicAttribute#getAdvance()
+     */
+    @Override
+    public float getAdvance() {
+        return Math.max(0, fImgWidth - fOriginX);
+    }
+
+    @Override
+    public float getAscent() {
+        return Math.max(0, fOriginY);
+    }
+
+    @Override
+    public Rectangle2D getBounds() {
+        return new Rectangle2D.Float(-fOriginX, -fOriginY, fImgWidth, fImgHeight);
+    }
+
+    /** 
+     * @see java.awt.font.GraphicAttribute#getDescent()
+     */
+    @Override
+    public float getDescent() {
+        return Math.max(0, fImgHeight - fOriginY);
+    }
+
+}
+
diff --git a/awt/java/awt/font/LineBreakMeasurer.java b/awt/java/awt/font/LineBreakMeasurer.java
new file mode 100644
index 0000000..efce615
--- /dev/null
+++ b/awt/java/awt/font/LineBreakMeasurer.java
@@ -0,0 +1,231 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.text.AttributedCharacterIterator;
+//???AWT: import java.text.BreakIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The class LineBreakMeasurer provides methods to measure the graphical 
+ * representation of a text in order to determine where to add line 
+ * breaks so the resulting line of text fits its wrapping width. 
+ * The wrapping width defines the visual width of the paragraph.
+ */
+public final class LineBreakMeasurer {
+    
+    /** The tm. */
+    private TextMeasurer tm = null;
+    //???AWT private BreakIterator bi = null;
+    /** The position. */
+    private int position = 0;
+    
+    /** The maxpos. */
+    int maxpos = 0;
+
+    /**
+     * Instantiates a new LineBreakMeasurer object for the specified text.
+     * 
+     * @param text the AttributedCharacterIterator object which contains
+     * text with at least one character.
+     * @param frc the FontRenderContext represented information
+     * about graphic device.
+     */
+    public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+        //???AWT: this(text, BreakIterator.getLineInstance(), frc);
+    }
+
+    /* ???AWT
+    public LineBreakMeasurer(
+            AttributedCharacterIterator text,
+            BreakIterator bi,
+            FontRenderContext frc
+    ) {
+        tm = new TextMeasurer(text, frc);
+        this.bi = bi;
+        this.bi.setText(text);
+        position = text.getBeginIndex();
+        maxpos = tm.aci.getEndIndex();
+    }
+    */
+
+    /**
+     * Deletes a character from the specified position of the text, 
+     * updates this LineBreakMeasurer object.
+     * 
+     * @param newText the new text.
+     * @param pos the posion of the character which is deleted.
+     */
+    public void deleteChar(AttributedCharacterIterator newText, int pos) {
+        tm.deleteChar(newText, pos);
+        //???AWT: bi.setText(newText);
+
+        position = newText.getBeginIndex();
+
+        maxpos--;
+    }
+
+    /**
+     * Gets current position of this LineBreakMeasurer.
+     * 
+     * @return current position of this LineBreakMeasurer
+     */
+    public int getPosition() {
+        return position;
+    }
+
+    /**
+     * Insertes a character at the specified position in the text, 
+     * updates this LineBreakMeasurer object.
+     * 
+     * @param newText the new text.
+     * @param pos the posion of the character which is inserted.
+     */
+    public void insertChar(AttributedCharacterIterator newText, int pos) {
+        tm.insertChar(newText, pos);
+//      ???AWT: bi.setText(newText);
+
+        position = newText.getBeginIndex();
+
+        maxpos++;
+    }
+
+    /**
+     * Returns the next line of text, updates current position in this 
+     * LineBreakMeasurer.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * @param offsetLimit the limit point withing the text indicating
+     * that no further text should be included on the line; the paragraph break.
+     * @param requireNextWord if true, null is returned (the entire word at the current 
+     * position does not fit within the wrapping width);  
+     * if false, a valid layout is returned that includes at least the 
+     * character at the current position.
+     * 
+     * @return the next TextLayout which begins at the current position and 
+     * represents the next line of text with width wrappingWidth, null is 
+     * returned if the entire word at the current position does not fit within 
+     * the wrapping width.
+     */
+    public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+        if (position == maxpos) {
+            return null;
+        }
+
+        int nextPosition = nextOffset(wrappingWidth, offsetLimit, requireNextWord);
+
+        if (nextPosition == position) {
+            return null;
+        }
+        TextLayout layout = tm.getLayout(position, nextPosition);
+        position = nextPosition;
+        return layout;
+    }
+
+    /**
+     * Returns the next line of text.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * 
+     * @return the next line of text.
+     */
+    public TextLayout nextLayout(float wrappingWidth) {
+        return nextLayout(wrappingWidth, maxpos, false);
+    }
+
+    /**
+     * Returns the end position of the next line of text.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * 
+     * @return the end position of the next line of text.
+     */
+    public int nextOffset(float wrappingWidth) {
+        return nextOffset(wrappingWidth, maxpos, false);
+    }
+
+    /**
+     * Returns the end position of the next line of text.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * @param offsetLimit the limit point withing the text indicating
+     * that no further text should be included on the line; the paragraph break.
+     * @param requireNextWord if true, the current position is returned 
+     * if the entire next word does not fit within wrappingWidth; 
+     * if false, the offset returned is at least one greater than the current
+     * position.
+     * 
+     * @return the end position of the next line of text.
+     * 
+     * @throws IllegalArgumentException if the offsetLimit is less than 
+     * the current position.
+     */
+    public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+        if (offsetLimit <= position) {
+            // awt.203=Offset limit should be greater than current position. 
+            throw new IllegalArgumentException(Messages.getString("awt.203")); //$NON-NLS-1$
+        }
+
+        if (position == maxpos) {
+            return position;
+        }
+
+        int breakPos = tm.getLineBreakIndex(position, wrappingWidth);
+        int correctedPos = breakPos;
+
+        // This check is required because bi.preceding(maxpos) throws an exception
+        /* ???AWT
+        if (breakPos == maxpos) {
+            correctedPos = maxpos;
+        } else if (Character.isWhitespace(bi.getText().setIndex(breakPos))) {
+            correctedPos = bi.following(breakPos);
+        } else {
+            correctedPos = bi.preceding(breakPos);
+        }
+        */
+        
+        if (position >= correctedPos) {
+            if (requireNextWord) {
+                correctedPos = position;
+            } else {
+                correctedPos = Math.max(position+1, breakPos);
+            }
+        }
+
+        return Math.min(correctedPos, offsetLimit);
+    }
+
+    /**
+     * Sets the new position of this LineBreakMeasurer.
+     * 
+     * @param pos the new position of this LineBreakMeasurer.
+     */
+    public void setPosition(int pos) {
+        if (tm.aci.getBeginIndex() > pos || maxpos < pos) {
+            // awt.33=index is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.33")); //$NON-NLS-1$
+        }
+        position = pos;
+    }
+}
+
diff --git a/awt/java/awt/font/LineMetrics.java b/awt/java/awt/font/LineMetrics.java
new file mode 100644
index 0000000..2857187
--- /dev/null
+++ b/awt/java/awt/font/LineMetrics.java
@@ -0,0 +1,115 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+/**
+ * The LineMetrics class provides information such as concerning how the text 
+ * is positioned with respect to the base line, such as ascent, descent, 
+ * and leading.
+ * 
+ */
+public abstract class LineMetrics {
+
+    /**
+     * Gets the baseline offsets of the text according to the 
+     * the baseline of this text.
+     * 
+     * @return the baseline offsets of the text according to the 
+     * the baseline of this text.
+     */
+    public abstract float[] getBaselineOffsets();
+
+    /**
+     * Gets the number of characters of the text.
+     * 
+     * @return the number of characters of the text.
+     */
+    public abstract int getNumChars();
+
+    /**
+     * Gets the baseline index, returns one of the following 
+     * index: ROMAN_BASELINE, CENTER_BASELINE, HANGING_BASELINE.
+     * 
+     * @return the baseline index: ROMAN_BASELINE, CENTER_BASELINE
+     * or HANGING_BASELINE.
+     */
+    public abstract int getBaselineIndex();
+
+    /**
+     * Gets the thickness of the underline.
+     * 
+     * @return the thickness of the underline.
+     */
+    public abstract float getUnderlineThickness();
+
+    /**
+     * Gets the offset of the underline.
+     * 
+     * @return the offset of the underline.
+     */
+    public abstract float getUnderlineOffset();
+
+    /**
+     * Gets the thickness of strike through line.
+     * 
+     * @return the thickness of strike through line.
+     */
+    public abstract float getStrikethroughThickness();
+
+    /**
+     * Gets the offset of the strike through line.
+     * 
+     * @return the offset of the strike through line.
+     */
+    public abstract float getStrikethroughOffset();
+
+    /**
+     * Gets the leading of the text.
+     * 
+     * @return the leading of the text.
+     */
+    public abstract float getLeading();
+
+    /**
+     * Gets the height of the text as a sum of the ascent, the descent 
+     * and the leading.
+     * 
+     * @return the height of the text as a sum of the ascent, the descent 
+     * and the leading.
+     */
+    public abstract float getHeight();
+
+    /**
+     * Gets the descent of the text.
+     * 
+     * @return the descent of the text.
+     */
+    public abstract float getDescent();
+
+    /**
+     * Gets the ascent of the text.
+     * 
+     * @return the ascent of the text.
+     */
+    public abstract float getAscent();
+
+}
+
diff --git a/awt/java/awt/font/MultipleMaster.java b/awt/java/awt/font/MultipleMaster.java
new file mode 100644
index 0000000..773bfcf
--- /dev/null
+++ b/awt/java/awt/font/MultipleMaster.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Font;
+
+/**
+ * The MultipleMaster interface provides methods to manipulate MultipleMaster 
+ * type fonts and retrieve graphical and design data from them.
+ */
+public interface MultipleMaster {
+
+    /**
+     * Derives a new multiple master font based on the specified 
+     * parameters.
+     * 
+     * @param glyphWidths float array which represents width of each glyph
+     * in font space.
+     * @param avgStemWidth the average stem width in font space.
+     * @param typicalCapHeight the typical upper case char height.
+     * @param typicalXHeight the typical lower case char height.
+     * @param italicAngle the slope angle for italics.
+     * 
+     * @return a MultipleMaster font.
+     */
+    public Font deriveMMFont(float[] glyphWidths, float avgStemWidth,
+            float typicalCapHeight, float typicalXHeight, float italicAngle);
+
+    /**
+     * Derives a new multiple master font based on the design axis values 
+     * contained in the specified array. 
+     * 
+     * @param axes an float array which contains axis values.
+     * 
+     * @return a MultipleMaster font.
+     */
+    public Font deriveMMFont(float[] axes);
+
+    /**
+     * Gets default design values for the axes.
+     * 
+     * @return the default design values for the axes.
+     */
+    public float[] getDesignAxisDefaults();
+
+    /**
+     * Gets the array of design axis names. 
+     * 
+     * @return the array of design axis names. 
+     */
+    public String[] getDesignAxisNames();
+
+    /**
+     * Gets the array of design axis ranges. 
+     * 
+     * @return the array of design axis ranges.
+     */
+    public float[] getDesignAxisRanges();
+
+    /**
+     * Gets the number of multiple master design controls. 
+     * 
+     * @return the number of multiple master design controls.
+     */
+    public int getNumDesignAxes();
+
+}
+
diff --git a/awt/java/awt/font/OpenType.java b/awt/java/awt/font/OpenType.java
new file mode 100644
index 0000000..53cb6c0
--- /dev/null
+++ b/awt/java/awt/font/OpenType.java
@@ -0,0 +1,410 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+/**
+ * The OpenType interface provides constants and methods for getting 
+ * instance data for fonts of type OpenType and TrueType. For more information,
+ * see the <a href="http://partners.adobe.com/public/developer/opentype/index_spec.html">OpenType specification</a>.
+ */
+public interface OpenType {
+
+    /** 
+     * The Constant TAG_ACNT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_ACNT = 1633906292;
+
+    /** 
+     * The Constant TAG_AVAR indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_AVAR = 1635148146;
+
+    /** 
+     * The Constant TAG_BASE indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BASE = 1111577413;
+
+    /** 
+     * The Constant TAG_BDAT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BDAT = 1650745716;
+
+    /** 
+     * The Constant TAG_BLOC indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BLOC = 1651273571;
+
+    /** 
+     * The Constant TAG_BSLN indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BSLN = 1651731566;
+
+    /** 
+     * The Constant TAG_CFF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CFF = 1128678944;
+
+    /** 
+     * The Constant TAG_CMAP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CMAP = 1668112752;
+
+    /** 
+     * The Constant TAG_CVAR indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CVAR = 1668702578;
+
+    /** 
+     * The Constant TAG_CVT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CVT = 1668707360;
+
+    /** 
+     * The Constant TAG_DSIG indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_DSIG = 1146308935;
+
+    /** 
+     * The Constant TAG_EBDT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_EBDT = 1161970772;
+
+    /** 
+     * The Constant TAG_EBLC indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_EBLC = 1161972803;
+
+    /** 
+     * The Constant TAG_EBSC  indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_EBSC = 1161974595;
+
+    /** 
+     * The Constant TAG_FDSC indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_FDSC = 1717859171;
+
+    /** 
+     * The Constant TAG_FEAT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FEAT = 1717920116;
+
+    /** 
+     * The Constant TAG_FMTX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FMTX = 1718449272;
+
+    /** 
+     * The Constant TAG_FPGM indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FPGM = 1718642541;
+
+    /** 
+     * The Constant TAG_FVAR indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FVAR = 1719034226;
+
+    /** 
+     * The Constant TAG_GASP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GASP = 1734439792;
+
+    /** 
+     * The Constant TAG_GDEF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GDEF = 1195656518;
+
+    /** 
+     * The Constant TAG_GLYF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GLYF = 1735162214;
+
+    /** 
+     * The Constant TAG_GPOS indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GPOS = 1196445523;
+
+    /** 
+     * The Constant TAG_GSUB indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GSUB = 1196643650;
+
+    /** 
+     * The Constant TAG_GVAR indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_GVAR = 1735811442;
+
+    /** 
+     * The Constant TAG_HDMX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HDMX = 1751412088;
+
+    /** 
+     * The Constant TAG_HEAD indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HEAD = 1751474532;
+
+    /** 
+     * The Constant TAG_HHEA indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HHEA = 1751672161;
+
+    /** 
+     * The Constant TAG_HMTX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HMTX = 1752003704;
+
+    /** 
+     * The Constant TAG_JSTF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_JSTF = 1246975046;
+
+    /** 
+     * The Constant TAG_JUST indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_JUST = 1786082164;
+
+    /** 
+     * The Constant TAG_KERN indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_KERN = 1801810542;
+
+    /** 
+     * The Constant TAG_LCAR indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_LCAR = 1818452338;
+
+    /** 
+     * The Constant TAG_LOCA indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_LOCA = 1819239265;
+
+    /** 
+     * The Constant TAG_LTSH indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_LTSH = 1280594760;
+
+    /** 
+     * The Constant TAG_MAXP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MAXP = 1835104368;
+
+    /** 
+     * The Constant TAG_MMFX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MMFX = 1296909912;
+
+    /** 
+     * The Constant TAG_MMSD indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MMSD = 1296913220;
+
+    /** 
+     * The Constant TAG_MORT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MORT = 1836020340;
+
+    /** 
+     * The Constant TAG_NAME indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_NAME = 1851878757;
+
+    /** 
+     * The Constant TAG_OPBD indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_OPBD = 1836020340;
+
+    /** 
+     * The Constant TAG_OS2 indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_OS2 = 1330851634;
+
+    /** 
+     * The Constant TAG_PCLT  indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_PCLT = 1346587732;
+
+    /** 
+     * The Constant TAG_POST indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_POST = 1886352244;
+
+    /** 
+     * The Constant TAG_PREP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_PREP = 1886545264;
+
+    /** 
+     * The Constant TAG_PROP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_PROP = 1886547824;
+
+    /** 
+     * The Constant TAG_TRAK indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_TRAK = 1953653099;
+
+    /** 
+     * The Constant TAG_TYP1 indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_TYP1 = 1954115633;
+
+    /** 
+     * The Constant TAG_VDMX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_VDMX = 1447316824;
+
+    /** 
+     * The Constant TAG_VHEA indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_VHEA = 1986553185;
+
+    /** 
+     * The Constant TAG_VMTX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_VMTX = 1986884728;
+
+    /**
+     * Returns the OpenType font version.
+     * 
+     * @return the the OpenType font version.
+     */
+    public int getVersion();
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items. 
+     *  
+     * @param sfntTag the sfnt tag.
+     * 
+     * @return a byte array contains the font data corresponding 
+     * to the specified tag.
+     */
+    public byte[] getFontTable(int sfntTag);
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items. 
+     *  
+     * @param sfntTag the sfnt tag.
+     * @param offset the offset of the returned table.
+     * @param count the number of returned table.
+     * 
+     * @return the table corresponding to sfntTag and containing 
+     * the bytes starting at offset byte and including count bytes.
+     */
+    public byte[] getFontTable(int sfntTag, int offset, int count);
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items.
+     * 
+     * @param strSfntTag the str sfnt tag as a String.
+     * 
+     * @return a byte array contains the font data corresponding 
+     * to the specified tag.
+     */
+    public byte[] getFontTable(String strSfntTag);
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items. 
+     *  
+     * @param strSfntTag the sfnt tag as a String.
+     * @param offset the offset of the returned table.
+     * @param count the number of returned table.
+     * 
+     * @return the table corresponding to sfntTag and containing 
+     * the bytes starting at offset byte and including count bytes.
+     */
+    public byte[] getFontTable(String strSfntTag, int offset, int count);
+
+    /**
+     * Gets the table size for a specified tag. 
+     * 
+     * @param strSfntTag the sfnt tag as a String.
+     * 
+     * @return the table size for a specified tag.
+     */
+    public int getFontTableSize(String strSfntTag);
+
+    /**
+     * Gets the table size for a specified tag. 
+     * 
+     * @param sfntTag the sfnt tag.
+     * 
+     * @return the table size for a specified tag.
+     */
+    public int getFontTableSize(int sfntTag);
+
+}
+
diff --git a/awt/java/awt/font/ShapeGraphicAttribute.java b/awt/java/awt/font/ShapeGraphicAttribute.java
new file mode 100644
index 0000000..45199fd
--- /dev/null
+++ b/awt/java/awt/font/ShapeGraphicAttribute.java
@@ -0,0 +1,195 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The ShapeGraphicAttribute class provides an opportunity to insert 
+ * shapes to a text.
+ */
+public final class ShapeGraphicAttribute extends GraphicAttribute {
+
+    // shape to render
+    /** The shape. */
+    private Shape fShape;
+    
+    // flag, if the shape should be stroked (true) or filled (false)
+    /** The stroke. */
+    private boolean fStroke;
+
+    // bounds of the shape
+    /** The bounds. */
+    private Rectangle2D fBounds;
+    
+    // X coordinate of the origin point
+    /** The origin x. */
+    private float fOriginX;
+    
+    // Y coordinate of the origin point
+    /** The origin y. */
+    private float fOriginY;
+
+    // width of the shape
+    /** The shape width. */
+    private float fShapeWidth;
+    
+    // height of the shape
+    /** The shape height. */
+    private float fShapeHeight;
+
+    /** 
+     * The Constant STROKE indicates whether the Shape is stroked 
+     * or not. 
+     */
+    public static final boolean STROKE = true;
+
+    /** 
+     * The Constant FILL indicates whether the Shape is filled 
+     * or not. */
+    public static final boolean FILL = false;
+
+    /**
+     * Instantiates a new ShapeGraphicAttribute object for the specified 
+     * Shape.
+     * 
+     * @param shape the shape to be rendered by this 
+     * ShapeGraphicAttribute.
+     * @param alignment the alignment of this ShapeGraphicAttribute.
+     * @param stroke true if the Shape is stroked,
+     *  false if the Shape is filled.
+     */
+    public ShapeGraphicAttribute(Shape shape, int alignment, boolean stroke) {
+        super(alignment);
+
+        this.fShape = shape;
+        this.fStroke = stroke;
+
+        this.fBounds  = fShape.getBounds2D();
+
+        this.fOriginX = (float)fBounds.getMinX();
+        this.fOriginY = (float)fBounds.getMinY();
+
+        this.fShapeWidth = (float)fBounds.getWidth();
+        this.fShapeHeight = (float)fBounds.getHeight();
+    }
+
+    /**
+     * Returns a hash code of this ShapeGraphicAttribute object.
+     * 
+     * @return a hash code of this ShapeGraphicAttribute object.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(fShape.hashCode());
+        hash.append(getAlignment());
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this ShapeGraphicAttribute object to the specified
+     * ShapeGraphicAttribute object.
+     * 
+     * @param sga the ShapeGraphicAttribute object to be compared.
+     * 
+     * @return true, if this ShapeGraphicAttribute object is equal
+     * to the specified ShapeGraphicAttribute object, false otherwise.
+     */
+    public boolean equals(ShapeGraphicAttribute sga) {
+        if (sga == null) {
+            return false;
+        }
+
+        if (sga == this) {
+            return true;
+        }
+
+        return ( fStroke == sga.fStroke &&
+                getAlignment() == sga.getAlignment() &&
+                fShape.equals(sga.fShape));
+
+    }
+
+    /**
+     * Compares this ShapeGraphicAttribute object to the specified
+     * Object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if this ShapeGraphicAttribute object is equal
+     * to the specified Object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        try {
+            return equals((ShapeGraphicAttribute) obj);
+        }
+        catch(ClassCastException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public void draw(Graphics2D g2, float x, float y) {
+        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
+        if (fStroke == STROKE){
+            Stroke oldStroke = g2.getStroke();
+            g2.setStroke(new BasicStroke());
+            g2.draw(at.createTransformedShape(fShape));
+            g2.setStroke(oldStroke);
+        } else {
+            g2.fill(at.createTransformedShape(fShape));
+        }
+
+    }
+
+    @Override
+    public float getAdvance() {
+        return Math.max(0, fShapeWidth + fOriginX);
+    }
+
+    @Override
+    public float getAscent() {
+        return Math.max(0, -fOriginY);
+    }
+
+    @Override
+    public Rectangle2D getBounds() {
+        return (Rectangle2D)fBounds.clone();
+    }
+
+    @Override
+    public float getDescent() {
+        return Math.max(0, fShapeHeight + fOriginY);
+    }
+
+}
+
diff --git a/awt/java/awt/font/TextHitInfo.java b/awt/java/awt/font/TextHitInfo.java
new file mode 100644
index 0000000..17bbf71
--- /dev/null
+++ b/awt/java/awt/font/TextHitInfo.java
@@ -0,0 +1,216 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The TextHitInfo class provides information about a caret position 
+ * in a text model for insertion or deletion of a character in a text.
+ * The TextHitInfo defines two biases of the character: leading or trailing.
+ * Leading position means the left edge of the specified character 
+ * (TextHitInfo.leading(2) method for "text" returns the left side of "x").
+ * Trailing position means the right edge of the specified character
+ * (TextHitInfo.trailing(2) method for "text" returns the right side of "x").
+ */
+public final class TextHitInfo {
+    
+    /** The char idx. */
+    private int charIdx; // Represents character index in the line
+    
+    /** The is trailing. */
+    private boolean isTrailing;
+
+    /**
+     * Instantiates a new text hit info.
+     * 
+     * @param idx the idx
+     * @param isTrailing the is trailing
+     */
+    private TextHitInfo(int idx, boolean isTrailing) {
+        charIdx = idx;
+        this.isTrailing = isTrailing;
+    }
+
+    /**
+     * To string.
+     * 
+     * @return the string
+     */
+    @Override
+    public String toString() {
+        return new String(
+                "TextHitInfo[" + charIdx + ", " + //$NON-NLS-1$ //$NON-NLS-2$
+                (isTrailing?"Trailing":"Leading") + "]" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        );
+    }
+
+    /**
+     * Compares this TextHitInfo object with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified object is a TextHitInfo object 
+     * with the same data values as this TextHitInfo, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof TextHitInfo) {
+            return equals((TextHitInfo) obj);
+        }
+        return false;
+    }
+
+    /**
+     * Compares this TextHitInfo object with the specified TextHitInfo
+     * object.
+     * 
+     * @param thi the TextHitInfo object to be compared.
+     * 
+     * @return true, if this TextHitInfo object has the same data values as the
+     * specified TextHitInfo object, false otherwise.
+     */
+    public boolean equals(TextHitInfo thi) {
+        return
+                thi != null &&
+                thi.charIdx == charIdx &&
+                thi.isTrailing == isTrailing;
+    }
+
+    /**
+     * Gets a TextHitInfo object with its character index 
+     * at the specified offset from the character index of 
+     * this TextHitInfo.
+     * 
+     * @param offset the offset.
+     * 
+     * @return the TextHitInfo. 
+     */
+    public TextHitInfo getOffsetHit(int offset) {
+        return new TextHitInfo(charIdx + offset, isTrailing);
+    }
+
+    /**
+     * Gets a TextHitInfo associated with the other side of 
+     * the insertion point. 
+     *  
+     * @return the other hit.
+     */
+    public TextHitInfo getOtherHit() {
+        return isTrailing ?
+                new TextHitInfo(charIdx+1, false) :
+                new TextHitInfo(charIdx-1, true);
+    }
+
+    /**
+     * Returns true if the leading edge of the character is hit,
+     * false if the trailing edge of the character is hit.
+     * 
+     * @return true if the leading edge of the character is hit,
+     * false if the trailing edge of the character is hit.
+     */
+    public boolean isLeadingEdge() {
+        return !isTrailing;
+    }
+
+    /**
+     * Hash code.
+     * 
+     * @return the int
+     */
+    @Override
+    public int hashCode() {
+        return HashCode.combine(charIdx, isTrailing);
+    }
+
+    /**
+     * Gets the insertion index.
+     * 
+     * @return the insertion index: character index if the leading edge
+     * is hit, or character index + 1 if the trailing edge is hit.   
+     */
+    public int getInsertionIndex() {
+        return isTrailing ? charIdx+1 : charIdx;
+    }
+
+    /**
+     * Gets the index of the character hit.
+     * 
+     * @return the character hit's index.
+     */
+    public int getCharIndex() {
+        return charIdx;
+    }
+
+    /**
+     * Returns a TextHitInfo associated with the trailing edge of 
+     * the character at the specified char index.
+     * 
+     * @param charIndex the char index.
+     * 
+     * @return the TextHitInfo associated with the trailing edge of 
+     * the character at the specified char index.
+     */
+    public static TextHitInfo trailing(int charIndex) {
+        return new TextHitInfo(charIndex, true);
+    }
+
+    /**
+     * Returns a TextHitInfo object associated with the leading edge 
+     * of the character at the specified char index.
+     * 
+     * @param charIndex the char index.
+     * 
+     * @return the TextHitInfo object associated with the leading edge 
+     * of the character at the specified char index.
+     */
+    public static TextHitInfo leading(int charIndex) {
+        return new TextHitInfo(charIndex, false);
+    }
+
+    /**
+     * Returns a (trailing) TextHitInfo object associated with the character 
+     * before the specified offset.
+     * 
+     * @param offset the offset.
+     * 
+     * @return the TextHitInfo object associated with the character 
+     * before the specified offset.
+     */
+    public static TextHitInfo beforeOffset(int offset) {
+        return new TextHitInfo(offset-1, true);
+    }
+
+    /**
+     * Returns a (leading) TextHitInfo object associated with the character 
+     * after the specified offset.
+     * 
+     * @param offset the offset.
+     * 
+     * @return the TextHitInfo object associated with the character 
+     * after the specified offset.
+     */
+    public static TextHitInfo afterOffset(int offset) {
+        return new TextHitInfo(offset, false);
+    }
+}
diff --git a/awt/java/awt/font/TextLayout.java b/awt/java/awt/font/TextLayout.java
new file mode 100644
index 0000000..e80afd0
--- /dev/null
+++ b/awt/java/awt/font/TextLayout.java
@@ -0,0 +1,916 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.GeneralPath;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.util.Map;
+
+import org.apache.harmony.awt.gl.font.BasicMetrics;
+import org.apache.harmony.awt.gl.font.CaretManager;
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TextLayout class defines the graphical representation of character data.
+ * This class provides method for obtaining information about cursor 
+ * positioning and movement, split cursors for text with different directions, 
+ * logical and visual highlighting, multiple baselines, hits, justification, 
+ * ascent, descent, and advance, and rendering. A TextLayout object can be 
+ * rendered using Graphics context. 
+ */
+public final class TextLayout implements Cloneable {
+
+    /**
+     * The CaretPolicy class provides a policy for obtaining the 
+     * caret location. The single getStrongCaret method specifies 
+     * the policy.
+     */
+    public static class CaretPolicy {
+
+        /**
+         * Instantiates a new CaretPolicy.
+         */
+        public CaretPolicy() {
+            // Nothing to do
+        }
+
+        /**
+         * Returns whichever of the two specified TextHitInfo objects 
+         * has the stronger caret (higher character level) in the 
+         * specified TextLayout.
+         * 
+         * @param hit1 the first TextHitInfo of the specified TextLayout.
+         * @param hit2 the second TextHitInfo of the specified TextLayout.
+         * @param layout the TextLayout.
+         * 
+         * @return the TextHitInfo with the stronger caret.
+         */
+        public TextHitInfo getStrongCaret(TextHitInfo hit1, TextHitInfo hit2, TextLayout layout) {
+            // Stronger hit is the one with greater level.
+            // If the level is same, leading edge is stronger.
+
+            int level1 = layout.getCharacterLevel(hit1.getCharIndex());
+            int level2 = layout.getCharacterLevel(hit2.getCharIndex());
+
+            if (level1 == level2) {
+                return (hit2.isLeadingEdge() && (!hit1.isLeadingEdge())) ? hit2 : hit1;
+            }
+            return level1 > level2 ? hit1 : hit2;
+        }
+
+    }
+
+    /** 
+     * The Constant DEFAULT_CARET_POLICY indicates the default caret policy.
+     */
+    public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
+
+    /** The breaker. */
+    private TextRunBreaker breaker;
+    
+    /** The metrics valid. */
+    private boolean metricsValid = false;
+    
+    /** The tmc. */
+    private TextMetricsCalculator tmc;
+    
+    /** The metrics. */
+    private BasicMetrics metrics;
+    
+    /** The caret manager. */
+    private CaretManager caretManager;
+    
+    /** The justification width. */
+    float justificationWidth = -1;
+
+    /**
+     * Instantiates a new TextLayout object from the specified string
+     * and Font.
+     * 
+     * @param string the string to be displayed.
+     * @param font the font of the text.
+     * @param frc the FontRenderContext object for obtaining
+     * information about a graphics device.
+     */
+    public TextLayout(String string, Font font, FontRenderContext frc) {
+        if (string == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (font == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "font")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (string.length() == 0){
+            // awt.02='{0}' parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        AttributedString as = new AttributedString(string);
+        as.addAttribute(TextAttribute.FONT, font);
+        this.breaker = new TextRunBreaker(as.getIterator(), frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new TextLayout from the specified text and 
+     * a map of attributes.
+     * 
+     * @param string the string to be displayed.
+     * @param attributes the attributes to be used for obtaining the text 
+     * style.
+     * @param frc the FontRenderContext object for obtaining
+     * information about a graphics device.
+     */
+    public TextLayout(
+            String string,
+            Map<? extends java.text.AttributedCharacterIterator.Attribute, ?> attributes,
+            FontRenderContext frc ) {
+        if (string == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (attributes == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "attributes")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (string.length() == 0){
+            // awt.02='{0}' parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        
+        AttributedString as = new AttributedString(string);
+        as.addAttributes(attributes, 0, string.length());
+        this.breaker = new TextRunBreaker(as.getIterator(), frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new TextLayout from the AttributedCharacterIterator.
+     * 
+     * @param text the AttributedCharacterIterator.
+     * @param frc the FontRenderContext object for obtaining
+     * information about a graphics device.
+     */
+    public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) {
+        if (text == null){
+            // awt.03='{0}' iterator parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.03", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (text.getBeginIndex() == text.getEndIndex()){
+            // awt.04='{0}' iterator parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.04", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        this.breaker = new TextRunBreaker(text, frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new text layout.
+     * 
+     * @param breaker the breaker
+     */
+    TextLayout(TextRunBreaker breaker) {
+        this.breaker = breaker;
+        caretManager = new CaretManager(this.breaker);
+    }
+
+    /**
+     * Returns a hash code of this TextLayout object.
+     * 
+     * @return a hash code of this TextLayout object.
+     */
+    @Override
+    public int hashCode() {
+        return breaker.hashCode();
+    }
+
+    /**
+     * Returns a copy of this object.
+     * 
+     * @return a copy of this object.
+     */
+    @Override
+    protected Object clone() {
+        TextLayout res = new TextLayout((TextRunBreaker) breaker.clone());
+
+        if (justificationWidth >= 0) {
+            res.handleJustify(justificationWidth);
+        }
+
+        return res;
+    }
+
+    /**
+     * Compares this TextLayout object to the specified TextLayout object.
+     * 
+     * @param layout the TextLayout object to be compared.
+     * 
+     * @return true, if this TextLayout object is equal to 
+     * the specified TextLayout object, false otherwise.
+     */
+    public boolean equals(TextLayout layout) {
+        if (layout == null) {
+            return false;
+        }
+        return this.breaker.equals(layout.breaker);
+    }
+
+    /**
+     * Compares this TextLayout object to the specified Object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if this TextLayout object is equal to 
+     * the specified Object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof TextLayout ? equals((TextLayout) obj) : false;
+    }
+
+    /**
+     * Gets the string representation for this TextLayout.
+     * 
+     * @return the string representation for this TextLayout.
+     */
+    @Override
+    public String toString() { // what for?
+        return super.toString();
+    }
+
+    /**
+     * Draws this TextLayout at the specified location with the 
+     * specified Graphics2D context. 
+     * 
+     * @param g2d the Graphics2D object which renders this TextLayout.
+     * @param x the X coordinate of the TextLayout origin. 
+     * @param y the Y coordinate of the TextLayout origin.
+     */
+    public void draw(Graphics2D g2d, float x, float y) {
+        updateMetrics();
+        breaker.drawSegments(g2d, x ,y);
+    }
+
+    /**
+     * Update metrics.
+     */
+    private void updateMetrics() {
+        if (!metricsValid) {
+            breaker.createAllSegments();
+            tmc = new TextMetricsCalculator(breaker);
+            metrics = tmc.createMetrics();
+            metricsValid = true;
+        }
+    }
+
+    /**
+     * Gets the advance of this TextLayout object.
+     * 
+     * @return the advance of this TextLayout object.
+     */
+    public float getAdvance() {
+        updateMetrics();
+        return metrics.getAdvance();
+    }
+
+    /**
+     * Gets the ascent of this TextLayout object.
+     * 
+     * @return the ascent of this TextLayout object.
+     */
+    public float getAscent() {
+        updateMetrics();
+        return metrics.getAscent();
+    }
+
+    /**
+     * Gets the baseline of this TextLayout object.
+     * 
+     * @return the baseline of this TextLayout object.
+     */
+    public byte getBaseline() {
+        updateMetrics();
+        return (byte) metrics.getBaseLineIndex();
+    }
+
+    /**
+     * Gets the float array of offsets for the baselines which 
+     * are used in this TextLayout.
+     * 
+     * @return the float array of offsets for the baselines which 
+     * are used in this TextLayout.
+     */
+    public float[] getBaselineOffsets() {
+        updateMetrics();
+        return tmc.getBaselineOffsets();
+    }
+
+    /**
+     * Gets the black box bounds of the characters in the specified area. 
+     * The black box bounds is an Shape which contains all 
+     * bounding boxes of all the glyphs of the characters 
+     * between firstEndpoint and secondEndpoint parameters values.     
+     *  
+     * @param firstEndpoint the first point of the area.
+     * @param secondEndpoint the second point of the area.
+     * 
+     * @return the Shape which contains black box bounds.
+     */
+    public Shape getBlackBoxBounds(int firstEndpoint, int secondEndpoint) {
+        updateMetrics();
+        if (firstEndpoint < secondEndpoint) {
+            return breaker.getBlackBoxBounds(firstEndpoint, secondEndpoint);
+        }
+        return breaker.getBlackBoxBounds(secondEndpoint, firstEndpoint);
+    }
+
+    /**
+     * Gets the bounds of this TextLayout.
+     * 
+     * @return the bounds of this TextLayout.
+     */
+    public Rectangle2D getBounds() {
+        updateMetrics();
+        return breaker.getVisualBounds();
+    }
+
+    /**
+     * Gets information about the caret of the specified TextHitInfo.
+     * 
+     * @param hitInfo the TextHitInfo.
+     * 
+     * @return the information about the caret of the specified TextHitInfo.
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo) {
+        updateMetrics();
+        return caretManager.getCaretInfo(hitInfo);
+    }
+
+    /**
+     * Gets information about the caret of the specified TextHitInfo
+     * of a character in this TextLayout.
+     * 
+     * @param hitInfo the TextHitInfo of a character in this TextLayout.
+     * @param bounds the bounds to which the caret info is constructed.
+     * 
+     * @return the caret of the specified TextHitInfo.
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo, Rectangle2D bounds) {
+        updateMetrics();
+        return caretManager.getCaretInfo(hitInfo);
+    }
+
+    /**
+     * Gets a Shape which represents the caret of the specified TextHitInfo
+     * in the bounds of this TextLayout.
+     * 
+     * @param hitInfo the TextHitInfo.
+     * @param bounds the bounds to which the caret info is constructed.
+     * 
+     * @return the Shape which represents the caret.
+     */
+    public Shape getCaretShape(TextHitInfo hitInfo, Rectangle2D bounds) {
+        updateMetrics();
+        return caretManager.getCaretShape(hitInfo, this);
+    }
+
+    /**
+     * Gets a Shape which represents the caret of the specified TextHitInfo
+     * in the bounds of this TextLayout.
+     * 
+     * @param hitInfo the TextHitInfo.
+     * 
+     * @return the Shape which represents the caret.
+     */
+    public Shape getCaretShape(TextHitInfo hitInfo) {
+        updateMetrics();
+        return caretManager.getCaretShape(hitInfo, this);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets with
+     * default caret policy and null bounds: the first element 
+     * is the strong caret, the second is the weak caret or null. 
+     * 
+     * @param offset an offset in the TextLayout.
+     * 
+     * @return an array of two Shapes corresponded to the strong
+     * and weak carets.
+     */
+    public Shape[] getCaretShapes(int offset) {
+        return getCaretShapes(offset, null, TextLayout.DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets with
+     * the default caret policy: the first element is the strong 
+     * caret, the second is the weak caret or null.
+     * 
+     * @param offset an offset in the TextLayout.
+     * @param bounds the bounds to which to extend the carets.
+     * 
+     * @return an array of two Shapes corresponded to the strong
+     * and weak carets.
+     */
+    public Shape[] getCaretShapes(int offset, Rectangle2D bounds) {
+        return getCaretShapes(offset, bounds, TextLayout.DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets: the first
+     * element is the strong caret, the second is the weak caret 
+     * or null.
+     * 
+     * @param offset an offset in the TextLayout.
+     * @param bounds the bounds to which to extend the carets.
+     * @param policy the specified CaretPolicy.
+     * 
+     * @return an array of two Shapes corresponded to the strong
+     * and weak carets.
+     */
+    public Shape[] getCaretShapes(int offset, Rectangle2D bounds, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        updateMetrics();
+        return caretManager.getCaretShapes(offset, bounds, policy, this);
+    }
+
+    /**
+     * Gets the number of characters in this TextLayout.
+     * 
+     * @return the number of characters in this TextLayout.
+     */
+    public int getCharacterCount() {
+        return breaker.getCharCount();
+    }
+
+    /**
+     * Gets the level of the character with the specified index. 
+     *  
+     * @param index the specified index of the character.
+     * 
+     * @return the level of the character.
+     */
+    public byte getCharacterLevel(int index) {
+        if (index == -1 || index == getCharacterCount()) {
+            return (byte) breaker.getBaseLevel();
+        }
+        return breaker.getLevel(index);
+    }
+
+    /**
+     * Gets the descent of this TextLayout.
+     * 
+     * @return the descent of this TextLayout.
+     */
+    public float getDescent() {
+        updateMetrics();
+        return metrics.getDescent();
+    }
+
+    /**
+     * Gets the TextLayout wich is justified with the specified
+     * width related to this TextLayout.
+     * 
+     * @param justificationWidth the width which is used 
+     * for justification.
+     * 
+     * @return a TextLayout justified to the specified width.
+     * 
+     * @throws Error the error occures if this TextLayout has been
+     * already justified.
+     */
+    public TextLayout getJustifiedLayout(float justificationWidth) throws Error {
+        float justification = breaker.getJustification();
+
+        if (justification < 0) {
+            // awt.196=Justification impossible, layout already justified
+            throw new Error(Messages.getString("awt.196")); //$NON-NLS-1$
+        } else if (justification == 0) {
+            return this;
+        }
+
+        TextLayout justifiedLayout = new TextLayout((TextRunBreaker) breaker.clone());
+        justifiedLayout.handleJustify(justificationWidth);
+        return justifiedLayout;
+    }
+
+    /**
+     * Gets the leading of this TextLayout.
+     * 
+     * @return the leading of this TextLayout.
+     */
+    public float getLeading() {
+        updateMetrics();
+        return metrics.getLeading();
+    }
+
+    /**
+     * Gets a Shape representing the logical selection betweeen 
+     * the specified endpoints and extended to the natural 
+     * bounds of this TextLayout.
+     * 
+     * @param firstEndpoint the first selected endpoint within the area of characters
+     * @param secondEndpoint the second selected endpoint within the area of characters
+     * 
+     * @return a Shape represented the logical selection betweeen 
+     * the specified endpoints.
+     */
+    public Shape getLogicalHighlightShape(int firstEndpoint, int secondEndpoint) {
+        updateMetrics();
+        return getLogicalHighlightShape(firstEndpoint, secondEndpoint, breaker.getLogicalBounds());
+    }
+
+    /**
+     * Gets a Shape representing the logical selection betweeen 
+     * the specified endpoints and extended to the specified 
+     * bounds of this TextLayout.
+     * 
+     * @param firstEndpoint the first selected endpoint within the area of characters
+     * @param secondEndpoint the second selected endpoint within the area of characters
+     * @param bounds the specified bounds of this TextLayout.
+     * 
+     * @return a Shape represented the logical selection betweeen 
+     * the specified endpoints.
+     */
+    public Shape getLogicalHighlightShape(
+            int firstEndpoint,
+            int secondEndpoint,
+            Rectangle2D bounds
+    ) {
+        updateMetrics();
+
+        if (firstEndpoint > secondEndpoint) {
+            if (secondEndpoint < 0 || firstEndpoint > breaker.getCharCount()) {
+                // awt.197=Endpoints are out of range
+                throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+            }
+            return caretManager.getLogicalHighlightShape(
+                    secondEndpoint,
+                    firstEndpoint,
+                    bounds,
+                    this
+            );
+        }
+        if (firstEndpoint < 0 || secondEndpoint > breaker.getCharCount()) {
+            // awt.197=Endpoints are out of range
+            throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+        }
+        return caretManager.getLogicalHighlightShape(
+                firstEndpoint,
+                secondEndpoint,
+                bounds,
+                this
+        );
+    }
+
+    /**
+     * Gets the logical ranges of text which corresponds to a visual 
+     * selection.
+     * 
+     * @param hit1 the first endpoint of the visual range.
+     * @param hit2 the second endpoint of the visual range.
+     * 
+     * @return the logical ranges of text which corresponds to a visual 
+     * selection.
+     */
+    public int[] getLogicalRangesForVisualSelection(TextHitInfo hit1, TextHitInfo hit2) {
+        return caretManager.getLogicalRangesForVisualSelection(hit1, hit2);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified offset. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * 
+     * @return the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified hit, or null 
+     * if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(int offset) {
+        return getNextLeftHit(offset, DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified hit. 
+     * 
+     * @param hitInfo the initial hit.
+     * 
+     * @return the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified hit, or null 
+     * if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(TextHitInfo hitInfo) {
+        breaker.createAllSegments();
+        return caretManager.getNextLeftHit(hitInfo);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified offset, given the 
+     * specified caret policy. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * @param policy the policy to be used for obtaining the strong caret.
+     * 
+     * @return the TextHitInfo for the next caret to the left of the 
+     * specified offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(int offset, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        TextHitInfo hit = TextHitInfo.afterOffset(offset);
+        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+        TextHitInfo nextLeftHit = getNextLeftHit(strongHit);
+
+        if (nextLeftHit != null) {
+            return policy.getStrongCaret(getVisualOtherHit(nextLeftHit), nextLeftHit, this);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified hit. 
+     * 
+     * @param hitInfo the initial hit.
+     * 
+     * @return the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified hit, or null 
+     * if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(TextHitInfo hitInfo) {
+        breaker.createAllSegments();
+        return caretManager.getNextRightHit(hitInfo);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified offset. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * 
+     * @return the TextHitInfo for the next caret to the right of the 
+     * specified offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(int offset) {
+        return getNextRightHit(offset, DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified offset, given the 
+     * specified caret policy. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * @param policy the policy to be used for obtaining the strong caret.
+     * 
+     * @return the TextHitInfo for the next caret to the right of the 
+     * specified offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(int offset, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        TextHitInfo hit = TextHitInfo.afterOffset(offset);
+        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+        TextHitInfo nextRightHit = getNextRightHit(strongHit);
+
+        if (nextRightHit != null) {
+            return policy.getStrongCaret(getVisualOtherHit(nextRightHit), nextRightHit, this);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the outline of this TextLayout as a Shape.
+     * 
+     * @param xform the AffineTransform to be used to transform 
+     * the outline before returning it, or null if no transformation
+     * is desired.
+     * 
+     * @return the outline of this TextLayout as a Shape.
+     */
+    public Shape getOutline(AffineTransform xform) {
+        breaker.createAllSegments();
+
+        GeneralPath outline = breaker.getOutline();
+
+        if (outline != null && xform != null) {
+            outline.transform(xform);
+        }
+
+        return outline;
+    }
+
+    /**
+     * Gets the visible advance of this TextLayout which is defined as
+     * diffence between leading (advance) and trailing whitespace.
+     * 
+     * @return the visible advance of this TextLayout.
+     */
+    public float getVisibleAdvance() {
+        updateMetrics();
+
+        // Trailing whitespace _SHOULD_ be reordered (Unicode spec) to
+        // base direction, so it is also trailing
+        // in logical representation. We use this fact.
+        int lastNonWhitespace = breaker.getLastNonWhitespace();
+
+        if (lastNonWhitespace < 0) {
+            return 0;
+        } else if (lastNonWhitespace == getCharacterCount()-1) {
+            return getAdvance();
+        } else if (justificationWidth >= 0) { // Layout is justified
+            return justificationWidth;
+        } else {
+            breaker.pushSegments(
+                    breaker.getACI().getBeginIndex(),
+                    lastNonWhitespace + breaker.getACI().getBeginIndex() + 1
+            );
+
+            breaker.createAllSegments();
+
+            float visAdvance = tmc.createMetrics().getAdvance();
+
+            breaker.popSegments();
+            return visAdvance;
+        }
+    }
+
+    /**
+     * Gets a Shape which corresponds to the highlighted (selected) area
+     * based on two hit locations within the text and extends to the bounds.
+     * 
+     * @param hit1 the first text hit location.
+     * @param hit2 the second text hit location.
+     * @param bounds the rectangle that the highlighted area should be 
+     * extended or restricted to.
+     * 
+     * @return a Shape which corresponds to the highlighted (selected) area.
+     */
+    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2, Rectangle2D bounds) {
+        return caretManager.getVisualHighlightShape(hit1, hit2, bounds, this);
+    }
+
+    /**
+     * Gets a Shape which corresponds to the highlighted (selected) area
+     * based on two hit locations within the text.
+     * 
+     * @param hit1 the first text hit location.
+     * @param hit2 the second text hit location.
+     * 
+     * @return a Shape which corresponds to the highlighted (selected) area.
+     */
+    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2) {
+        breaker.createAllSegments();
+        return caretManager.getVisualHighlightShape(hit1, hit2, breaker.getLogicalBounds(), this);
+    }
+
+    /**
+     * Gets the TextHitInfo for a hit on the opposite side of the 
+     * specified hit's caret.
+     * 
+     * @param hitInfo the specified TextHitInfo.
+     * 
+     * @return the TextHitInfo for a hit on the opposite side of the 
+     * specified hit's caret.
+     */
+    public TextHitInfo getVisualOtherHit(TextHitInfo hitInfo) {
+        return caretManager.getVisualOtherHit(hitInfo);
+    }
+
+    /**
+     * Justifies the text; this method should be overridden
+     * by subclasses.
+     * 
+     * @param justificationWidth the width for justification.
+     */
+    protected void handleJustify(float justificationWidth) {
+        float justification = breaker.getJustification();
+
+        if (justification < 0) {
+            // awt.196=Justification impossible, layout already justified
+            throw new IllegalStateException(Messages.getString("awt.196")); //$NON-NLS-1$
+        } else if (justification == 0) {
+            return;
+        }
+
+        float gap = (justificationWidth - getVisibleAdvance()) * justification;
+        breaker.justify(gap);
+        this.justificationWidth = justificationWidth;
+
+        // Correct metrics
+        tmc = new TextMetricsCalculator(breaker);
+        tmc.correctAdvance(metrics);
+    }
+
+    /**
+     * Returns a TextHitInfo object that gives information on which 
+     * division point (between two characters) is corresponds to a 
+     * hit (such as a mouse click) at the specified coordinates.
+     * 
+     * @param x the X coordinate in this TextLayout.
+     * @param y the Y coordinate in this TextLayout.
+     * 
+     * TextHitInfo object cooresponding to the given coordinates
+     * within the text.
+     */
+    public TextHitInfo hitTestChar(float x, float y) {
+        return hitTestChar(x, y, getBounds());
+    }
+
+    /**
+     * Returns a TextHitInfo object that gives information on which 
+     * division point (between two characters) is corresponds to a 
+     * hit (such as a mouse click) at the specified coordinates within 
+     * the specified text rectangle.
+     * 
+     * @param x the X coordinate in this TextLayout.
+     * @param y the Y coordinate in this TextLayout.
+     * @param bounds the bounds of the text area.
+     * 
+     * TextHitInfo object cooresponding to the given coordinates
+     * within the text.
+     */
+    public TextHitInfo hitTestChar(float x, float y, Rectangle2D bounds) {
+        if (x > bounds.getMaxX()) {
+            return breaker.isLTR() ?
+                    TextHitInfo.trailing(breaker.getCharCount() - 1) : TextHitInfo.leading(0);
+        }
+
+        if (x < bounds.getMinX()) {
+            return breaker.isLTR() ?
+                    TextHitInfo.leading(0) : TextHitInfo.trailing(breaker.getCharCount() - 1);
+        }
+
+        return breaker.hitTest(x, y);
+    }
+
+    /**
+     * Returns true if this TextLayout has a "left to right" 
+     * direction.
+     * 
+     * @return true if this TextLayout has a "left to right" 
+     * direction, false if this TextLayout has a "right to left" 
+     * direction. 
+     */
+    public boolean isLeftToRight() {
+        return breaker.isLTR();
+    }
+
+    /**
+     * Returns true if this TextLayout is vertical, false otherwise.
+     * 
+     * @return true if this TextLayout is vertical, false if horizontal.
+     */
+    public boolean isVertical() {
+        return false;
+    }
+}
+
diff --git a/awt/java/awt/font/TextMeasurer.java b/awt/java/awt/font/TextMeasurer.java
new file mode 100644
index 0000000..017f3d9
--- /dev/null
+++ b/awt/java/awt/font/TextMeasurer.java
@@ -0,0 +1,167 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+
+import java.text.AttributedCharacterIterator;
+
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+
+/**
+ * The TextMeasurer class provides utilities for line break operations.
+ */
+public final class TextMeasurer implements Cloneable {
+    
+    /** The aci. */
+    AttributedCharacterIterator aci;
+    
+    /** The frc. */
+    FontRenderContext frc;
+    
+    /** The breaker. */
+    TextRunBreaker breaker = null;
+    
+    /** The tmc. */
+    TextMetricsCalculator tmc = null;
+
+    /**
+     * Instantiates a new text measurer from the specified text.
+     * 
+     * @param text the source text.
+     * @param frc the FontRenderContext.
+     */
+    public TextMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+        this.aci = text;
+        this.frc = frc;
+        breaker = new TextRunBreaker(aci, this.frc);
+        tmc = new TextMetricsCalculator(breaker);
+    }
+
+    /**
+     * Replaces the current text with the new text, inserting a break
+     * character at the specified insert position.  
+     * 
+     * @param newParagraph the new paragraph text. 
+     * @param insertPos the position in the text where the character is inserted. 
+     */
+    public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
+        AttributedCharacterIterator oldAci = aci;
+        aci = newParagraph;
+        if ((oldAci.getEndIndex() - oldAci.getBeginIndex()) -
+           (aci.getEndIndex() - aci.getBeginIndex()) != -1) {
+            breaker = new TextRunBreaker(aci, this.frc);
+            tmc = new TextMetricsCalculator(breaker);
+        } else {
+            breaker.insertChar(newParagraph, insertPos);
+        }
+    }
+
+    /**
+     * Replaces the current text with the new text and deletes a
+     * character at the specified position.  
+     * 
+     * @param newParagraph the paragraph text after deletion. 
+     * @param deletePos the position in the text where the character is removed. 
+     */
+    public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
+        AttributedCharacterIterator oldAci = aci;
+        aci = newParagraph;
+        if ((oldAci.getEndIndex() - oldAci.getBeginIndex()) -
+           (aci.getEndIndex() - aci.getBeginIndex()) != 1) {
+            breaker = new TextRunBreaker(aci, this.frc);
+            tmc = new TextMetricsCalculator(breaker);
+        } else {
+            breaker.deleteChar(newParagraph, deletePos);
+        }
+    }
+
+    /**
+     * Returns a copy of this object.
+     * 
+     * @return a copy of this object.
+     */
+    @Override
+    protected Object clone() {
+        return new TextMeasurer((AttributedCharacterIterator) aci.clone(), frc);
+    }
+
+    /**
+     * Returns a TextLayout of the specified character range.
+     * 
+     * @param start the index of the first character.
+     * @param limit the index after the last character. 
+     * 
+     * @return a TextLayout for the characters beginning at "start" up 
+     * to "end".
+     */
+    public TextLayout getLayout(int start, int limit) {
+        breaker.pushSegments(start - aci.getBeginIndex(), limit - aci.getBeginIndex());
+
+        breaker.createAllSegments();
+        TextLayout layout = new TextLayout((TextRunBreaker) breaker.clone());
+
+        breaker.popSegments();
+        return layout;
+    }
+
+    /**
+     * Returns the graphical width of a line beginning at "start" 
+     * parameter and including characters up to "end" parameter. 
+     * "start" and "end" are absolute indices, not relative to the 
+     * "start" of the paragraph.
+     * 
+     * @param start the character index at which to start measuring.
+     * @param end the character index at which to stop measuring.
+     * 
+     * @return the graphical width of a line beginning at "start"  
+     * and including characters up to "end".
+     */
+    public float getAdvanceBetween(int start, int end) {
+        breaker.pushSegments(start - aci.getBeginIndex(), end - aci.getBeginIndex());
+
+        breaker.createAllSegments();
+        float retval = tmc.createMetrics().getAdvance();
+
+        breaker.popSegments();
+        return retval;
+    }
+
+    /**
+     * Returns the index of the first character which is not fit on 
+     * a line beginning at start and possible measuring up to maxAdvance 
+     * in graphical width.
+     * 
+     * @param start he character index at which to start measuring. 
+     * @param maxAdvance the graphical width in which the line must fit. 
+     * 
+     * @return the index after the last character that is fit on a line 
+     * beginning at start, which is not longer than maxAdvance in graphical
+     * width.
+     */
+    public int getLineBreakIndex(int start, float maxAdvance) {
+        breaker.createAllSegments();
+        return breaker.getLineBreakIndex(
+                start - aci.getBeginIndex(), maxAdvance) + aci.getBeginIndex();
+    }
+}
+
diff --git a/awt/java/awt/font/TransformAttribute.java b/awt/java/awt/font/TransformAttribute.java
new file mode 100644
index 0000000..7c9b0bd
--- /dev/null
+++ b/awt/java/awt/font/TransformAttribute.java
@@ -0,0 +1,80 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+import java.io.Serializable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TransformAttribute class is a wrapper for the AffineTransform class in
+ * order to use it as attribute.
+ */
+public final class TransformAttribute implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 3356247357827709530L;
+
+    // affine transform of this TransformAttribute instance
+    /** The transform. */
+    private AffineTransform fTransform;
+
+    /**
+     * Instantiates a new TransformAttribute from the specified
+     * AffineTransform.
+     * 
+     * @param transform the AffineTransform to be wrapped.
+     */
+    public TransformAttribute(AffineTransform transform) {
+        if (transform == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+        if (!transform.isIdentity()){
+            this.fTransform = new AffineTransform(transform);
+        }
+    }
+
+    /**
+     * Gets the initial AffineTransform which is wrapped.
+     * 
+     * @return the initial AffineTransform which is wrapped.
+     */
+    public AffineTransform getTransform() {
+        if (fTransform != null){
+            return new AffineTransform(fTransform);
+        }
+        return new AffineTransform();
+    }
+
+    /**
+     * Checks if this transform is an identity transform.
+     * 
+     * @return true, if this transform is an identity transform,
+     * false otherwise.
+     */
+    public boolean isIdentity() {
+        return (fTransform == null);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/AffineTransform.java b/awt/java/awt/geom/AffineTransform.java
new file mode 100644
index 0000000..5fd3934
--- /dev/null
+++ b/awt/java/awt/geom/AffineTransform.java
@@ -0,0 +1,1158 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Shape;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class AffineTransform represents a linear transformation 
+ * (rotation, scaling, or shear) followed by a translation that 
+ * acts on a coordinate space. It preserves colinearity of points 
+ * and ratios of distances between collinear points: so if A, B, 
+ * and C are on a line, then after the space has been transformed 
+ * via the affine transform, the images of the three points will 
+ * still be on a line, and the ratio of the distance from A to B
+ * with the distance from B to C will be the same as the corresponding
+ * ratio in the image space.
+ */
+public class AffineTransform implements Cloneable, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 1330973210523860834L;
+
+    /** The Constant TYPE_IDENTITY. */
+    public static final int TYPE_IDENTITY = 0;
+    
+    /** The Constant TYPE_TRANSLATION. */
+    public static final int TYPE_TRANSLATION = 1;
+    
+    /** The Constant TYPE_UNIFORM_SCALE. */
+    public static final int TYPE_UNIFORM_SCALE = 2;
+    
+    /** The Constant TYPE_GENERAL_SCALE. */
+    public static final int TYPE_GENERAL_SCALE = 4;
+    
+    /** The Constant TYPE_QUADRANT_ROTATION. */
+    public static final int TYPE_QUADRANT_ROTATION = 8;
+    
+    /** The Constant TYPE_GENERAL_ROTATION. */
+    public static final int TYPE_GENERAL_ROTATION = 16;
+    
+    /** The Constant TYPE_GENERAL_TRANSFORM. */
+    public static final int TYPE_GENERAL_TRANSFORM = 32;
+    
+    /** The Constant TYPE_FLIP. */
+    public static final int TYPE_FLIP = 64;
+    
+    /** The Constant TYPE_MASK_SCALE. */
+    public static final int TYPE_MASK_SCALE = TYPE_UNIFORM_SCALE | TYPE_GENERAL_SCALE;
+    
+    /** The Constant TYPE_MASK_ROTATION. */
+    public static final int TYPE_MASK_ROTATION = TYPE_QUADRANT_ROTATION | TYPE_GENERAL_ROTATION;
+
+    /** The <code>TYPE_UNKNOWN</code> is an initial type value. */
+    static final int TYPE_UNKNOWN = -1;
+    
+    /** The min value equivalent to zero. If absolute value less then ZERO it considered as zero. */
+    static final double ZERO = 1E-10;
+   
+    /** The values of transformation matrix. */
+    double m00;
+    
+    /** The m10. */
+    double m10;
+    
+    /** The m01. */
+    double m01;
+    
+    /** The m11. */
+    double m11;
+    
+    /** The m02. */
+    double m02;
+    
+    /** The m12. */
+    double m12;
+
+    /** The transformation <code>type</code>. */
+    transient int type;
+
+    /**
+     * Instantiates a new affine transform of type <code>TYPE_IDENTITY</code>
+     * (which leaves coordinates unchanged).
+     */
+    public AffineTransform() {
+        type = TYPE_IDENTITY;
+        m00 = m11 = 1.0;
+        m10 = m01 = m02 = m12 = 0.0;
+    }
+
+    /**
+     * Instantiates a new affine transform that has the same data as
+     * the given AffineTransform.
+     * 
+     * @param t the transform to copy.
+     */
+    public AffineTransform(AffineTransform t) {
+        this.type = t.type;
+        this.m00 = t.m00;
+        this.m10 = t.m10;
+        this.m01 = t.m01;
+        this.m11 = t.m11;
+        this.m02 = t.m02;
+        this.m12 = t.m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by specifying the values of the 2x3
+     * transformation matrix as floats. The type is set to the default
+     * type: <code>TYPE_UNKNOWN</code>
+     * 
+     * @param m00 the m00 entry in the transformation matrix.
+     * @param m10 the m10 entry in the transformation matrix.
+     * @param m01 the m01 entry in the transformation matrix.
+     * @param m11 the m11 entry in the transformation matrix.
+     * @param m02 the m02 entry in the transformation matrix.
+     * @param m12 the m12 entry in the transformation matrix.
+     */
+    public AffineTransform(float m00, float m10, float m01, float m11, float m02, float m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by specifying the values of the 2x3
+     * transformation matrix as doubles. The type is set to the default
+     * type: <code>TYPE_UNKNOWN</code>
+     * 
+     * @param m00 the m00 entry in the transformation matrix.
+     * @param m10 the m10 entry in the transformation matrix.
+     * @param m01 the m01 entry in the transformation matrix.
+     * @param m11 the m11 entry in the transformation matrix.
+     * @param m02 the m02 entry in the transformation matrix.
+     * @param m12 the m12 entry in the transformation matrix.
+     */
+    public AffineTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by reading the values of the 
+     * transformation matrix from an array of floats. The mapping from the
+     * array to the matrix starts with <code>matrix[0]</code> giving the 
+     * top-left entry of the matrix and 
+     * proceeds with the usual left-to-right and top-down ordering.
+     * <p>
+     * If the array has only four entries, then the two entries of the 
+     * last row of the transformation matrix default to zero.
+     * 
+     * @param matrix the array of four or six floats giving the values 
+     * of the matrix.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if the size of the array
+     * is 0, 1, 2, 3, or 5.
+     */
+    public AffineTransform(float[] matrix) {
+        this.type = TYPE_UNKNOWN;
+        m00 = matrix[0];
+        m10 = matrix[1];
+        m01 = matrix[2];
+        m11 = matrix[3];
+        if (matrix.length > 4) {
+            m02 = matrix[4];
+            m12 = matrix[5];
+        }
+    }
+
+    /**
+     * Instantiates a new affine transform by reading the values of the 
+     * transformation matrix from an array of doubles. The mapping from the
+     * array to the matrix starts with <code>matrix[0]</code> giving the 
+     * top-left entry of the matrix and 
+     * proceeds with the usual left-to-right and top-down ordering.
+     * <p>
+     * If the array has only four entries, then the two entries of the 
+     * last row of the transformation matrix default to zero.
+     * 
+     * @param matrix the array of four or six doubles giving the values 
+     * of the matrix.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if the size of the array
+     * is 0, 1, 2, 3, or 5.
+     */
+    public AffineTransform(double[] matrix) {
+        this.type = TYPE_UNKNOWN;
+        m00 = matrix[0];
+        m10 = matrix[1];
+        m01 = matrix[2];
+        m11 = matrix[3];
+        if (matrix.length > 4) {
+            m02 = matrix[4];
+            m12 = matrix[5];
+        }
+    }
+
+
+    /**
+     * Returns type of the affine transformation.
+     * <p>
+     * The type is computed as follows: Label the entries of the 
+     * transformation matrix as three rows (m00, m01), (m10, m11), and
+     * (m02, m12). Then if the original basis vectors are (1, 0) and (0, 1), 
+     * the new basis vectors after transformation are given by (m00, m01) 
+     * and (m10, m11), and the translation vector is (m02, m12).
+     * <p>
+     * The types are classified as follows: <br/> 
+     *   TYPE_IDENTITY - no change<br/>
+     *   TYPE_TRANSLATION - The translation vector isn't zero<br/>
+     *   TYPE_UNIFORM_SCALE - The new basis vectors have equal length<br/>
+     *   TYPE_GENERAL_SCALE - The new basis vectors dont' have equal length<br/>
+     *   TYPE_FLIP - The new basis vector orientation differs from the original one<br/>
+     *   TYPE_QUADRANT_ROTATION - The new basis is a rotation of the original by 90, 180, 270, or 360 degrees<br/>   
+     *   TYPE_GENERAL_ROTATION - The new basis is a rotation of the original by an arbitrary angle<br/>
+     *   TYPE_GENERAL_TRANSFORM - The transformation can't be inverted.<br/>
+     *   <p>
+     * Note that multiple types are possible, thus the types can be combined 
+     * using bitwise combinations.
+     * 
+     * @return the type of the Affine Transform.
+     */
+    public int getType() {
+        if (type != TYPE_UNKNOWN) {
+            return type;
+        }
+
+        int type = 0;
+
+        if (m00 * m01 + m10 * m11 != 0.0) {
+            type |= TYPE_GENERAL_TRANSFORM;
+            return type;
+        }
+
+        if (m02 != 0.0 || m12 != 0.0) {
+            type |= TYPE_TRANSLATION;
+        } else
+            if (m00 == 1.0 && m11 == 1.0 && m01 == 0.0 && m10 == 0.0) {
+                type = TYPE_IDENTITY;
+                return type;
+            }
+
+        if (m00 * m11 - m01 * m10 < 0.0) {
+            type |= TYPE_FLIP;
+        }
+
+        double dx = m00 * m00 + m10 * m10;
+        double dy = m01 * m01 + m11 * m11;
+        if (dx != dy) {
+            type |= TYPE_GENERAL_SCALE;
+        } else
+            if (dx != 1.0) {
+                type |= TYPE_UNIFORM_SCALE;
+            }
+
+        if ((m00 == 0.0 && m11 == 0.0) ||
+            (m10 == 0.0 && m01 == 0.0 && (m00 < 0.0 || m11 < 0.0)))
+        {
+            type |= TYPE_QUADRANT_ROTATION;
+        } else
+            if (m01 != 0.0 || m10 != 0.0) {
+                type |= TYPE_GENERAL_ROTATION;
+            }
+
+        return type;
+    }
+
+    /**
+     * Gets the scale x entry of the transformation matrix
+     * (the upper left matrix entry).
+     * 
+     * @return the scale x value.
+     */
+    public double getScaleX() {
+        return m00;
+    }
+
+    /**
+     * Gets the scale y entry of the transformation matrix
+     * (the lower right entry of the linear transformation).
+     * 
+     * @return the scale y value.
+     */
+    public double getScaleY() {
+        return m11;
+    }
+
+    /**
+     * Gets the shear x entry of the transformation matrix
+     * (the upper right entry of the linear transformation).
+     * 
+     * @return the shear x value.
+     */
+    public double getShearX() {
+        return m01;
+    }
+
+    /**
+     * Gets the shear y entry of the transformation matrix
+     * (the lower left entry of the linear transformation).
+     * 
+     * @return the shear y value.
+     */
+    public double getShearY() {
+        return m10;
+    }
+
+    /**
+     * Gets the x coordinate of the translation vector.
+     * 
+     * @return the x coordinate of the translation vector.
+     */
+    public double getTranslateX() {
+        return m02;
+    }
+
+    /**
+     * Gets the y coordinate of the translation vector.
+     * 
+     * @return the y coordinate of the translation vector.
+     */
+    public double getTranslateY() {
+        return m12;
+    }
+
+    /**
+     * Checks if the AffineTransformation is the identity.
+     * 
+     * @return true, if the AffineTransformation is the identity.
+     */
+    public boolean isIdentity() {
+        return getType() == TYPE_IDENTITY;
+    }
+
+    /**
+     * Writes the values of the transformation matrix into the given 
+     * array of doubles. If the array has length 4, only the linear
+     * transformation part will be written into it. If it has length 
+     * greater than 4, the translation vector will be included as well.
+     * 
+     * @param matrix the array to fill with the values of the matrix.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if the size of the array
+     * is 0, 1, 2, 3, or 5.
+     */
+    public void getMatrix(double[] matrix) {
+        matrix[0] = m00;
+        matrix[1] = m10;
+        matrix[2] = m01;
+        matrix[3] = m11;
+        if (matrix.length > 4) {
+            matrix[4] = m02;
+            matrix[5] = m12;
+        }
+    }
+
+    /**
+     * Gets the determinant of the linear transformation matrix.
+     * 
+     * @return the determinant of the linear transformation matrix.
+     */
+    public double getDeterminant() {
+        return m00 * m11 - m01 * m10;
+    }
+
+    /**
+     * Sets the transform in terms of a list of double values.
+     * 
+     * @param m00 the m00 coordinate of the transformation matrix.
+     * @param m10 the m10 coordinate of the transformation matrix.
+     * @param m01 the m01 coordinate of the transformation matrix.
+     * @param m11 the m11 coordinate of the transformation matrix.
+     * @param m02 the m02 coordinate of the transformation matrix.
+     * @param m12 the m12 coordinate of the transformation matrix.
+     */
+    public void setTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Sets the transform's data to match the data of the transform 
+     * sent as a parameter.
+     * 
+     * @param t the transform that gives the new values.
+     */
+    public void setTransform(AffineTransform t) {
+        type = t.type;
+        setTransform(t.m00, t.m10, t.m01, t.m11, t.m02, t.m12);
+    }
+
+    /**
+     * Sets the transform to the identity transform.
+     */
+    public void setToIdentity() {
+        type = TYPE_IDENTITY;
+        m00 = m11 = 1.0;
+        m10 = m01 = m02 = m12 = 0.0;
+    }
+
+    /**
+     * Sets the transformation to a translation alone.
+     * Sets the linear part of the transformation to identity 
+     * and the translation vector to the values sent as parameters.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_TRANSLATION</code>.
+     * 
+     * @param mx the distance to translate in the x direction.
+     * @param my the distance to translate in the y direction.
+     */
+    public void setToTranslation(double mx, double my) {
+        m00 = m11 = 1.0;
+        m01 = m10 = 0.0;
+        m02 = mx;
+        m12 = my;
+        if (mx == 0.0 && my == 0.0) {
+            type = TYPE_IDENTITY;
+        } else {
+            type = TYPE_TRANSLATION;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a scale alone, eliminating 
+     * rotation, shear, and translation elements.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param scx the scaling factor in the x direction.
+     * @param scy the scaling factor in the y direction.
+     */
+    public void setToScale(double scx, double scy) {
+        m00 = scx;
+        m11 = scy;
+        m10 = m01 = m02 = m12 = 0.0;
+        if (scx != 1.0 || scy != 1.0) {
+            type = TYPE_UNKNOWN;
+        } else {
+            type = TYPE_IDENTITY;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a shear alone, eliminating 
+     * rotation, scaling, and translation elements.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param shx the shearing factor in the x direction.
+     * @param shy the shearing factor in the y direction.
+     */
+    public void setToShear(double shx, double shy) {
+        m00 = m11 = 1.0;
+        m02 = m12 = 0.0;
+        m01 = shx;
+        m10 = shy;
+        if (shx != 0.0 || shy != 0.0) {
+            type = TYPE_UNKNOWN;
+        } else {
+            type = TYPE_IDENTITY;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a rotation alone, eliminating 
+     * shearing, scaling, and translation elements.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     */
+    public void setToRotation(double angle) {
+        double sin = Math.sin(angle);
+        double cos = Math.cos(angle);
+        if (Math.abs(cos) < ZERO) {
+            cos = 0.0;
+            sin = sin > 0.0 ? 1.0 : -1.0;
+        } else
+            if (Math.abs(sin) < ZERO) {
+                sin = 0.0;
+                cos = cos > 0.0 ? 1.0 : -1.0;
+            }
+        m00 = m11 = cos;
+        m01 = -sin;
+        m10 = sin;
+        m02 = m12 = 0.0;
+        type = TYPE_UNKNOWN;
+    }
+
+    /**
+     * Sets the transformation to being a rotation followed by a 
+     * translation. 
+     * Sets the type to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     * @param px the distance to translate in the x direction.
+     * @param py the distance to translate in the y direction.
+     */
+    public void setToRotation(double angle, double px, double py) {
+        setToRotation(angle);
+        m02 = px * (1.0 - m00) + py * m10;
+        m12 = py * (1.0 - m00) - px * m10;
+        type = TYPE_UNKNOWN;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a translation alone
+     * with the translation vector given by the values sent as parameters.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_TRANSLATION</code>.
+     * 
+     * @param mx the distance to translate in the x direction.
+     * @param my the distance to translate in the y direction.
+
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getTranslateInstance(double mx, double my) {
+        AffineTransform t = new AffineTransform();
+        t.setToTranslation(mx, my);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a scale alone.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param scx the scaling factor in the x direction.
+     * @param scY the scaling factor in the y direction.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getScaleInstance(double scx, double scY) {
+        AffineTransform t = new AffineTransform();
+        t.setToScale(scx, scY);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a shear alone.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param shx the shearing factor in the x direction.
+     * @param shy the shearing factor in the y direction.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getShearInstance(double shx, double shy) {
+        AffineTransform m = new AffineTransform();
+        m.setToShear(shx, shy);
+        return m;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a rotation alone.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getRotateInstance(double angle) {
+        AffineTransform t = new AffineTransform();
+        t.setToRotation(angle);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a rotation followed by a 
+     * translation. 
+     * Sets the type to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     * @param x the distance to translate in the x direction.
+     * @param y the distance to translate in the y direction.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getRotateInstance(double angle, double x, double y) {
+        AffineTransform t = new AffineTransform();
+        t.setToRotation(angle, x, y);
+        return t;
+    }
+
+    /**
+     * Applies a translation to this AffineTransformation.
+     * 
+     * @param mx the distance to translate in the x direction.
+     * @param my the distance to translate in the y direction.
+     */
+    public void translate(double mx, double my) {
+        concatenate(AffineTransform.getTranslateInstance(mx, my));
+    }
+
+    /**
+     * Applies a scaling transformation to this AffineTransformation.
+     * 
+     * @param scx the scaling factor in the x direction.
+     * @param scy the scaling factor in the y direction.
+     */
+    public void scale(double scx, double scy) {
+        concatenate(AffineTransform.getScaleInstance(scx, scy));
+    }
+
+    /**
+     * Applies a shearing transformation to this AffineTransformation.
+     * 
+     * @param shx the shearing factor in the x direction.
+     * @param shy the shearing factor in the y direction.
+     */
+    public void shear(double shx, double shy) {
+        concatenate(AffineTransform.getShearInstance(shx, shy));
+    }
+
+    /**
+     * Applies a rotation transformation to this AffineTransformation.
+     * 
+     * @param angle the angle of rotation in radians.
+     */
+    public void rotate(double angle) {
+        concatenate(AffineTransform.getRotateInstance(angle));
+    }
+
+    /**
+     * Applies a rotation and translation transformation to this 
+     * AffineTransformation.
+     * 
+     * @param angle the angle of rotation in radians.
+     * @param px the distance to translate in the x direction.
+     * @param py the distance to translate in the y direction.
+     */
+    public void rotate(double angle, double px, double py) {
+        concatenate(AffineTransform.getRotateInstance(angle, px, py));
+    }
+
+    /**
+     * Multiplies the matrix representations of two AffineTransform objects.
+     * 
+     * @param t1 - the AffineTransform object is a multiplicand
+     * @param t2 - the AffineTransform object is a multiplier
+     * 
+     * @return an AffineTransform object that is the result of t1 multiplied by the matrix t2.
+     */
+    AffineTransform multiply(AffineTransform t1, AffineTransform t2) {
+        return new AffineTransform(
+                t1.m00 * t2.m00 + t1.m10 * t2.m01,          // m00
+                t1.m00 * t2.m10 + t1.m10 * t2.m11,          // m01
+                t1.m01 * t2.m00 + t1.m11 * t2.m01,          // m10
+                t1.m01 * t2.m10 + t1.m11 * t2.m11,          // m11
+                t1.m02 * t2.m00 + t1.m12 * t2.m01 + t2.m02, // m02
+                t1.m02 * t2.m10 + t1.m12 * t2.m11 + t2.m12);// m12
+    }
+
+    /**
+     * Applies the given AffineTransform to this AffineTransform
+     * via matrix multiplication.
+     * 
+     * @param t the AffineTransform to apply to this AffineTransform.
+     */
+    public void concatenate(AffineTransform t) {
+        setTransform(multiply(t, this));
+    }
+
+    /**
+     * Changes the current AffineTransform the one obtained by 
+     * taking the transform t and applying this AffineTransform to it.
+     * 
+     * @param t the AffineTransform that this AffineTransform is multiplied by.
+     */
+    public void preConcatenate(AffineTransform t) {
+        setTransform(multiply(this, t));
+    }
+
+    /**
+     * Creates an AffineTransform that is the inverse of this transform.
+     * 
+     * @return the affine transform that is the inverse of this AffineTransform.
+     * 
+     * @throws NoninvertibleTransformException if this AffineTransform cannot be 
+     * inverted (the determinant of the linear transformation part is zero).
+     */
+    public AffineTransform createInverse() throws NoninvertibleTransformException {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+        return new AffineTransform(
+                 m11 / det, // m00
+                -m10 / det, // m10
+                -m01 / det, // m01
+                 m00 / det, // m11
+                (m01 * m12 - m11 * m02) / det, // m02
+                (m10 * m02 - m00 * m12) / det  // m12
+        );
+    }
+
+    /**
+     * Apply the current AffineTransform to the point.
+     * 
+     * @param src the original point.
+     * @param dst Point2D object to be filled with the destination
+     * coordinates (where the original point is sent by this AffineTransform). May be null.
+     * 
+     * @return the point in the AffineTransform's image space where the
+     * original point is sent.
+     */
+    public Point2D transform(Point2D src, Point2D dst) {
+        if (dst == null) {
+            if (src instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX();
+        double y = src.getY();
+
+        dst.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
+        return dst;
+    }
+
+    /**
+     * Applies this AffineTransform to an array of points.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length > src.length</code> or
+     * <code>dstOff + length > dst.length</code>.
+     */
+    public void transform(Point2D[] src, int srcOff, Point2D[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            Point2D srcPoint = src[srcOff++]; 
+            double x = srcPoint.getX();
+            double y = srcPoint.getY();
+            Point2D dstPoint = dst[dstOff]; 
+            if (dstPoint == null) {
+                if (srcPoint instanceof Point2D.Double) {
+                    dstPoint = new Point2D.Double();
+                } else {
+                    dstPoint = new Point2D.Float();
+                }
+            }
+            dstPoint.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
+            dst[dstOff++] = dstPoint;
+        }
+    }
+    
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+     public void transform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
+        int step = 2;
+        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
+            srcOff = srcOff + length * 2 - 2;
+            dstOff = dstOff + length * 2 - 2;
+            step = -2;
+        }
+        while (--length >= 0) {
+            double x = src[srcOff + 0];
+            double y = src[srcOff + 1];
+            dst[dstOff + 0] = x * m00 + y * m01 + m02;
+            dst[dstOff + 1] = x * m10 + y * m11 + m12;
+            srcOff += step;
+            dstOff += step;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of float values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(float[] src, int srcOff, float[] dst, int dstOff, int length) {
+        int step = 2;
+        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
+            srcOff = srcOff + length * 2 - 2;
+            dstOff = dstOff + length * 2 - 2;
+            step = -2;
+        }
+        while (--length >= 0) {
+            float x = src[srcOff + 0];
+            float y = src[srcOff + 1];
+            dst[dstOff + 0] = (float)(x * m00 + y * m01 + m02);
+            dst[dstOff + 1] = (float)(x * m10 + y * m11 + m12);
+            srcOff += step;
+            dstOff += step;
+        }
+    }
+    
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of float values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * The destination coordinates are given as values of type <code>double</code>.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(float[] src, int srcOff, double[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            float x = src[srcOff++];
+            float y = src[srcOff++];
+            dst[dstOff++] = x * m00 + y * m01 + m02;
+            dst[dstOff++] = x * m10 + y * m11 + m12;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * The destination coordinates are given as values of type <code>float</code>.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(double[] src, int srcOff, float[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            double x = src[srcOff++];
+            double y = src[srcOff++];
+            dst[dstOff++] = (float)(x * m00 + y * m01 + m02);
+            dst[dstOff++] = (float)(x * m10 + y * m11 + m12);
+        }
+    }
+
+    /**
+     * Transforms the point according to the linear transformation
+     * part of this AffineTransformation (without applying the translation).
+     * 
+     * @param src the original point.
+     * @param dst the point object where the result of the delta transform
+     * is written.
+     * 
+     * @return the result of applying the delta transform (linear part 
+     * only) to the original point.
+     */
+    // TODO: is this right? if dst is null, we check what it's an
+    // instance of? Shouldn't it be src instanceof Point2D.Double?
+    public Point2D deltaTransform(Point2D src, Point2D dst) {
+        if (dst == null) {
+            if (dst instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX();
+        double y = src.getY();
+
+        dst.setLocation(x * m00 + y * m01, x * m10 + y * m11);
+        return dst;
+    }
+
+    /**
+     * Applies the linear transformation part of this AffineTransform 
+     * (ignoring the translation part) to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the delta transformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void deltaTransform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            double x = src[srcOff++];
+            double y = src[srcOff++];
+            dst[dstOff++] = x * m00 + y * m01;
+            dst[dstOff++] = x * m10 + y * m11;
+        }
+    }
+
+    /**
+     * Transforms the point according to the inverse of this AffineTransformation.
+     * 
+     * @param src the original point.
+     * @param dst the point object where the result of the inverse transform
+     * is written (may be null).
+     * 
+     * @return the result of applying the inverse transform.
+     * Inverse transform.
+     * 
+     * @throws NoninvertibleTransformException if this AffineTransform cannot be 
+     * inverted (the determinant of the linear transformation part is zero).
+     */
+    public Point2D inverseTransform(Point2D src, Point2D dst) throws NoninvertibleTransformException {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            if (src instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX() - m02;
+        double y = src.getY() - m12;
+
+        dst.setLocation((x * m11 - y * m01) / det, (y * m00 - x * m10) / det);
+        return dst;
+    }
+
+    /**
+     * Applies the inverse of this AffineTransform to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the inverse of the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     * @throws NoninvertibleTransformException if this AffineTransform cannot be 
+     * inverted (the determinant of the linear transformation part is zero).
+     */
+    public void inverseTransform(double[] src, int srcOff, double[] dst, int dstOff, int length)
+        throws NoninvertibleTransformException
+    {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+
+        while (--length >= 0) {
+            double x = src[srcOff++] - m02;
+            double y = src[srcOff++] - m12;
+            dst[dstOff++] = (x * m11 - y * m01) / det;
+            dst[dstOff++] = (y * m00 - x * m10) / det;
+        }
+    }
+
+    /**
+     * Creates a new shape whose data is given by applying this 
+     * AffineTransform to the specified shape.
+     * 
+     * @param src the original shape whose data is to be transformed.
+     * 
+     * @return the new shape found by applying this AffineTransform to 
+     * the original shape.
+     */
+    public Shape createTransformedShape(Shape src) {
+        if (src == null) {
+            return null;
+        }
+        if (src instanceof GeneralPath) {
+            return ((GeneralPath)src).createTransformedShape(this);
+        }
+        PathIterator path = src.getPathIterator(this);
+        GeneralPath dst = new GeneralPath(path.getWindingRule());
+        dst.append(path, false);
+        return dst;
+    }
+
+    @Override
+    public String toString() {
+        return
+            getClass().getName() +
+            "[[" + m00 + ", " + m01 + ", " + m02 + "], [" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                + m10 + ", " + m11 + ", " + m12 + "]]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(m00);
+        hash.append(m01);
+        hash.append(m02);
+        hash.append(m10);
+        hash.append(m11);
+        hash.append(m12);
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof AffineTransform) {
+            AffineTransform t = (AffineTransform)obj;
+            return
+                m00 == t.m00 && m01 == t.m01 &&
+                m02 == t.m02 && m10 == t.m10 &&
+                m11 == t.m11 && m12 == t.m12;
+        }
+        return false;
+    }
+
+    
+    /**
+     * Writes the AffineTrassform object to the output steam.
+     * 
+     * @param stream - the output stream
+     * 
+     * @throws IOException - if there are I/O errors while writing to the output strem
+     */
+    private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
+        stream.defaultWriteObject();
+    }
+
+    
+    /**
+     * Read the AffineTransform object from the input stream.
+     * 
+     * @param stream - the input steam
+     * 
+     * @throws IOException - if there are I/O errors while reading from the input strem
+     * @throws ClassNotFoundException - if class could not be found
+     */
+    private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+        type = TYPE_UNKNOWN;
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Arc2D.java b/awt/java/awt/geom/Arc2D.java
new file mode 100644
index 0000000..bc1e95c
--- /dev/null
+++ b/awt/java/awt/geom/Arc2D.java
@@ -0,0 +1,1028 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Arc2D represents a segment of a curve inscribed 
+ * in a rectangle. The curve is defined by a start angle and an 
+ * extent angle (the end angle minus the start angle) as 
+ * a pie wedge whose point is in the center of the rectangle.
+ * The Arc2D as a shape may be either OPEN (including nothing 
+ * but the curved arc segment itself), CHORD (the curved arc
+ * segment closed by a connecting segment from the end to the 
+ * beginning of the arc, or PIE (the segments from the end 
+ * of the arc to the center of the rectangle and from the
+ * center of the rectangle back to the arc's start point are 
+ * included).
+ */
+public abstract class Arc2D extends RectangularShape {
+
+    /** The arc type OPEN indicates that the shape includes only the 
+     * curved arc segment. */
+    public final static int OPEN = 0;
+    
+    /** The arc type CHORD indicates that as a shape the connecting
+     * segment from the end point of the curved arc to the beginning
+     * point is included. */
+    public final static int CHORD = 1;
+    
+    /** The arc type PIE indicates that as a shape the two segments 
+     * from the arc's endpoint to the center of the rectangle and from 
+     * the center of the rectangle to the arc's endpoint are included. */
+    public final static int PIE = 2;
+
+    /**
+     * The Class Float is a subclass of Arc2D in which all of the 
+     * data values are given as floats.
+     * @see Arc2D.Double
+     */
+    public static class Float extends Arc2D {
+
+        /** The x coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public float x;
+        
+        /** The y coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public float y;
+        
+        /** The width of the rectangle that contains the arc. */
+        public float width;
+        
+        /** The height of the rectangle that contains the arc. */
+        public float height;
+        
+        /** The start angle of the arc in degrees. */
+        public float start;
+        
+        /** The width angle of the arc in degrees. */
+        public float extent;
+
+        /**
+         * Instantiates a new Arc2D of type OPEN with float values.
+         */
+        public Float() {
+            super(OPEN);
+        }
+
+        /**
+         * Instantiates a new Arc2D of the specified type with float values.
+         * 
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(int type) {
+            super(type);
+        }
+
+        /**
+         * Instantiates a Arc2D with the specified float-valued data.
+         * 
+         * @param x the x coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param y the y coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param width the width of the rectangle that
+         * contains the arc.
+         * @param height the height of the rectangle that
+         * contains the arc.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(float x, float y, float width, float height, float start, float extent, int type) {
+            super(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        /**
+         * Instantiates a new Angle2D with the specified float-valued data
+         * and the bounding rectangle given by the parameter bounds.
+         * 
+         * @param bounds the bounding rectangle of the Angle2D.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(Rectangle2D bounds, float start, float extent, int type) {
+            super(type);
+            this.x = (float)bounds.getX();
+            this.y = (float)bounds.getY();
+            this.width = (float)bounds.getWidth();
+            this.height = (float)bounds.getHeight();
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+       @Override
+       public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getAngleStart() {
+            return start;
+        }
+
+        @Override
+        public double getAngleExtent() {
+            return extent;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        @Override
+        public void setArc(double x, double y, double width, double height,
+                double start, double extent, int type)
+        {
+            this.setArcType(type);
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+            this.start = (float)start;
+            this.extent = (float)extent;
+        }
+
+        @Override
+        public void setAngleStart(double start) {
+            this.start = (float)start;
+        }
+
+        @Override
+        public void setAngleExtent(double extent) {
+            this.extent = (float)extent;
+        }
+
+        @Override
+        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
+            return new Rectangle2D.Float((float)x, (float)y, (float)width, (float)height);
+        }
+
+    }
+
+    /**
+     * The Class Double is a subclass of Arc2D in which all of the 
+     * data values are given as doubles.
+     * @see Arc2D.Float
+     */
+    public static class Double extends Arc2D {
+
+        /** The x coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public double x;
+        
+        /** The y coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public double y;
+        
+        /** The width of the rectangle that contains the arc. */
+        public double width;
+        
+        /** The height of the rectangle that contains the arc. */
+        public double height;
+        
+        /** The start angle of the arc in degrees. */
+        public double start;
+        
+        /** The width angle of the arc in degrees. */
+        public double extent;
+
+        /**
+         * Instantiates a new Arc2D of type OPEN with double values.
+         */
+        public Double() {
+            super(OPEN);
+        }
+
+        /**
+         * Instantiates a new Arc2D of the specified type with double values.
+         * 
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(int type) {
+            super(type);
+        }
+
+        /**
+         * Instantiates a Arc2D with the specified double-valued data.
+         * 
+         * @param x the x coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param y the y coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param width the width of the rectangle that
+         * contains the arc.
+         * @param height the height of the rectangle that
+         * contains the arc.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(double x, double y, double width, double height,
+                double start, double extent, int type)
+        {
+            super(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        /**
+         * Instantiates a new Angle2D with the specified float-valued data
+         * and the bounding rectangle given by the parameter bounds.
+         * 
+         * @param bounds the bounding rectangle of the Angle2D.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(Rectangle2D bounds, double start, double extent, int type) {
+            super(type);
+            this.x = bounds.getX();
+            this.y = bounds.getY();
+            this.width = bounds.getWidth();
+            this.height = bounds.getHeight();
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getAngleStart() {
+            return start;
+        }
+
+        @Override
+        public double getAngleExtent() {
+            return extent;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setArc(double x, double y, double width, double height,
+                double start, double extent, int type)
+        {
+            this.setArcType(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public void setAngleStart(double start) {
+            this.start = start;
+        }
+
+        @Override
+        public void setAngleExtent(double extent) {
+            this.extent = extent;
+        }
+
+        @Override
+        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+
+    }
+
+    /**
+     * The Class Iterator is the subclass of PathIterator that is used to 
+     * traverse the boundary of a shape of type Arc2D.
+     */
+    class Iterator implements PathIterator {
+
+        /** The x coordinate of the center of the arc's bounding rectangle. */
+        double x;
+
+        /** The y coordinate of the center of the arc's bounding rectangle. */
+        double y;
+
+        /** Half of the width of the arc's bounding rectangle (the radius in the case of a circular arc). */
+        double width;
+        
+        /** Half of the height of the arc's bounding rectangle (the radius in the case of a circular arc). */
+        double height;
+        
+        /** The start angle of the arc in degrees. */
+        double angle;
+        
+        /** The angle extent in degrees. */
+        double extent;
+         
+        /** The closure type of the arc. */
+        int type;
+        
+        /** The path iterator transformation. */
+        AffineTransform t;
+        
+        /** The current segment index. */
+        int index;
+        
+        /** The number of arc segments the source arc subdivided to be approximated by Bezier curves. Depends on extent value. */
+        int arcCount;
+        
+        /** The number of line segments. Depends on closure type. */
+        int lineCount;
+        
+        /** The step to calculate next arc subdivision point. */
+        double step;
+        
+        /** The temporary value of cosinus of the current angle. */
+        double cos;
+
+        /** The temporary value of sinus of the current angle. */
+        double sin;
+        
+        /** The coefficient to calculate control points of Bezier curves. */
+        double k;
+        
+        /** The temporary value of x coordinate of the Bezier curve control vector. */
+        double kx;
+
+        /** The temporary value of y coordinate of the Bezier curve control vector. */
+        double ky;
+        
+        /** The x coordinate of the first path point (MOVE_TO). */
+        double mx;
+        
+        /** The y coordinate of the first path point (MOVE_TO). */
+        double my;
+
+        /**
+         * Constructs a new Arc2D.Iterator for given line and transformation
+         * 
+         * @param a - the source Arc2D object
+         * @param t the AffineTransformation.
+         */
+        Iterator(Arc2D a, AffineTransform t) {
+            if (width < 0 || height < 0) {
+                arcCount = 0;
+                lineCount = 0;
+                index = 1;
+                return;
+            }
+
+            this.width = a.getWidth() / 2.0;
+            this.height = a.getHeight() / 2.0;
+            this.x = a.getX() + width;
+            this.y = a.getY() + height;
+            this.angle = -Math.toRadians(a.getAngleStart());
+            this.extent = -a.getAngleExtent();
+            this.type = a.getArcType();
+            this.t = t;
+
+            if (Math.abs(extent) >= 360.0) {
+                arcCount = 4;
+                k = 4.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+                step = Math.PI / 2.0;
+                if (extent < 0.0) {
+                    step = -step;
+                    k = -k;
+                }
+            } else {
+                arcCount = (int)Math.rint(Math.abs(extent) / 90.0);
+                step = Math.toRadians(extent / arcCount);
+                k = 4.0 / 3.0 * (1.0 - Math.cos(step / 2.0))
+                        / Math.sin(step / 2.0);
+            }
+
+            lineCount = 0;
+            if (type == Arc2D.CHORD) {
+                lineCount++;
+            } else if (type == Arc2D.PIE) {
+                lineCount += 2;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > arcCount + lineCount;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[0] = mx = x + cos * width;
+                coords[1] = my = y + sin * height;
+            } else if (index <= arcCount) {
+                type = SEG_CUBICTO;
+                count = 3;
+                coords[0] = mx - kx;
+                coords[1] = my + ky;
+                angle += step;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[4] = mx = x + cos * width;
+                coords[5] = my = y + sin * height;
+                coords[2] = mx + kx;
+                coords[3] = my - ky;
+            } else if (index == arcCount + lineCount) {
+                type = SEG_CLOSE;
+                count = 0;
+            } else {
+                type = SEG_LINETO;
+                count = 1;
+                coords[0] = x;
+                coords[1] = y;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[0] = (float)(mx = x + cos * width);
+                coords[1] = (float)(my = y + sin * height);
+            } else if (index <= arcCount) {
+                type = SEG_CUBICTO;
+                count = 3;
+                coords[0] = (float)(mx - kx);
+                coords[1] = (float)(my + ky);
+                angle += step;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[4] = (float)(mx = x + cos * width);
+                coords[5] = (float)(my = y + sin * height);
+                coords[2] = (float)(mx + kx);
+                coords[3] = (float)(my - ky);
+            } else if (index == arcCount + lineCount) {
+                type = SEG_CLOSE;
+                count = 0;
+            } else {
+                type = SEG_LINETO;
+                count = 1;
+                coords[0] = (float)x;
+                coords[1] = (float)y;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /** The closure type of the arc. */
+    private int type;
+
+    /**
+     * Instantiates a new arc2D.
+     * 
+     * @param type the closure type.
+     */
+    protected Arc2D(int type) {
+        setArcType(type);
+    }
+
+    /**
+     * Takes the double-valued data and creates the corresponding Rectangle2D
+     * object with values either of type float or of type double depending on
+     * whether this Arc2D instance is of type Float or Double.
+     * 
+     * @param x the x coordinate of the upper left corner of the bounding rectangle.
+     * @param y the y coordinate of the upper left corner of the bounding rectangle.
+     * @param width the width of the bounding rectangle.
+     * @param height the height of the bounding rectangle.
+     * 
+     * @return the corresponding Rectangle2D object.
+     */
+    protected abstract Rectangle2D makeBounds(double x, double y, double width, double height);
+
+    /**
+     * Gets the start angle.
+     * 
+     * @return the start angle.
+     */
+    public abstract double getAngleStart();
+
+    /**
+     * Gets the width angle.
+     * 
+     * @return the width angle.
+     */
+    public abstract double getAngleExtent();
+
+    /**
+     * Sets the start angle.
+     * 
+     * @param start the new start angle.
+     */
+    public abstract void setAngleStart(double start);
+
+    /**
+     * Sets the width angle.
+     * 
+     * @param extent the new width angle.
+     */
+    public abstract void setAngleExtent(double extent);
+
+    /**
+     * Sets the data values that define the arc.
+     * 
+     * @param x the x coordinate of the upper left corner of the rectangle that
+     * contains the arc.
+     * @param y the y coordinate of the upper left corner of the rectangle that
+     * contains the arc.
+     * @param width the width of the rectangle that
+     * contains the arc.
+     * @param height the height of the rectangle that
+     * contains the arc.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the width angle of the arc in degrees.
+     * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public abstract void setArc(double x, double y, double width,
+            double height, double start, double extent, int type);
+
+    /**
+     * Gets the arc type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     * 
+     * @return the arc type.
+     */
+    public int getArcType() {
+        return type;
+    }
+
+    /**
+     * Sets the arc type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     * 
+     * @param type the new arc type.
+     */
+    public void setArcType(int type) {
+        if (type != OPEN && type != CHORD && type != PIE) {
+            // awt.205=Invalid type of Arc: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.205", type)); //$NON-NLS-1$
+        }
+        this.type = type;
+    }
+
+    /**
+     * Gets the start point of the arc as a Point2D.
+     * 
+     * @return the start point of the curved arc segment.
+     */
+    public Point2D getStartPoint() {
+        double a = Math.toRadians(getAngleStart());
+        return new Point2D.Double(
+                getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0,
+                getY() + (1.0 - Math.sin(a)) * getHeight() / 2.0);
+    }
+
+    /**
+     * Gets the end point of the arc as a Point2D.
+     * 
+     * @return the end point of the curved arc segment.
+     */
+    public Point2D getEndPoint() {
+        double a = Math.toRadians(getAngleStart() + getAngleExtent());
+        return new Point2D.Double(
+                getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0,
+                getY() + (1.0 - Math.sin(a)) * getHeight() / 2.0);
+    }
+
+    public Rectangle2D getBounds2D() {
+        if (isEmpty()) {
+            return makeBounds(getX(), getY(), getWidth(), getHeight());
+        }
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+
+        double bx1 = containsAngle(180.0) ? rx1 : Math.min(p1.getX(), p2.getX());
+        double by1 = containsAngle(90.0)  ? ry1 : Math.min(p1.getY(), p2.getY());
+        double bx2 = containsAngle(0.0)   ? rx2 : Math.max(p1.getX(), p2.getX());
+        double by2 = containsAngle(270.0) ? ry2 : Math.max(p1.getY(), p2.getY());
+
+        if (type == PIE) {
+            double cx = getCenterX();
+            double cy = getCenterY();
+            bx1 = Math.min(bx1, cx);
+            by1 = Math.min(by1, cy);
+            bx2 = Math.max(bx2, cx);
+            by2 = Math.max(by2, cy);
+        }
+        return makeBounds(bx1, by1, bx2 - bx1, by2 - by1);
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setArc(x, y, width, height, getAngleStart(), getAngleExtent(), type);
+    }
+
+    /**
+     * Sets the data that defines the arc.
+     * 
+     * @param point the upper left corner of the bounding rectangle.
+     * @param size the size of the bounding rectangle.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the angle witdth of the arc in degrees.
+     * @param type the closure type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArc(Point2D point, Dimension2D size, double start, double extent, int type) {
+        setArc(point.getX(), point.getY(), size.getWidth(), size.getHeight(), start, extent, type);
+    }
+
+    /**
+     * Sets the data that defines the arc.
+     * 
+     * @param rect the arc's bounding rectangle.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the angle witdth of the arc in degrees.
+     * @param type the closure type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArc(Rectangle2D rect, double start, double extent, int type) {
+        setArc(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), start, extent, type);
+    }
+
+    /**
+     * Sets the data that defines the arc by copying it from another Arc2D.
+     * 
+     * @param arc the arc whose data is copied into this arc.
+     */
+    public void setArc(Arc2D arc) {
+        setArc(arc.getX(), arc.getY(), arc.getWidth(), arc.getHeight(), arc
+                .getAngleStart(), arc.getAngleExtent(), arc.getArcType());
+    }
+
+    /**
+     * Sets the data for a circular arc by giving its center and radius.
+     * 
+     * @param x the x coordinate of the center of the circle.
+     * @param y the y coordinate of the center of the circle.
+     * @param radius the radius of the circle.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the angle witdth of the arc in degrees.
+     * @param type the closure type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArcByCenter(double x, double y, double radius, double start, double extent, int type) {
+        setArc(x - radius, y - radius, radius * 2.0, radius * 2.0, start, extent, type);
+    }
+
+    /**
+     * Sets the arc data for a circular arc based on two tangent lines
+     * and the radius. The two tangent lines are the lines from p1 
+     * to p2 and from p2 to p3, which determine a unique circle 
+     * with the given radius. The start and end points of the arc 
+     * are the points where the circle touches the two lines, and 
+     * the arc itself is the shorter of the two circle segments 
+     * determined by the two points (in other words, it is the 
+     * piece of the circle that is closer to the lines' intersection 
+     * point p2 and forms a concave shape with the segments from p1 to p2 
+     * and from p2 to p3).
+     * 
+     * @param p1 a point which determines one of the two tanget lines (with p2).
+     * @param p2 the point of intersection of the two tangent lines.
+     * @param p3 a point which determines one of the two tanget lines (with p2).
+     * @param radius the radius of the circular arc.
+     */
+    public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double radius) {
+        // Used simple geometric calculations of arc center, radius and angles by tangents
+        double a1 = -Math.atan2(p1.getY() - p2.getY(), p1.getX() - p2.getX());
+        double a2 = -Math.atan2(p3.getY() - p2.getY(), p3.getX() - p2.getX());
+        double am = (a1 + a2) / 2.0;
+        double ah = a1 - am;
+        double d = radius / Math.abs(Math.sin(ah));
+        double x = p2.getX() + d * Math.cos(am);
+        double y = p2.getY() - d * Math.sin(am);
+        ah = ah >= 0.0 ? Math.PI * 1.5 - ah : Math.PI * 0.5 - ah;
+        a1 = getNormAngle(Math.toDegrees(am - ah));
+        a2 = getNormAngle(Math.toDegrees(am + ah));
+        double delta = a2 - a1;
+        if (delta <= 0.0) {
+            delta += 360.0;
+        }
+        setArcByCenter(x, y, radius, a1, delta, type);
+    }
+
+    /**
+     * Sets a new start angle to be the angle given by the the vector 
+     * from the current center point to the specified point.
+     * 
+     * @param point the point that determines the new start angle.
+     */
+    public void setAngleStart(Point2D point) {
+        double angle = Math.atan2(point.getY() - getCenterY(), point.getX() - getCenterX());
+        setAngleStart(getNormAngle(-Math.toDegrees(angle)));
+    }
+
+    /**
+     * Sets the angles in terms of vectors from the current arc center 
+     * to the points (x1, y1) and (x2, y2). The start angle is given 
+     * by the vector from the current center to the point (x1, y1) and
+     * the end angle is given by the vector from the center to the point
+     * (x2, y2).
+     * 
+     * @param x1 the x coordinate of the point whose vector from the center
+     * point determines the new start angle of the arc.
+     * @param y1 the y coordinate of the point whose vector from the center
+     * point determines the new start angle of the arc.
+     * @param x2 the x coordinate of the point whose vector from the center
+     * point determines the new end angle of the arc.
+     * @param y2 the y coordinate of the point whose vector from the center
+     * point determines the new end angle of the arc.
+     */
+    public void setAngles(double x1, double y1, double x2, double y2) {
+        double cx = getCenterX();
+        double cy = getCenterY();
+        double a1 = getNormAngle(-Math.toDegrees(Math.atan2(y1 - cy, x1 - cx)));
+        double a2 = getNormAngle(-Math.toDegrees(Math.atan2(y2 - cy, x2 - cx)));
+        a2 -= a1;
+        if (a2 <= 0.0) {
+            a2 += 360.0;
+        }
+        setAngleStart(a1);
+        setAngleExtent(a2);
+    }
+
+    /**
+     * Sets the angles in terms of vectors from the current arc center 
+     * to the points p1 and p2. The start angle is given 
+     * by the vector from the current center to the point p1 and
+     * the end angle is given by the vector from the center to the point
+     * p2.
+     * 
+     * @param p1 the point whose vector from the center
+     * point determines the new start angle of the arc.
+     * @param p2 the point whose vector from the center
+     * point determines the new end angle of the arc.
+     */
+    public void setAngles(Point2D p1, Point2D p2) {
+        setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Normalizes the angle by removing extra winding (past 360 degrees)
+     * and placing it in the positive degree range.
+     * 
+     * @param angle - the source angle in degrees
+     * 
+     * @return an angle between 0 and 360 degrees which corresponds
+     * to the same direction vector as the source angle.
+     */
+    double getNormAngle(double angle) {
+        double n = Math.floor(angle / 360.0);
+        return angle - n * 360.0;
+    }
+
+    /**
+     * Determines whether the given angle is contained in the span of the arc.
+     * 
+     * @param angle the angle to test in degrees.
+     * 
+     * @return true, if the given angle is between the start angle and 
+     * the end angle of the arc.
+     */
+    public boolean containsAngle(double angle) {
+        double extent = getAngleExtent();
+        if (extent >= 360.0) {
+            return true;
+        }
+        angle = getNormAngle(angle);
+        double a1 = getNormAngle(getAngleStart());
+        double a2 = a1 + extent;
+        if (a2 > 360.0) {
+            return angle >= a1 || angle <= a2 - 360.0;
+        }
+        if (a2 < 0.0) {
+            return angle >= a2 + 360.0 || angle <= a1;
+        }
+        return extent > 0.0 ? a1 <= angle && angle <= a2 : a2 <= angle
+                && angle <= a1;
+    }
+
+    public boolean contains(double px, double py) {
+        // Normalize point
+        double nx = (px - getX()) / getWidth() - 0.5;
+        double ny = (py - getY()) / getHeight() - 0.5;
+
+        if ((nx * nx + ny * ny) > 0.25) {
+            return false;
+        }
+
+        double extent = getAngleExtent();
+        double absExtent = Math.abs(extent);
+        if (absExtent >= 360.0) {
+            return true;
+        }
+
+        boolean containsAngle = containsAngle(Math.toDegrees(-Math
+                .atan2(ny, nx)));
+        if (type == PIE) {
+            return containsAngle;
+        }
+        if (absExtent <= 180.0 && !containsAngle) {
+            return false;
+        }
+
+        Line2D l = new Line2D.Double(getStartPoint(), getEndPoint());
+        int ccw1 = l.relativeCCW(px, py);
+        int ccw2 = l.relativeCCW(getCenterX(), getCenterY());
+        return ccw1 == 0 || ccw2 == 0
+                || ((ccw1 + ccw2) == 0 ^ absExtent > 180.0);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+
+        if (!(contains(rx, ry) && contains(rx + rw, ry)
+                && contains(rx + rw, ry + rh) && contains(rx, ry + rh))) {
+            return false;
+        }
+
+        double absExtent = Math.abs(getAngleExtent());
+        if (type != PIE || absExtent <= 180.0 || absExtent >= 360.0) {
+            return true;
+        }
+
+        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
+
+        double cx = getCenterX();
+        double cy = getCenterY();
+        if (r.contains(cx, cy)) {
+            return false;
+        }
+
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+
+        return !r.intersectsLine(cx, cy, p1.getX(), p1.getY())
+                && !r.intersectsLine(cx, cy, p2.getX(), p2.getY());
+    }
+
+    @Override
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        // Check: Does arc contain rectangle's points
+        if (contains(rx, ry) || contains(rx + rw, ry) || contains(rx, ry + rh)
+                || contains(rx + rw, ry + rh)) {
+            return true;
+        }
+
+        double cx = getCenterX();
+        double cy = getCenterY();
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
+
+        // Check: Does rectangle contain arc's points
+        if (r.contains(p1) || r.contains(p2) || (type == PIE && r.contains(cx, cy))) {
+            return true;
+        }
+
+        if (type == PIE) {
+            if (r.intersectsLine(p1.getX(), p1.getY(), cx, cy) ||
+                r.intersectsLine(p2.getX(), p2.getY(), cx, cy))
+            {
+                return true;
+            }
+        } else {
+            if (r.intersectsLine(p1.getX(), p1.getY(), p2.getX(), p2.getY())) {
+                return true;
+            }
+        }
+
+        // Nearest rectangle point
+        double nx = cx < rx ? rx : (cx > rx + rw ? rx + rw : cx);
+        double ny = cy < ry ? ry : (cy > ry + rh ? ry + rh : cy);
+        return contains(nx, ny);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Area.java b/awt/java/awt/geom/Area.java
new file mode 100644
index 0000000..bc27d4e
--- /dev/null
+++ b/awt/java/awt/geom/Area.java
@@ -0,0 +1,317 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Area provides a minimal implementation for a generic shape.
+ */
+public class Area implements Shape, Cloneable {
+
+    /** The source Shape object. */
+    Shape s;
+
+    /**
+     * The Class NullIterator.
+     */
+    private static class NullIterator implements PathIterator {
+
+        /**
+         * Instantiates a new null iterator.
+         */
+        NullIterator() {
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return true;
+        }
+
+        public void next() {
+            // nothing
+        }
+
+        public int currentSegment(double[] coords) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+
+        public int currentSegment(float[] coords) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+
+    }
+
+    /**
+     * Instantiates a new area with no data.
+     */
+    public Area() {
+    }
+
+    /**
+     * Instantiates a new area with data given by the specified shape.
+     * 
+     * @param s the shape that gives the data for this Area
+     */
+    public Area(Shape s) {
+        if (s == null) {
+            throw new NullPointerException();
+        }
+        this.s = s;
+    }
+
+    public boolean contains(double x, double y) {
+        return s == null ? false : s.contains(x, y);
+    }
+
+    public boolean contains(double x, double y, double width, double height) {
+        return s == null ? false : s.contains(x, y, width, height);
+    }
+
+    public boolean contains(Point2D p) {
+        if (p == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.contains(p);
+    }
+
+    public boolean contains(Rectangle2D r) {
+        if (r == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.contains(r);
+    }
+
+    /**
+     * Tests whether the object is equal to this Area.
+     * 
+     * @param obj the object to compare
+     * 
+     * @return true, if successful
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean equals(Area obj) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    public boolean intersects(double x, double y, double width, double height) {
+        return s == null ? false : s.intersects(x, y, width, height);
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        if (r == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.intersects(r);
+    }
+
+    public Rectangle getBounds() {
+        return s == null ? new Rectangle() : s.getBounds();
+    }
+
+    public Rectangle2D getBounds2D() {
+        return s == null ? new Rectangle2D.Double(): s.getBounds2D();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return s == null ? new NullIterator() : s.getPathIterator(t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return s == null ? new NullIterator() : s.getPathIterator(t, flatness);
+    }
+
+    /**
+     * Adds the specified area to this area.
+     * 
+     * @param area the area to add to this area
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void add(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Performs an exclusive or operation between this shape and the
+     * specified shape.
+     * 
+     * @param area the area to XOR against this area
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void exclusiveOr(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Extracts a Rectangle2D from the source shape if the underlying shape
+     * data describes a rectangle.
+     * 
+     * @return a Rectangle2D object if the source shape is rectangle, 
+     * or null if shape is empty or not rectangle.
+     */
+    Rectangle2D extractRectangle() {
+        if (s == null) {
+            return null;
+        }
+        float[] points = new float[12];
+        int count = 0;
+        PathIterator p = s.getPathIterator(null);
+        float[] coords = new float[6];
+        while(!p.isDone()) {
+            int type = p.currentSegment(coords);
+            if (count > 12 || type == PathIterator.SEG_QUADTO || type == PathIterator.SEG_CUBICTO) {
+                return null;
+            }
+            points[count++] = coords[0];
+            points[count++] = coords[1];
+            p.next();
+        }
+        if (points[0] == points[6] && points[6] == points[8] && points[2] == points[4] &&
+            points[1] == points[3] && points[3] == points[9] && points[5] == points[7])
+        {
+            return new Rectangle2D.Float(points[0], points[1], points[2] - points[0], points[7] - points[1]);
+        }
+        return null;
+    }
+    
+    /**
+     * Reduces the size of this Area by intersecting it with the 
+     * specified Area if they are both rectangles.
+     * 
+     * @see java.awt.geom.Rectangle2D#intersect(Rectangle2D, Rectangle2D, Rectangle2D)
+     * 
+     * @param area the area
+     */
+    public void intersect(Area area) {
+        Rectangle2D src1 = extractRectangle();
+        Rectangle2D src2 = area.extractRectangle();
+        if (src1 != null && src2 != null) {
+            Rectangle2D.intersect(src1, src2, (Rectangle2D)s);
+        }
+    }
+
+    /**
+     * Subtract the specified area from this area.
+     * 
+     * @param area the area to subtract
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void subtract(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is empty.
+     * 
+     * @return true, if this Area is empty
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isEmpty() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is polygonal.
+     * 
+     * @return true, if this Area is polygonal
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isPolygonal() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is rectangular.
+     * 
+     * @return true, if this Area is rectangular
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isRectangular() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is singular.
+     * 
+     * @return true, if this Area is singular
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isSingular() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Resets the data of this Area.
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void reset() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Transforms the data of this Area according to the specified 
+     * AffineTransform.
+     * 
+     * @param t the transform to use to transform the data
+     */
+    public void transform(AffineTransform t) {
+        s = t.createTransformedShape(s);
+    }
+
+    /**
+     * Creates a new Area that is the result of transforming the data 
+     * of this Area according to the specified AffineTransform.
+     * 
+     * @param t the transform to use to transform the data
+     * 
+     * @return the new Area that is the result of transforming the data 
+     * of this Area according to the specified AffineTransform.
+     */
+    public Area createTransformedArea(AffineTransform t) {
+        return s == null ? new Area() : new Area(t.createTransformedShape(s));
+    }
+
+    @Override
+    public Object clone() {
+        return new Area(this);
+    }
+
+}
diff --git a/awt/java/awt/geom/CubicCurve2D.java b/awt/java/awt/geom/CubicCurve2D.java
new file mode 100644
index 0000000..3e440c8
--- /dev/null
+++ b/awt/java/awt/geom/CubicCurve2D.java
@@ -0,0 +1,945 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class CubicCurve2D is a Shape that represents a segment of a 
+ * quadratic (Bezier) curve. The curved segment is determined by four points:
+ * a start point, an end point, and two control points. 
+ * The control points give information about the tangent and next 
+ * derivative at the endpoints according to the standard theory of 
+ * Bezier curves. For more information on Bezier curves, 
+ * see <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">this article</a>.
+ */
+public abstract class CubicCurve2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of CubicCurve2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends CubicCurve2D {
+
+        /** The x coordinate of the starting point. */
+        public float x1;
+        
+        /** The y coordinate of the starting point. */
+        public float y1;
+        
+        /** The x coordinate of the first control point. */
+        public float ctrlx1;
+        
+        /** The y coordinate of the first control point. */
+        public float ctrly1;
+        
+        /** The x coordinate of the second control point. */
+        public float ctrlx2;
+        
+        /** The y coordinate of the second control point. */
+        public float ctrly2;
+        
+        /** The x coordinate of the end point. */
+        public float x2;
+        
+        /** The y coordinate of the end point. */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued CubicCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued CubicCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param ctrlx1 the x coordinate of the first control point
+         * @param ctrly1 the y coordinate of the first control point
+         * @param ctrlx2 the x coordinate of the second control point
+         * @param ctrly2 the y coordinate of the second control point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Float(float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x2, float y2) {
+            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX1() {
+            return ctrlx1;
+        }
+
+        @Override
+        public double getCtrlY1() {
+            return ctrly1;
+        }
+
+        @Override
+        public double getCtrlX2() {
+            return ctrlx2;
+        }
+
+        @Override
+        public double getCtrlY2() {
+            return ctrly2;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlP1() {
+            return new Point2D.Float(ctrlx1, ctrly1);
+        }
+
+        @Override
+        public Point2D getCtrlP2() {
+            return new Point2D.Float(ctrlx2, ctrly2);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+                double ctrlx2, double ctrly2, double x2, double y2)
+        {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.ctrlx1 = (float)ctrlx1;
+            this.ctrly1 = (float)ctrly1;
+            this.ctrlx2 = (float)ctrlx2;
+            this.ctrly2 = (float)ctrly2;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values of the curve.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param ctrlx1 the x coordinate of the first control point
+         * @param ctrly1 the y coordinate of the first control point
+         * @param ctrlx2 the x coordinate of the second control point
+         * @param ctrly2 the y coordinate of the second control point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public void setCurve(float x1, float y1, float ctrlx1, float ctrly1,
+                float ctrlx2, float ctrly2, float x2, float y2)
+        {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx1 = ctrlx1;
+            this.ctrly1 = ctrly1;
+            this.ctrlx2 = ctrlx2;
+            this.ctrly2 = ctrly2;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
+            float ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
+            float rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
+            float ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
+            return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of CubicCurve2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends CubicCurve2D {
+
+        /** The x coordinate of the starting point. */
+        public double x1;
+        
+        /** The y coordinate of the starting point. */
+        public double y1;
+        
+        /** The x coordinate of the first control point. */
+        public double ctrlx1;
+        
+        /** The y coordinate of the first control point. */
+        public double ctrly1;
+        
+        /** The x coordinate of the second control point. */
+        public double ctrlx2;
+        
+        /** The y coordinate of the second control point. */
+        public double ctrly2;
+        
+        /** The x coordinate of the end point. */
+        public double x2;
+        
+        /** The y coordinate of the end point. */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued CubicCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued CubicCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param ctrlx1 the x coordinate of the first control point
+         * @param ctrly1 the y coordinate of the first control point
+         * @param ctrlx2 the x coordinate of the second control point
+         * @param ctrly2 the y coordinate of the second control point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Double(double x1, double y1, double ctrlx1, double ctrly1,
+                double ctrlx2, double ctrly2, double x2, double y2) {
+            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX1() {
+            return ctrlx1;
+        }
+
+        @Override
+        public double getCtrlY1() {
+            return ctrly1;
+        }
+
+        @Override
+        public double getCtrlX2() {
+            return ctrlx2;
+        }
+
+        @Override
+        public double getCtrlY2() {
+            return ctrly2;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlP1() {
+            return new Point2D.Double(ctrlx1, ctrly1);
+        }
+
+        @Override
+        public Point2D getCtrlP2() {
+            return new Point2D.Double(ctrlx2, ctrly2);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+                double ctrlx2, double ctrly2, double x2, double y2)
+        {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx1 = ctrlx1;
+            this.ctrly1 = ctrly1;
+            this.ctrlx2 = ctrlx2;
+            this.ctrly2 = ctrly2;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
+            double ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
+            double rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
+            double ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
+            return new Rectangle2D.Double(rx1, ry1, rx2 - rx1, ry2 - ry1);
+        }
+    }
+
+    /*
+     * CubicCurve2D path iterator 
+     */
+    /**
+     * The Iterator class for the Shape CubicCurve2D.
+     */
+    class Iterator implements PathIterator {
+
+        /** The source CubicCurve2D object. */
+        CubicCurve2D c;
+        
+        /** The path iterator transformation. */
+        AffineTransform t;
+        
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new CubicCurve2D.Iterator for given line and transformation
+         * 
+         * @param c - the source CubicCurve2D object
+         * @param t the t
+         */
+        Iterator(CubicCurve2D c, AffineTransform t) {
+            this.c = c;
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 1;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = c.getX1();
+                coords[1] = c.getY1();
+                count = 1;
+            } else {
+                type = SEG_CUBICTO;
+                coords[0] = c.getCtrlX1();
+                coords[1] = c.getCtrlY1();
+                coords[2] = c.getCtrlX2();
+                coords[3] = c.getCtrlY2();
+                coords[4] = c.getX2();
+                coords[5] = c.getY2();
+                count = 3;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)c.getX1();
+                coords[1] = (float)c.getY1();
+                count = 1;
+            } else {
+                type = SEG_CUBICTO;
+                coords[0] = (float)c.getCtrlX1();
+                coords[1] = (float)c.getCtrlY1();
+                coords[2] = (float)c.getCtrlX2();
+                coords[3] = (float)c.getCtrlY2();
+                coords[4] = (float)c.getX2();
+                coords[5] = (float)c.getY2();
+                count = 3;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new 2-D cubic curve.
+     */
+    protected CubicCurve2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the starting point.
+     * 
+     * @return the starting point
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the x coordinate of the first control point.
+     * 
+     * @return the x coordinate of the first control point
+     */
+    public abstract double getCtrlX1();
+
+    /**
+     * Gets the y coordinate of the first control point.
+     * 
+     * @return the y coordinate of the first control point
+     */
+    public abstract double getCtrlY1();
+
+    /**
+     * Gets the second control point.
+     * 
+     * @return the second control point
+     */
+    public abstract Point2D getCtrlP1();
+
+    /**
+     * Gets the x coordinate of the second control point.
+     * 
+     * @return the x coordinate of the second control point
+     */
+    public abstract double getCtrlX2();
+
+    /**
+     * Gets the y coordinate of the second control point.
+     * 
+     * @return the y coordinate of the second control point
+     */
+    public abstract double getCtrlY2();
+
+    /**
+     * Gets the second control point.
+     * 
+     * @return the second control point
+     */
+    public abstract Point2D getCtrlP2();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x coordinate of the end point
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the end point.
+     * 
+     * @return the end point
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param ctrlx1 the x coordinate of the first control point
+     * @param ctrly1 the y coordinate of the first control point
+     * @param ctrlx2 the x coordinate of the second control point
+     * @param ctrly2 the y coordinate of the second control point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     */
+    public abstract void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2);
+
+    /**
+     * Sets the data of the curve as point objects.
+     * 
+     * @param p1 the starting point
+     * @param cp1 the first control point
+     * @param cp2 the second control point
+     * @param p2 the end point
+     * 
+     * @throws NullPointerException if any of the points is null.
+     */
+    public void setCurve(Point2D p1, Point2D cp1, Point2D cp2, Point2D p2) {
+        setCurve(
+                p1.getX(), p1.getY(),
+                cp1.getX(), cp1.getY(),
+                cp2.getX(), cp2.getY(),
+                p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of values. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#setCurve(double, double, double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of values containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 8.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public void setCurve(double[] coords, int offset) {
+        setCurve(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of points. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#setCurve(Point2D, Point2D, Point2D, Point2D)}
+     * 
+     * @param points the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + .
+     * @throws NullPointerException if the point array is null.
+     */
+    public void setCurve(Point2D[] points, int offset) {
+        setCurve(
+                points[offset + 0].getX(), points[offset + 0].getY(),
+                points[offset + 1].getX(), points[offset + 1].getY(),
+                points[offset + 2].getX(), points[offset + 2].getY(),
+                points[offset + 3].getX(), points[offset + 3].getY());
+    }
+
+    /**
+     * Sets the data of the curve by copying it from another CubicCurve2D.
+     * 
+     * @param curve the curve to copy the data points from
+     * 
+     * @throws NullPointerException if the curve is null.
+     */
+    public void setCurve(CubicCurve2D curve) {
+        setCurve(
+                curve.getX1(), curve.getY1(),
+                curve.getCtrlX1(), curve.getCtrlY1(),
+                curve.getCtrlX2(), curve.getCtrlY2(),
+                curve.getX2(), curve.getY2());
+    }
+
+    /**
+     * Gets the square of the flatness of this curve, where the flatness is the 
+     * maximum distance from the curves control points to the 
+     * line segment connecting the two points.
+     * 
+     * @return the square of the flatness
+     */
+    public double getFlatnessSq() {
+        return getFlatnessSq(
+                getX1(), getY1(),
+                getCtrlX1(), getCtrlY1(),
+                getCtrlX2(), getCtrlY2(),
+                getX2(), getY2());
+    }
+
+    /**
+     * Gets the square of the flatness of the cubic curve segment 
+     * defined by the specified values.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param ctrlx1 the x coordinate of the first control point
+     * @param ctrly1 the y coordinate of the first control point
+     * @param ctrlx2 the x coordinate of the second control point
+     * @param ctrly2 the y coordinate of the second control point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     * 
+     * @return the square of the flatness
+     */
+    public static double getFlatnessSq(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2)
+    {
+        return Math.max(
+                Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx1, ctrly1),
+                Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx2, ctrly2));
+    }
+
+    /**
+     * Gets the square of the flatness of the cubic curve segment 
+     * defined by the specified values. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#getFlatnessSq(double, double, double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the square of the flatness
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + .
+     * @throws NullPointerException if the point array is null.
+     */
+    public static double getFlatnessSq(double coords[], int offset) {
+        return getFlatnessSq(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Gets the flatness of this curve, where the flatness is the 
+     * maximum distance from the curves control points to the 
+     * line segment connecting the two points.
+     * 
+     * @return the flatness of this curve
+     */
+    public double getFlatness() {
+        return getFlatness(
+                getX1(), getY1(),
+                getCtrlX1(), getCtrlY1(),
+                getCtrlX2(), getCtrlY2(),
+                getX2(), getY2());
+    }
+
+    /**
+     * Gets the flatness of the cubic curve segment 
+     * defined by the specified values.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param ctrlx1 the x coordinate of the first control point
+     * @param ctrly1 the y coordinate of the first control point
+     * @param ctrlx2 the x coordinate of the second control point
+     * @param ctrly2 the y coordinate of the second control point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     * 
+     * @return the flatness
+     */
+    public static double getFlatness(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2)
+    {
+        return Math.sqrt(getFlatnessSq(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2));
+    }
+
+    /**
+     * Gets the flatness of the cubic curve segment 
+     * defined by the specified values. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#getFlatness(double, double, double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the flatness
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + .
+     * @throws NullPointerException if the point array is null.
+     */
+    public static double getFlatness(double coords[], int offset) {
+        return getFlatness(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing this
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the average of curve's two control points. 
+     * The two new control points (nearest the new endpoint) are computed
+     * by averaging the original control points with the new endpoint.
+     * The data of this curve is left unchanged.
+     * 
+     * @param left the CubicCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the CubicCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if either curve is null.
+     */
+    public void subdivide(CubicCurve2D left, CubicCurve2D right) {
+        subdivide(this, left, right);
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing the specified
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the average of curve's two control points. 
+     * The two new control points (nearest the new endpoint) are computed
+     * by averaging the original control points with the new endpoint.
+     * The data of the source curve is left unchanged.
+     * 
+     * @param src the original curve to be divided in two
+     * @param left the CubicCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the CubicCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if either curve is null.
+     */
+    public static void subdivide(CubicCurve2D src, CubicCurve2D left, CubicCurve2D right) {
+        double x1 = src.getX1();
+        double y1 = src.getY1();
+        double cx1 = src.getCtrlX1();
+        double cy1 = src.getCtrlY1();
+        double cx2 = src.getCtrlX2();
+        double cy2 = src.getCtrlY2();
+        double x2 = src.getX2();
+        double y2 = src.getY2();
+        double cx = (cx1 + cx2) / 2.0;
+        double cy = (cy1 + cy2) / 2.0;
+        cx1 = (x1 + cx1) / 2.0;
+        cy1 = (y1 + cy1) / 2.0;
+        cx2 = (x2 + cx2) / 2.0;
+        cy2 = (y2 + cy2) / 2.0;
+        double ax = (cx1 + cx) / 2.0;
+        double ay = (cy1 + cy) / 2.0;
+        double bx = (cx2 + cx) / 2.0;
+        double by = (cy2 + cy) / 2.0;
+        cx = (ax + bx) / 2.0;
+        cy = (ay + by) / 2.0;
+        if (left != null) {
+            left.setCurve(x1, y1, cx1, cy1, ax, ay, cx, cy);
+        }
+        if (right != null) {
+            right.setCurve(cx, cy, bx, by, cx2, cy2, x2, y2);
+        }
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing the specified
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the average of curve's two control points. 
+     * The two new control points (nearest the new endpoint) are computed
+     * by averaging the original control points with the new endpoint.
+     * The data of the source curve is left unchanged. The data for the 
+     * three curves is read/written in the usual order: { x1, y1, 
+     * ctrlx1, ctrly1, ctrlx2, crtry2, x2, y3 }
+     * 
+     * @param src the array that gives the data values for the source curve
+     * @param srcOff the offset in the src array to read the values from
+     * @param left the array where the coordinates of the start curve should be written
+     * @param leftOff the offset in the left array to start writing the values
+     * @param right the array where the coordinates of the end curve should be written
+     * @param rightOff the offset in the right array to start writing the values
+     * 
+     * @throws ArrayIndexOutOfBoundsException if src.length < srcoff + 8
+     * or if left.length < leftOff + 8 or if right.length < rightOff + 8.
+     * @throws NullPointerException if one of the arrays is null.
+     */
+    public static void subdivide(double src[], int srcOff, double left[], int leftOff, double right[], int rightOff) {
+        double x1 = src[srcOff + 0];
+        double y1 = src[srcOff + 1];
+        double cx1 = src[srcOff + 2];
+        double cy1 = src[srcOff + 3];
+        double cx2 = src[srcOff + 4];
+        double cy2 = src[srcOff + 5];
+        double x2 = src[srcOff + 6];
+        double y2 = src[srcOff + 7];
+        double cx = (cx1 + cx2) / 2.0;
+        double cy = (cy1 + cy2) / 2.0;
+        cx1 = (x1 + cx1) / 2.0;
+        cy1 = (y1 + cy1) / 2.0;
+        cx2 = (x2 + cx2) / 2.0;
+        cy2 = (y2 + cy2) / 2.0;
+        double ax = (cx1 + cx) / 2.0;
+        double ay = (cy1 + cy) / 2.0;
+        double bx = (cx2 + cx) / 2.0;
+        double by = (cy2 + cy) / 2.0;
+        cx = (ax + bx) / 2.0;
+        cy = (ay + by) / 2.0;
+        if (left != null) {
+            left[leftOff + 0] = x1;
+            left[leftOff + 1] = y1;
+            left[leftOff + 2] = cx1;
+            left[leftOff + 3] = cy1;
+            left[leftOff + 4] = ax;
+            left[leftOff + 5] = ay;
+            left[leftOff + 6] = cx;
+            left[leftOff + 7] = cy;
+        }
+        if (right != null) {
+            right[rightOff + 0] = cx;
+            right[rightOff + 1] = cy;
+            right[rightOff + 2] = bx;
+            right[rightOff + 3] = by;
+            right[rightOff + 4] = cx2;
+            right[rightOff + 5] = cy2;
+            right[rightOff + 6] = x2;
+            right[rightOff + 7] = y2;
+        }
+    }
+
+    /**
+     * Finds the roots of the cubic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[3]*x*x*x + eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written back into the array eqn starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been changed by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * cubic polynomial to solve.
+     * 
+     * @return the number of roots of the cubic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 4.
+     * @throws NullPointerException if the array is null.
+     */
+    public static int solveCubic(double eqn[]) {
+        return solveCubic(eqn, eqn);
+    }
+
+    /**
+     * Finds the roots of the cubic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[3]*x*x*x + eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written into the array res starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been changed by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * cubic polynomial to solve.
+     * @param res the array that this method writes the results into
+     * 
+     * @return the number of roots of the cubic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 4 or 
+     * if res.length is less than the number of roots.
+     * @throws NullPointerException if either array is null.
+     */
+    public static int solveCubic(double eqn[], double res[]) {
+        return Crossing.solveCubic(eqn, res);
+    }
+
+    public boolean contains(double px, double py) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(at), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/geom/Dimension2D.java b/awt/java/awt/geom/Dimension2D.java
new file mode 100644
index 0000000..eef63e6
--- /dev/null
+++ b/awt/java/awt/geom/Dimension2D.java
@@ -0,0 +1,78 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Class Dimension2D represents a size (width and height) of a 
+ * geometric object. It stores double-valued data in order to be compatible
+ * with high-precision geometric operations.
+ */
+public abstract class Dimension2D implements Cloneable {
+
+    /**
+     * Instantiates a new dimension 2d with no data.
+     */
+    protected Dimension2D() {
+    }
+
+    /**
+     * Gets the width.
+     * 
+     * @return the width
+     */
+    public abstract double getWidth();
+
+    /**
+     * Gets the height.
+     * 
+     * @return the height
+     */
+    public abstract double getHeight();
+
+    /**
+     * Sets the width and height.
+     * 
+     * @param width the width
+     * @param height the height
+     */
+    public abstract void setSize(double width, double height);
+
+    /**
+     * Sets the width and height based on the data of another 
+     * Dimension2D object.
+     * 
+     * @param d the Dimension2D object providing the data to copy 
+     * into this Dimension2D object
+     */
+    public void setSize(Dimension2D d) {
+        setSize(d.getWidth(), d.getHeight());
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+}
+
diff --git a/awt/java/awt/geom/Ellipse2D.java b/awt/java/awt/geom/Ellipse2D.java
new file mode 100644
index 0000000..33464af
--- /dev/null
+++ b/awt/java/awt/geom/Ellipse2D.java
@@ -0,0 +1,403 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Ellipse2D describes an ellipse defined by a rectangular
+ * area in which it is inscribed.
+ */
+public abstract class Ellipse2D extends RectangularShape {
+
+    /**
+     * The Class Float is the subclass of Ellipse2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends Ellipse2D {
+
+        /** The x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public float x;
+        
+        /** The y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public float y;
+        
+        /** The width of the ellipse's bounding rectangle. */
+        public float width;
+        
+        /** The height of the ellipse's bounding rectangle. */
+        public float height;
+
+        /**
+         * Instantiates a new float-valued Ellipse2D.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Ellipse2D with the specified data.
+         * 
+         * @param x the x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param y the y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param width the width of the ellipse's bounding rectangle
+         * @param height the height of the ellipse's bounding rectangle
+         */
+        public Float(float x, float y, float width, float height) {
+            setFrame(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        /**
+         * Sets the data of the ellipse's bounding rectangle.
+         * 
+         * @param x the x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param y the y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param width the width of the ellipse's bounding rectangle
+         * @param height the height of the ellipse's bounding rectangle
+         */
+        public void setFrame(float x, float y, float width, float height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setFrame(double x, double y, double width, double height) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Float(x, y, width, height);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Ellipse2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends Ellipse2D {
+
+        /** The x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public double x;
+        
+        /** The y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public double y;
+        
+        /** The width of the ellipse's bounding rectangle. */
+        public double width;
+        
+        /** The height of the ellipse's bounding rectangle. */
+        public double height;
+
+        /**
+         * Instantiates a new double-valued Ellipse2D.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Ellipse2D with the specified
+         * data.
+         * 
+         * @param x the x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param y the y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param width the width of the ellipse's bounding rectangle
+         * @param height the height of the ellipse's bounding rectangle
+         */
+        public Double(double x, double y, double width, double height) {
+            setFrame(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setFrame(double x, double y, double width, double height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+    }
+
+    /*
+     * Ellipse2D path iterator 
+     */
+    /**
+     * The subclass of PathIterator to traverse an Ellipse2D.
+     */
+    class Iterator implements PathIterator {
+
+        /*
+         * Ellipse is subdivided into four quarters by x and y axis. Each part approximated by
+         * cubic Bezier curve. Arc in first quarter is started in (a, 0) and finished in (0, b) points.
+         * Control points for cubic curve wiil be (a, 0), (a, m), (n, b) and (0, b) where n and m are
+         * calculated based on requirement Bezier curve in point 0.5 should lay on the arc.
+         */
+
+        /** The coefficient to calculate control points of Bezier curves. */
+        final double u = 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+
+        /** The points coordinates calculation table. */
+        final double points[][] = {
+                { 1.0, 0.5 + u, 0.5 + u, 1.0, 0.5, 1.0 },
+                { 0.5 - u, 1.0, 0.0, 0.5 + u, 0.0, 0.5 },
+                { 0.0, 0.5 - u, 0.5 - u, 0.0, 0.5, 0.0 },
+                { 0.5 + u, 0.0, 1.0, 0.5 - u, 1.0, 0.5 }
+        };
+
+        /** The x coordinate of left-upper corner of the ellipse bounds. */
+        double x;
+        
+        /** The y coordinate of left-upper corner of the ellipse bounds. */
+        double y;
+        
+        /** The width of the ellipse bounds. */
+        double width;
+        
+        /** The height of the ellipse bounds. */
+        double height;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new Ellipse2D.Iterator for given ellipse and transformation
+         * 
+         * @param e - the source Ellipse2D object
+         * @param t the t
+         */
+        Iterator(Ellipse2D e, AffineTransform t) {
+            this.x = e.getX();
+            this.y = e.getY();
+            this.width = e.getWidth();
+            this.height = e.getHeight();
+            this.t = t;
+            if (width < 0.0 || height < 0.0) {
+                index = 6;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 5;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                double p[] = points[3];
+                coords[0] = x + p[4] * width;
+                coords[1] = y + p[5] * height;
+            } else {
+                type = SEG_CUBICTO;
+                count = 3;
+                double p[] = points[index - 1];
+                int j = 0;
+                for (int i = 0; i < 3; i++) {
+                    coords[j] = x + p[j++] * width;
+                    coords[j] = y + p[j++] * height;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                double p[] = points[3];
+                coords[0] = (float)(x + p[4] * width);
+                coords[1] = (float)(y + p[5] * height);
+            } else {
+                type = SEG_CUBICTO;
+                count = 3;
+                int j = 0;
+                double p[] = points[index - 1];
+                for (int i = 0; i < 3; i++) {
+                    coords[j] = (float)(x + p[j++] * width);
+                    coords[j] = (float)(y + p[j++] * height);
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new Ellipse2D.
+     */
+    protected Ellipse2D() {
+    }
+
+    public boolean contains(double px, double py) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double a = (px - getX()) / getWidth() - 0.5;
+        double b = (py - getY()) / getHeight() - 0.5;
+
+        return a * a + b * b < 0.25;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double cx = getX() + getWidth() / 2.0;
+        double cy = getY() + getHeight() / 2.0;
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
+        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
+
+        return contains(nx, ny);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        return
+            contains(rx1, ry1) &&
+            contains(rx2, ry1) &&
+            contains(rx2, ry2) &&
+            contains(rx1, ry2);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+}
+
diff --git a/awt/java/awt/geom/FlatteningPathIterator.java b/awt/java/awt/geom/FlatteningPathIterator.java
new file mode 100644
index 0000000..ca5c7c2
--- /dev/null
+++ b/awt/java/awt/geom/FlatteningPathIterator.java
@@ -0,0 +1,326 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class FlatteningPathIterator takes a PathIterator for traversing 
+ * a curved shape and flattens it by estimating the curve as a series 
+ * of line segments. The flattening factor indicates how far the 
+ * estimating line segments are allowed to be from the actual curve:
+ * the FlatteningPathIterator will keep dividing each curved segment 
+ * into smaller and smaller flat segments until either the segments 
+ * are withing the flattening factor of the curve or until the buffer
+ * limit is reached.
+ */
+public class FlatteningPathIterator implements PathIterator {
+
+    /** The default points buffer size. */
+    private static final int BUFFER_SIZE = 16;
+    
+    /** The default curve subdivision limit. */
+    private static final int BUFFER_LIMIT = 16;
+
+    /** The points buffer capacity. */
+    private static final int BUFFER_CAPACITY = 16;
+    
+    /** The type of current segment to be flat. */
+    int bufType;
+    
+    /** The curve subdivision limit. */
+    int bufLimit;
+    
+    /** The current points buffer size. */
+    int bufSize;
+    
+    /** The inner cursor position in points buffer. */
+    int bufIndex;
+    
+    /** The current subdivision count. */
+    int bufSubdiv;
+
+    /** The points buffer. */
+    double buf[];
+    
+    /** The indicator of empty points buffer. */
+    boolean bufEmpty = true;
+    
+    /** The source PathIterator. */
+    PathIterator p;
+    
+    /** The flatness of new path. */
+    double flatness;
+    
+    /** The square of flatness. */
+    double flatness2;
+    
+    /** The x coordinate of previous path segment. */
+    double px;
+
+    /** The y coordinate of previous path segment. */
+    double py;
+    
+    /** The tamporary buffer for getting points from PathIterator. */
+    double coords[] = new double[6];
+
+    /**
+     * Instantiates a new flattening path iterator given the path 
+     * iterator for a (possibly) curved path and a flattening factor
+     * which indicates how close together the points on the curve 
+     * should be chosen. The buffer limit defaults to 16 which means 
+     * that each curve will be divided into no more than 16 segments 
+     * regardless of the flattening factor.
+     * 
+     * @param path the path iterator of the original curve
+     * @param flatness the flattening factor that indicates how far the 
+     * flat path is allowed to be from the actual curve in order to 
+     * decide when to stop dividing the path into smaller and smaller
+     * segments.
+     * 
+     * @throws IllegalArgumentException if the flatness is less than zero.
+     * @throws NullPointerException if the path is null.
+     */
+    public FlatteningPathIterator(PathIterator path, double flatness) {
+        this(path, flatness, BUFFER_LIMIT);
+    }
+
+    /**
+     * Instantiates a new flattening path iterator given the path 
+     * iterator for a (possibly) curved path and a flattening factor
+     * and a buffer limit. The FlatteningPathIterator will keep 
+     * dividing each curved segment into smaller and smaller flat segments 
+     * until either the segments are withing the flattening factor of the 
+     * curve or until the buffer limit is reached.
+     * 
+     * @param path the path iterator of the original curve
+     * @param flatness the flattening factor that indicates how far the 
+     * flat path is allowed to be from the actual curve in order to 
+     * decide when to stop dividing the path into smaller and smaller
+     * segments.
+     * @param limit the maximum number of flat segments to divide each 
+     * curve into
+     * 
+     * @throws IllegalArgumentException if the flatness or limit is less than zero.
+     * @throws NullPointerException if the path is null.
+     */
+    public FlatteningPathIterator(PathIterator path, double flatness, int limit) {
+        if (flatness < 0.0) {
+            // awt.206=Flatness is less then zero
+            throw new IllegalArgumentException(Messages.getString("awt.206")); //$NON-NLS-1$
+        }
+        if (limit < 0) {
+            // awt.207=Limit is less then zero
+            throw new IllegalArgumentException(Messages.getString("awt.207")); //$NON-NLS-1$
+        }
+        if (path == null) {
+            // awt.208=Path is null
+            throw new NullPointerException(Messages.getString("awt.208")); //$NON-NLS-1$
+        }
+        this.p = path;
+        this.flatness = flatness;
+        this.flatness2 = flatness * flatness;
+        this.bufLimit = limit;
+        this.bufSize = Math.min(bufLimit, BUFFER_SIZE);
+        this.buf = new double[bufSize];
+        this.bufIndex = bufSize;
+    }
+
+    /**
+     * Gets the flattening factor.
+     * 
+     * @return the flattening factor
+     */
+    public double getFlatness() {
+        return flatness;
+    }
+
+    /**
+     * Gets the maximum number of subdivisions per curved segment.
+     * 
+     * @return the maximum number of subdivisions per curved segment
+     */
+    public int getRecursionLimit() {
+        return bufLimit;
+    }
+
+    public int getWindingRule() {
+        return p.getWindingRule();
+    }
+
+    public boolean isDone() {
+        return bufEmpty && p.isDone();
+    }
+
+    /**
+     * Calculates flat path points for current segment of the source shape.
+     * 
+     * Line segment is flat by itself. Flatness of quad and cubic curves evaluated by getFlatnessSq() method.
+     * Curves subdivided until current flatness is bigger than user defined and subdivision limit isn't exhausted.
+     * Single source segment translated to series of buffer points. The less flatness the bigger serries.
+     * Every currentSegment() call extract one point from the buffer. When series completed evaluate() takes next source shape segment.
+     */
+    void evaluate() {
+        if (bufEmpty) {
+            bufType = p.currentSegment(coords);
+        }
+
+        switch (bufType) {
+        case SEG_MOVETO:
+        case SEG_LINETO:
+            px = coords[0];
+            py = coords[1];
+            break;
+        case SEG_QUADTO:
+            if (bufEmpty) {
+                bufIndex -= 6;
+                buf[bufIndex + 0] = px;
+                buf[bufIndex + 1] = py;
+                System.arraycopy(coords, 0, buf, bufIndex + 2, 4);
+                bufSubdiv = 0;
+            }
+
+            while (bufSubdiv < bufLimit) {
+                if (QuadCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
+                    break;
+                }
+
+                // Realloc buffer
+                if (bufIndex <= 4) {
+                    double tmp[] = new double[bufSize + BUFFER_CAPACITY];
+                    System.arraycopy(
+                            buf, bufIndex,
+                            tmp, bufIndex + BUFFER_CAPACITY,
+                            bufSize - bufIndex);
+                    buf = tmp;
+                    bufSize += BUFFER_CAPACITY;
+                    bufIndex += BUFFER_CAPACITY;
+                }
+
+                QuadCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 4, buf, bufIndex);
+
+                bufIndex -= 4;
+                bufSubdiv++;
+            }
+
+            bufIndex += 4;
+            px = buf[bufIndex];
+            py = buf[bufIndex + 1];
+
+            bufEmpty = (bufIndex == bufSize - 2);
+            if (bufEmpty) {
+                bufIndex = bufSize;
+                bufType = SEG_LINETO;
+            } else {
+                bufSubdiv--;
+            }
+            break;
+        case SEG_CUBICTO:
+            if (bufEmpty) {
+                bufIndex -= 8;
+                buf[bufIndex + 0] = px;
+                buf[bufIndex + 1] = py;
+                System.arraycopy(coords, 0, buf, bufIndex + 2, 6);
+                bufSubdiv = 0;
+            }
+
+            while (bufSubdiv < bufLimit) {
+                if (CubicCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
+                    break;
+                }
+
+                // Realloc buffer
+                if (bufIndex <= 6) {
+                    double tmp[] = new double[bufSize + BUFFER_CAPACITY];
+                    System.arraycopy(
+                            buf, bufIndex,
+                            tmp, bufIndex + BUFFER_CAPACITY,
+                            bufSize - bufIndex);
+                    buf = tmp;
+                    bufSize += BUFFER_CAPACITY;
+                    bufIndex += BUFFER_CAPACITY;
+                }
+
+                CubicCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 6, buf, bufIndex);
+
+                bufIndex -= 6;
+                bufSubdiv++;
+            }
+
+            bufIndex += 6;
+            px = buf[bufIndex];
+            py = buf[bufIndex + 1];
+
+            bufEmpty = (bufIndex == bufSize - 2);
+            if (bufEmpty) {
+                bufIndex = bufSize;
+                bufType = SEG_LINETO;
+            } else {
+                bufSubdiv--;
+            }
+            break;
+        }
+
+    }
+
+    public void next() {
+        if (bufEmpty) {
+            p.next();
+        }
+    }
+
+    public int currentSegment(float[] coords) {
+        if (isDone()) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4Bx")); //$NON-NLS-1$
+        }
+        evaluate();
+        int type = bufType;
+        if (type != SEG_CLOSE) {
+            coords[0] = (float)px;
+            coords[1] = (float)py;
+            if (type != SEG_MOVETO) {
+                type = SEG_LINETO;
+            }
+        }
+        return type;
+    }
+
+    public int currentSegment(double[] coords) {
+        if (isDone()) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+        evaluate();
+        int type = bufType;
+        if (type != SEG_CLOSE) {
+            coords[0] = px;
+            coords[1] = py;
+            if (type != SEG_MOVETO) {
+                type = SEG_LINETO;
+            }
+        }
+        return type;
+    }
+}
+
diff --git a/awt/java/awt/geom/GeneralPath.java b/awt/java/awt/geom/GeneralPath.java
new file mode 100644
index 0000000..36b01c4
--- /dev/null
+++ b/awt/java/awt/geom/GeneralPath.java
@@ -0,0 +1,566 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class GeneralPath represents a shape whose outline is given 
+ * by different types of curved and straight segments.
+ */
+public final class GeneralPath implements Shape, Cloneable {
+
+    /** The Constant WIND_EVEN_ODD see {@link PathIterator#WIND_EVEN_ODD}. */
+    public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
+    
+    /** The Constant WIND_NON_ZERO see {@link PathIterator#WIND_NON_ZERO}. */
+    public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
+
+    /** The buffers size. */
+    private static final int BUFFER_SIZE = 10;
+    
+    /** The buffers capacity. */
+    private static final int BUFFER_CAPACITY = 10;
+
+    /** The point's types buffer. */
+    byte[] types;
+    
+    /** The points buffer. */
+    float[] points;
+    
+    /** The point's type buffer size. */
+    int typeSize;
+    
+    /** The points buffer size. */
+    int pointSize;
+    
+    /** The path rule. */
+    int rule;
+
+    /** The space amount in points buffer for different segmenet's types. */
+    static int pointShift[] = {
+            2,  // MOVETO
+            2,  // LINETO
+            4,  // QUADTO
+            6,  // CUBICTO
+            0}; // CLOSE
+
+    /*
+     * GeneralPath path iterator 
+     */
+    /**
+     * The Class Iterator is the subclass of Iterator for traversing the 
+     * outline of a GeneralPath.
+     */
+    class Iterator implements PathIterator {
+
+        /** The current cursor position in types buffer. */
+        int typeIndex;
+        
+        /** The current cursor position in points buffer. */
+        int pointIndex;
+        
+        /** The source GeneralPath object. */
+        GeneralPath p;
+        
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /**
+         * Constructs a new GeneralPath.Iterator for given general path
+         * 
+         * @param path - the source GeneralPath object
+         */
+        Iterator(GeneralPath path) {
+            this(path, null);
+        }
+
+        /**
+         * Constructs a new GeneralPath.Iterator for given general path and transformation
+         * 
+         * @param path - the source GeneralPath object
+         * @param at - the AffineTransform object to apply rectangle path
+         */
+        Iterator(GeneralPath path, AffineTransform at) {
+            this.p = path;
+            this.t = at;
+        }
+
+        public int getWindingRule() {
+            return p.getWindingRule();
+        }
+
+        public boolean isDone() {
+            return typeIndex >= p.typeSize;
+        }
+
+        public void next() {
+            typeIndex++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = p.types[typeIndex];
+            int count = GeneralPath.pointShift[type];
+            for (int i = 0; i < count; i++) {
+                coords[i] = p.points[pointIndex + i];
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count / 2);
+            }
+            pointIndex += count;
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = p.types[typeIndex];
+            int count = GeneralPath.pointShift[type];
+            System.arraycopy(p.points, pointIndex, coords, 0, count);
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count / 2);
+            }
+            pointIndex += count;
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new general path with the winding rule set 
+     * to {@link PathIterator#WIND_NON_ZERO} and the initial capacity
+     * (number of segments) set to the default value 10.
+     */
+    public GeneralPath() {
+        this(WIND_NON_ZERO, BUFFER_SIZE);
+    }
+
+    /**
+     * Instantiates a new general path with the given winding rule
+     *  and the initial capacity (number of segments) set to the 
+     *  default value 10.
+     * 
+     * @param rule the winding rule, either {@link PathIterator#WIND_EVEN_ODD}
+     * or {@link PathIterator#WIND_NON_ZERO}
+     */
+    public GeneralPath(int rule) {
+        this(rule, BUFFER_SIZE);
+    }
+
+    /**
+     * Instantiates a new general path with the given winding rule
+     * and initial capacity (number of segments).
+     * 
+     * @param rule the winding rule, either {@link PathIterator#WIND_EVEN_ODD}
+     * or {@link PathIterator#WIND_NON_ZERO}
+     * @param initialCapacity the number of segments the path is set to hold
+     */
+    public GeneralPath(int rule, int initialCapacity) {
+        setWindingRule(rule);
+        types = new byte[initialCapacity];
+        points = new float[initialCapacity * 2];
+    }
+
+    /**
+     * Creates a new GeneralPath from the outline of the given shape.
+     * 
+     * @param shape the shape
+     */
+    public GeneralPath(Shape shape) {
+        this(WIND_NON_ZERO, BUFFER_SIZE);
+        PathIterator p = shape.getPathIterator(null);
+        setWindingRule(p.getWindingRule());
+        append(p, false);
+    }
+
+    /**
+     * Sets the winding rule, which determines how to decide whether 
+     * a point that isn't on the path itself is inside or outside of 
+     * the shape.
+     * 
+     * @param rule the new winding rule
+     * 
+     * @throws IllegalArgumentException if the winding rule is neither
+     * {@link PathIterator#WIND_EVEN_ODD} nor {@link PathIterator#WIND_NON_ZERO}.
+     */
+    public void setWindingRule(int rule) {
+        if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
+            // awt.209=Invalid winding rule value
+            throw new java.lang.IllegalArgumentException(Messages.getString("awt.209")); //$NON-NLS-1$
+        }
+        this.rule = rule;
+    }
+
+    /**
+     * Gets the winding rule.
+     * 
+     * @return the winding rule, either {@link PathIterator#WIND_EVEN_ODD}
+     * or {@link PathIterator#WIND_NON_ZERO}
+     */
+    public int getWindingRule() {
+        return rule;
+    }
+
+    /**
+     * Checks the point data buffer sizes to see whether pointCount additional
+     * point-data elements can fit. (Note that the number of point data 
+     * elements to add is more than one per point -- it depends on the type 
+     * of point being added.) Reallocates the buffers to enlarge the size if necessary.
+     * 
+     * @param pointCount - the number of point data elements to be added
+     * @param checkMove whether to check for existing points
+     * 
+     * @throws IllegalPathStateException checkMove is true and the 
+     * path is currently empty.
+     */
+    void checkBuf(int pointCount, boolean checkMove) {
+        if (checkMove && typeSize == 0) {
+            // awt.20A=First segment should be SEG_MOVETO type
+            throw new IllegalPathStateException(Messages.getString("awt.20A")); //$NON-NLS-1$
+        }
+        if (typeSize == types.length) {
+            byte tmp[] = new byte[typeSize + BUFFER_CAPACITY];
+            System.arraycopy(types, 0, tmp, 0, typeSize);
+            types = tmp;
+        }
+        if (pointSize + pointCount > points.length) {
+            float tmp[] = new float[pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
+            System.arraycopy(points, 0, tmp, 0, pointSize);
+            points = tmp;
+        }
+    }
+
+    /**
+     * Appends a new point to the end of this general path, disconnected
+     * from the existing path.
+     * 
+     * @param x the x coordinate of the next point to append
+     * @param y the y coordinate of the next point to append
+     */
+    public void moveTo(float x, float y) {
+        if (typeSize > 0 && types[typeSize - 1] == PathIterator.SEG_MOVETO) {
+            points[pointSize - 2] = x;
+            points[pointSize - 1] = y;
+        } else {
+            checkBuf(2, false);
+            types[typeSize++] = PathIterator.SEG_MOVETO;
+            points[pointSize++] = x;
+            points[pointSize++] = y;
+        }
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making 
+     * a straight line segment from the current endpoint to the 
+     * given new point.
+     * 
+     * @param x the x coordinate of the next point to append
+     * @param y the y coordinate of the next point to append
+     */
+    public void lineTo(float x, float y) {
+        checkBuf(2, true);
+        types[typeSize++] = PathIterator.SEG_LINETO;
+        points[pointSize++] = x;
+        points[pointSize++] = y;
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making 
+     * a quadratic curve from the current endpoint to the point (x2, y2)
+     * using the point (x1, y1) as the quadratic curve's control point.
+     * 
+     * @param x1 the x coordinate of the quadratic curve's control point
+     * @param y1 the y coordinate of the quadratic curve's control point
+     * @param x2 the x coordinate of the quadratic curve's end point
+     * @param y2 the y coordinate of the quadratic curve's end point
+     */
+    public void quadTo(float x1, float y1, float x2, float y2) {
+        checkBuf(4, true);
+        types[typeSize++] = PathIterator.SEG_QUADTO;
+        points[pointSize++] = x1;
+        points[pointSize++] = y1;
+        points[pointSize++] = x2;
+        points[pointSize++] = y2;
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making 
+     * a cubic curve from the current endpoint to the point (x3, y3)
+     * using (x1, y1) and (x2, y2) as control points.
+     * 
+     * @see java.awt.geom.CubicCurve2D
+     * 
+     * @param x1 the x coordinate of the new cubic segment's first control point
+     * @param y1 the y coordinate of the new cubic segment's first control point
+     * @param x2 the x coordinate of the new cubic segment's second control point
+     * @param y2 the y coordinate of the new cubic segment's second control point
+     * @param x3 the x coordinate of the new cubic segment's end point
+     * @param y3 the y coordinate of the new cubic segment's end point
+     */
+    public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) {
+        checkBuf(6, true);
+        types[typeSize++] = PathIterator.SEG_CUBICTO;
+        points[pointSize++] = x1;
+        points[pointSize++] = y1;
+        points[pointSize++] = x2;
+        points[pointSize++] = y2;
+        points[pointSize++] = x3;
+        points[pointSize++] = y3;
+    }
+
+    /**
+     * Appends the type information to declare that the current
+     * endpoint closes the curve.
+     */
+    public void closePath() {
+        if (typeSize == 0 || types[typeSize - 1] != PathIterator.SEG_CLOSE) {
+            checkBuf(0, true);
+            types[typeSize++] = PathIterator.SEG_CLOSE;
+        }
+    }
+
+    /**
+     * Appends the outline of the specified shape onto the end 
+     * of this GeneralPath.
+     * 
+     * @param shape the shape whose outline is to be appended
+     * @param connect true to connect this path's current 
+     * endpoint to the first point of the shape's outline or 
+     * false to append the shape's outline without connecting it
+     * 
+     * @throws NullPointerException if the shape parameter is null
+     */
+    public void append(Shape shape, boolean connect) {
+        PathIterator p = shape.getPathIterator(null);
+        append(p, connect);
+    }
+
+    /**
+     * Appends the path defined by the specified PathIterator onto the end 
+     * of this GeneralPath.
+     * 
+     * @param path the PathIterator that defines the new path to append
+     * @param connect true to connect this path's current 
+     * endpoint to the first point of the shape's outline or 
+     * false to append the shape's outline without connecting it
+     */
+    public void append(PathIterator path, boolean connect) {
+        while (!path.isDone()) {
+            float coords[] = new float[6];
+            switch (path.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (!connect || typeSize == 0) {
+                    moveTo(coords[0], coords[1]);
+                    break;
+                }
+                if (types[typeSize - 1] != PathIterator.SEG_CLOSE &&
+                    points[pointSize - 2] == coords[0] &&
+                    points[pointSize - 1] == coords[1])
+                {
+                    break;
+                }
+            // NO BREAK;
+            case PathIterator.SEG_LINETO:
+                lineTo(coords[0], coords[1]);
+                break;
+            case PathIterator.SEG_QUADTO:
+                quadTo(coords[0], coords[1], coords[2], coords[3]);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
+                break;
+            case PathIterator.SEG_CLOSE:
+                closePath();
+                break;
+            }
+            path.next();
+            connect = false;
+        }
+    }
+
+    /**
+     * Gets the current end point of the path.
+     * 
+     * @return the current end point of the path
+     */
+    public Point2D getCurrentPoint() {
+        if (typeSize == 0) {
+            return null;
+        }
+        int j = pointSize - 2;
+        if (types[typeSize - 1] == PathIterator.SEG_CLOSE) {
+
+            for (int i = typeSize - 2; i > 0; i--) {
+                int type = types[i];
+                if (type == PathIterator.SEG_MOVETO) {
+                    break;
+                }
+                j -= pointShift[type];
+            }
+        }
+        return new Point2D.Float(points[j], points[j + 1]);
+    }
+
+    /**
+     * Resets the GeneralPath to being an empty path. The underlying
+     * point and segment data is not deleted but rather the end indices
+     * of the data arrays are set to zero.
+     */
+    public void reset() {
+        typeSize = 0;
+        pointSize = 0;
+    }
+
+    /**
+     * Transform all of the coordinates of this path according to the
+     * specified AffineTransform.
+     * 
+     * @param t the AffineTransform
+     */
+    public void transform(AffineTransform t) {
+        t.transform(points, 0, points, 0, pointSize / 2);
+    }
+
+    /**
+     * Creates a new GeneralPath whose data is given by this path's 
+     * data transformed according to the specified AffineTransform.
+     * 
+     * @param t the AffineTransform
+     * 
+     * @return the new GeneralPath whose data is given by this path's 
+     * data transformed according to the specified AffineTransform
+     */
+    public Shape createTransformedShape(AffineTransform t) {
+        GeneralPath p = (GeneralPath)clone();
+        if (t != null) {
+            p.transform(t);
+        }
+        return p;
+    }
+
+    public Rectangle2D getBounds2D() {
+        float rx1, ry1, rx2, ry2;
+        if (pointSize == 0) {
+            rx1 = ry1 = rx2 = ry2 = 0.0f;
+        } else {
+            int i = pointSize - 1;
+            ry1 = ry2 = points[i--];
+            rx1 = rx2 = points[i--];
+            while (i > 0) {
+                float y = points[i--];
+                float x = points[i--];
+                if (x < rx1) {
+                    rx1 = x;
+                } else
+                    if (x > rx2) {
+                        rx2 = x;
+                    }
+                if (y < ry1) {
+                    ry1 = y;
+                } else
+                    if (y > ry2) {
+                        ry2 = y;
+                    }
+            }
+        }
+        return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    /**
+     * Checks the cross count (number of times a ray from the point 
+     * crosses the shape's boundary) to determine whether the number 
+     * of crossings corresponds to a point inside the shape or not
+     * (according to the shape's path rule).
+     * 
+     * @param cross - the point's cross count
+     * 
+     * @return true if the point is inside the path, or false otherwise
+     */
+    boolean isInside(int cross) {
+        if (rule == WIND_NON_ZERO) {
+            return Crossing.isInsideNonZero(cross);
+        }
+        return Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(double px, double py) {
+        return isInside(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && isInside(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || isInside(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            GeneralPath p = (GeneralPath) super.clone();
+            p.types = types.clone();
+            p.points = points.clone();
+            return p;
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/geom/IllegalPathStateException.java b/awt/java/awt/geom/IllegalPathStateException.java
new file mode 100644
index 0000000..7f459e7
--- /dev/null
+++ b/awt/java/awt/geom/IllegalPathStateException.java
@@ -0,0 +1,50 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Class IllegalPathStateException indicates errors where the 
+ * current state of a path object is imcompatible with the desired 
+ * action, such as performing non-trivial actions on an empty path.
+ */
+public class IllegalPathStateException extends RuntimeException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -5158084205220481094L;
+
+    /**
+     * Instantiates a new illegal path state exception.
+     */
+    public IllegalPathStateException() {
+    }
+
+    /**
+     * Instantiates a new illegal path state exception with the 
+     * specified detail message.
+     * 
+     * @param s the details of the error
+     */
+    public IllegalPathStateException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Line2D.java b/awt/java/awt/geom/Line2D.java
new file mode 100644
index 0000000..a53c470
--- /dev/null
+++ b/awt/java/awt/geom/Line2D.java
@@ -0,0 +1,871 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Line2D represents a line whose data is given in 
+ * high-precision values appropriate for graphical operations.
+ */
+public abstract class Line2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of Line2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends Line2D {
+
+        /** The x coordinate of the starting point. */
+        public float x1;
+        
+        /** The y coordinate of the starting point. */
+        public float y1;
+        
+        /** The x coordinate of the end point. */
+        public float x2;
+        
+        /** The y coordinate of the end point. */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued Line2D with
+         * its data values set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Float(float x1, float y1, float x2, float y2) {
+            setLine(x1, y1, x2, y2);
+        }
+
+        /**
+         * Instantiates a new float-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param p1 the starting point
+         * @param p2 the end point
+         */
+        public Float(Point2D p1, Point2D p2) {
+            setLine(p1, p2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setLine(double x1, double y1, double x2, double y2) {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values that define the line.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public void setLine(float x1, float y1, float x2, float y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx, ry, rw, rh;
+            if (x1 < x2) {
+                rx = x1;
+                rw = x2 - x1;
+            } else {
+                rx = x2;
+                rw = x1 - x2;
+            }
+            if (y1 < y2) {
+                ry = y1;
+                rh = y2 - y1;
+            } else {
+                ry = y2;
+                rh = y1 - y2;
+            }
+            return new Rectangle2D.Float(rx, ry, rw, rh);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Line2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends Line2D {
+
+        /** The x coordinate of the starting point. */
+        public double x1;
+        
+        /** The y coordinate of the starting point. */
+        public double y1;
+        
+        /** The x coordinate of the end point. */
+        public double x2;
+        
+        /** The y coordinate of the end point. */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued  Line2D with
+         * its data values set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Double(double x1, double y1, double x2, double y2) {
+            setLine(x1, y1, x2, y2);
+        }
+
+        /**
+         * Instantiates a new double-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param p1 the starting point
+         * @param p2 the end point
+         */
+        public Double(Point2D p1, Point2D p2) {
+            setLine(p1, p2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setLine(double x1, double y1, double x2, double y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx, ry, rw, rh;
+            if (x1 < x2) {
+                rx = x1;
+                rw = x2 - x1;
+            } else {
+                rx = x2;
+                rw = x1 - x2;
+            }
+            if (y1 < y2) {
+                ry = y1;
+                rh = y2 - y1;
+            } else {
+                ry = y2;
+                rh = y1 - y2;
+            }
+            return new Rectangle2D.Double(rx, ry, rw, rh);
+        }
+    }
+
+    /*
+     * Line2D path iterator 
+     */
+    /**
+     * The subclass of PathIterator to traverse a Line2D.
+     */
+    class Iterator implements PathIterator {
+
+        /** The x coordinate of the start line point. */
+        double x1;
+        
+        /** The y coordinate of the start line point. */
+        double y1;
+        
+        /** The x coordinate of the end line point. */
+        double x2;
+        
+        /** The y coordinate of the end line point. */
+        double y2;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new Line2D.Iterator for given line and transformation
+         * 
+         * @param l - the source Line2D object
+         * @param at - the AffineTransform object to apply rectangle path
+         */
+        Iterator(Line2D l, AffineTransform at) {
+            this.x1 = l.getX1();
+            this.y1 = l.getY1();
+            this.x2 = l.getX2();
+            this.y2 = l.getY2();
+            this.t = at;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 1;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = x1;
+                coords[1] = y1;
+            } else {
+                type = SEG_LINETO;
+                coords[0] = x2;
+                coords[1] = y2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)x1;
+                coords[1] = (float)y1;
+            } else {
+                type = SEG_LINETO;
+                coords[0] = (float)x2;
+                coords[1] = (float)y2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new Line2D.
+     */
+    protected Line2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x2
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the p the starting point.
+     * 
+     * @return the p the starting point
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the p end point.
+     * 
+     * @return the p end point
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the line's endpoints.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     */
+    public abstract void setLine(double x1, double y1, double x2, double y2);
+
+    /**
+     * Sets the line's endpoints.
+     * 
+     * @param p1 the starting point
+     * @param p2 the end point
+     */
+    public void setLine(Point2D p1, Point2D p2) {
+        setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the line's endpoints by copying the data from another Line2D.
+     * 
+     * @param line the Line2D to copy the endpoint data from
+     */
+    public void setLine(Line2D line) {
+        setLine(line.getX1(), line.getY1(), line.getX2(), line.getY2());
+    }
+
+    public Rectangle getBounds() {
+    return getBounds2D().getBounds();
+    }
+
+    /**
+     * Tells where the point is with respect to the line segment, 
+     * given the orientation of the line segment. If the ray 
+     * found by extending the line segment from its starting point 
+     * is rotated, this method tells whether the ray
+     * should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the 
+     * point is on the line segment, it's 1 if the point is on the ray 
+     * or if the ray should rotate in a counter-clockwise direction to get to the
+     * point, and it's -1 if the ray should rotate in a clockwise 
+     * direction to get to the point or if the point is on the line 
+     * determined by the line segment but not on the ray from the 
+     * segment's starting point and through its end point.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the p coordinate of the test point
+     * 
+     * @return the value that describes where the point is with respect to the line segment, 
+     * given the orientation of the line segment
+     */
+    public static int relativeCCW(double x1, double y1, double x2, double y2, double px, double py) {
+        /*
+         * A = (x2-x1, y2-y1) P = (px-x1, py-y1)
+         */
+        x2 -= x1;
+        y2 -= y1;
+        px -= x1;
+        py -= y1;
+        double t = px * y2 - py * x2; // PxA
+        if (t == 0.0) {
+            t = px * x2 + py * y2; // P*A
+            if (t > 0.0) {
+                px -= x2; // B-A
+                py -= y2;
+                t = px * x2 + py * y2; // (P-A)*A
+                if (t < 0.0) {
+                    t = 0.0;
+                }
+            }
+        }
+
+        return t < 0.0 ? -1 : (t > 0.0 ? 1 : 0);
+    }
+
+    /**
+     * Tells where the point is with respect to this line segment, 
+     * given the orientation of this line segment. If the ray 
+     * found by extending the line segment from its starting point 
+     * is rotated, this method tells whether the ray
+     * should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the 
+     * point is on the line segment, it's 1 if the point is on the ray 
+     * or if the ray should rotate in a counter-clockwise direction to get to the
+     * point, and it's -1 if the ray should rotate in a clockwise 
+     * direction to get to the point or if the point is on the line 
+     * determined by the line segment but not on the ray from the 
+     * segment's starting point and through its end point.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the p coordinate of the test point
+     * 
+     * @return the value that describes where the point is with respect to 
+     * this line segment, given the orientation of this line segment
+     */
+    public int relativeCCW(double px, double py) {
+        return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Tells where the point is with respect to this line segment, 
+     * given the orientation of this line segment. If the ray 
+     * found by extending the line segment from its starting point 
+     * is rotated, this method tells whether the ray
+     * should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the 
+     * point is on the line segment, it's 1 if the point is on the ray 
+     * or if the ray should rotate in a counter-clockwise direction to get to the
+     * point, and it's -1 if the ray should rotate in a clockwise 
+     * direction to get to the point or if the point is on the line 
+     * determined by the line segment but not on the ray from the 
+     * segment's starting point and through its end point.
+     * 
+     * @param p the test point
+     * 
+     * @return the value that describes where the point is with respect to 
+     * this line segment, given the orientation of this line segment
+     */
+    public int relativeCCW(Point2D p) {
+        return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Tells whether the two line segments cross.
+     * 
+     * @param x1 the x coordinate of the starting point of the first segment
+     * @param y1 the y coordinate of the starting point of the first segment
+     * @param x2 the x coordinate of the end point of the first segment
+     * @param y2 the y coordinate of the end point of the first segment
+     * @param x3 the x coordinate of the starting point of the second segment
+     * @param y3 the y coordinate of the starting point of the second segment
+     * @param x4 the x coordinate of the end point of the second segment
+     * @param y4 the y coordinate of the end point of the second segment
+     * 
+     * @return true, if the two line segments cross
+     */
+    public static boolean linesIntersect(double x1, double y1, double x2,
+            double y2, double x3, double y3, double x4, double y4)
+    {
+        /*
+         * A = (x2-x1, y2-y1) B = (x3-x1, y3-y1) C = (x4-x1, y4-y1) D = (x4-x3,
+         * y4-y3) = C-B E = (x1-x3, y1-y3) = -B F = (x2-x3, y2-y3) = A-B
+         *
+         * Result is ((AxB) * (AxC) <=0) and ((DxE) * (DxF) <= 0)
+         *
+         * DxE = (C-B)x(-B) = BxB-CxB = BxC DxF = (C-B)x(A-B) = CxA-CxB-BxA+BxB =
+         * AxB+BxC-AxC
+         */
+
+        x2 -= x1; // A
+        y2 -= y1;
+        x3 -= x1; // B
+        y3 -= y1;
+        x4 -= x1; // C
+        y4 -= y1;
+
+        double AvB = x2 * y3 - x3 * y2;
+        double AvC = x2 * y4 - x4 * y2;
+
+        // Online
+        if (AvB == 0.0 && AvC == 0.0) {
+            if (x2 != 0.0) {
+                return
+                    (x4 * x3 <= 0.0) ||
+                    ((x3 * x2 >= 0.0) &&
+                     (x2 > 0.0 ? x3 <= x2 || x4 <= x2 : x3 >= x2 || x4 >= x2));
+            }
+            if (y2 != 0.0) {
+                return
+                    (y4 * y3 <= 0.0) ||
+                    ((y3 * y2 >= 0.0) &&
+                     (y2 > 0.0 ? y3 <= y2 || y4 <= y2 : y3 >= y2 || y4 >= y2));
+            }
+            return false;
+        }
+
+        double BvC = x3 * y4 - x4 * y3;
+
+        return (AvB * AvC <= 0.0) && (BvC * (AvB + BvC - AvC) <= 0.0);
+    }
+
+    /**
+     * Tells whether the specified line segments crosses this line segment.
+     * 
+     * @param x1 the x coordinate of the starting point of the test segment
+     * @param y1 the y coordinate of the starting point of the test segment
+     * @param x2 the x coordinate of the end point of the test segment
+     * @param y2 the y coordinate of the end point of the test segment
+     * 
+     * @return true, if the specified line segments crosses this line segment
+     */
+    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
+        return linesIntersect(x1, y1, x2, y2, getX1(), getY1(), getX2(), getY2());
+    }
+
+    /**
+     * Tells whether the specified line segments crosses this line segment.
+     * 
+     * @param l the test segment
+     * 
+     * @return true, if the specified line segments crosses this line segment
+     * 
+     * @throws NullPointerException if l is null
+     */
+    public boolean intersectsLine(Line2D l) {
+        return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(), getX1(), getY1(), getX2(), getY2());
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line segment.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the the square of the distance between the point and the 
+     * line segment
+     */
+    public static double ptSegDistSq(double x1, double y1, double x2, double y2, double px, double py) {
+        /*
+         * A = (x2 - x1, y2 - y1) P = (px - x1, py - y1)
+         */
+        x2 -= x1; // A = (x2, y2)
+        y2 -= y1;
+        px -= x1; // P = (px, py)
+        py -= y1;
+        double dist;
+        if (px * x2 + py * y2 <= 0.0) { // P*A
+            dist = px * px + py * py;
+        } else {
+            px = x2 - px; // P = A - P = (x2 - px, y2 - py)
+            py = y2 - py;
+            if (px * x2 + py * y2 <= 0.0) { // P*A
+                dist = px * px + py * py;
+            } else {
+                dist = px * y2 - py * x2;
+                dist = dist * dist / (x2 * x2 + y2 * y2); // pxA/|A|
+            }
+        }
+        if (dist < 0) {
+            dist = 0;
+        }
+        return dist;
+    }
+
+    /**
+     * Gives the distance between the point and the 
+     * line segment.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the the distance between the point and the 
+     * line segment
+     */
+    public static double ptSegDist(double x1, double y1, double x2, double y2, double px, double py) {
+        return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
+    }
+
+    /**
+     * Gives the square of the distance between the point and this 
+     * line segment.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the the square of the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDistSq(double px, double py) {
+        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the square of the distance between the point and this 
+     * line segment.
+     * 
+     * @param p the test point
+     * 
+     * @return the square of the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDistSq(Point2D p) {
+        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the distance between the point and this 
+     * line segment.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDist(double px, double py) {
+        return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the distance between the point and this 
+     * line segment.
+     * 
+     * @param p the test point
+     * 
+     * @return the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDist(Point2D p) {
+        return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line
+     */
+    public static double ptLineDistSq(double x1, double y1, double x2, double y2, double px, double py) {
+        x2 -= x1;
+        y2 -= y1;
+        px -= x1;
+        py -= y1;
+        double s = px * y2 - py * x2;
+        return s * s / (x2 * x2 + y2 * y2);
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line
+     */
+    public static double ptLineDist(double x1, double y1, double x2, double y2, double px, double py) {
+        return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDistSq(double px, double py) {
+        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param p the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDistSq(Point2D p) {
+        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDist(double px, double py) {
+        return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param p the test point
+     * 
+     * @return the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDist(Point2D p) {
+        return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    public boolean contains(double px, double py) {
+        return false;
+    }
+
+    public boolean contains(Point2D p) {
+        return false;
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return false;
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        return false;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        return intersects(new Rectangle2D.Double(rx, ry, rw, rh));
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return new Iterator(this, at);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
diff --git a/awt/java/awt/geom/NoninvertibleTransformException.java b/awt/java/awt/geom/NoninvertibleTransformException.java
new file mode 100644
index 0000000..2b7b542
--- /dev/null
+++ b/awt/java/awt/geom/NoninvertibleTransformException.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Class NoninvertibleTransformException is the exception that is thrown 
+ * when an action requires inverting an {@link AffineTransform} that is 
+ * not invertible (has determinant 0).
+ */
+public class NoninvertibleTransformException extends java.lang.Exception {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 6137225240503990466L;
+
+    /**
+     * Instantiates a new noninvertible transform exception.
+     * 
+     * @param s the error message
+     */
+    public NoninvertibleTransformException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/PathIterator.java b/awt/java/awt/geom/PathIterator.java
new file mode 100644
index 0000000..5a98083
--- /dev/null
+++ b/awt/java/awt/geom/PathIterator.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Interface PathIterator represents an iterator object that can 
+ * be used to traverse the outline of a {@link java.awt.Shape}. 
+ * It returns points along the boundary of the Shape 
+ * which may be actual vertices (in the case of a shape made of line 
+ * segments) or may be points on a curved segment with the distance 
+ * between the points determined by a chosen flattening factor. 
+ * <p>
+ * If the shape is closed, the outline is traversed in the counter-clockwise 
+ * direction. That means that moving forward along the boundary is to travel 
+ * in such a way that the interior of the shape is to the left of the 
+ * outline path and the exterior of the shape is to the right of the outline
+ * path. The interior and exterior of the shape are determined by a 
+ * winding rule. 
+ */
+public interface PathIterator {
+
+    /** The Constant WIND_EVEN_ODD indicates the winding rule that says 
+     * that a point is outside the shape if any infinite ray from the point 
+     * crosses the outline of the shape an even number of times, otherwise
+     * it is inside. */
+    public static final int WIND_EVEN_ODD = 0;
+    
+    /** The Constant WIND_NON_ZERO indicates the winding rule that says that
+     * a point is inside the shape if every infinite ray starting from that
+     * point crosses the outline of the shape a non-zero number of times. */
+    public static final int WIND_NON_ZERO = 1;
+
+    /** The Constant SEG_MOVETO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should be placed directly on the current point. */
+    public static final int SEG_MOVETO  = 0;
+    
+    /** The Constant SEG_LINETO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should follow a straight line. */
+    public static final int SEG_LINETO  = 1;
+    
+    /** The Constant SEG_QUADTO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should follow a quadratic curve. */
+    public static final int SEG_QUADTO  = 2;
+    
+    /** The Constant SEG_CUBICTO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should follow a cubic curve. */
+    public static final int SEG_CUBICTO = 3;
+    
+    /** The Constant SEG_CLOSE indicates that the previous point was the end
+     * of the shape's outline. */
+    public static final int SEG_CLOSE   = 4;
+
+    /**
+     * Gets the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
+     * {@link PathIterator#WIND_NON_ZERO}.
+     * 
+     * @return the winding rule
+     */
+    public int getWindingRule();
+
+    /**
+     * Checks if this PathIterator has been completely traversed.
+     * 
+     * @return true, if this PathIterator has been completely traversed
+     */
+    public boolean isDone();
+
+    /**
+     * Tells this PathIterator to skip to the next segment.
+     */
+    public void next();
+
+    /**
+     * Gets the coordinates of the next vertex point along the shape's outline 
+     * and a flag that indicates what kind of segment to use in order to 
+     * connect the previous vertex point to the current vertex point to form 
+     * the current segment.
+     * 
+     * @param coords the array that the coordinates of the end point of the current 
+     * segment are written into.
+     * 
+     * @return the flag that indicates how to follow the shape's outline
+     * from the previous point to the current one, chosen from 
+     * the following constants:
+     * {@link PathIterator#SEG_MOVETO}, {@link PathIterator#SEG_LINETO}, 
+     * {@link PathIterator#SEG_QUADTO}, {@link PathIterator#SEG_CUBICTO}, 
+     * or {@link PathIterator#SEG_CLOSE}
+     */
+    public int currentSegment(float[] coords);
+
+    /**
+     * Gets the coordinates of the next vertex point along the shape's outline 
+     * and a flag that indicates what kind of segment to use in order to 
+     * connect the previous vertex point to the current vertex point to form 
+     * the current segment.
+     * 
+     * @param coords the array that the coordinates of the end point of the current 
+     * segment are written into.
+     * 
+     * @return the flag that indicates how to follow the shape's outline
+     * from the previous point to the current one, chosen from 
+     * the following constants:
+     * {@link PathIterator#SEG_MOVETO}, {@link PathIterator#SEG_LINETO}, 
+     * {@link PathIterator#SEG_QUADTO}, {@link PathIterator#SEG_CUBICTO}, 
+     * or {@link PathIterator#SEG_CLOSE}
+     */
+    public int currentSegment(double[] coords);
+
+}
+
diff --git a/awt/java/awt/geom/Point2D.java b/awt/java/awt/geom/Point2D.java
new file mode 100644
index 0000000..7719e67
--- /dev/null
+++ b/awt/java/awt/geom/Point2D.java
@@ -0,0 +1,288 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class Point2D represents a point whose data is given in 
+ * high-precision values appropriate for graphical operations.
+ */
+public abstract class Point2D implements Cloneable {
+
+    /**
+     * The Class Float is the subclass of Point2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends Point2D {
+
+        /** The x coordinate. */
+        public float x;
+        
+        /** The y coordinate. */
+        public float y;
+
+        /**
+         * Instantiates a new float-valued Point2D with its data 
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Point2D with the specified coordinates.
+         * 
+         * @param x the x coordinate
+         * @param y the y coordinate
+         */
+        public Float(float x, float y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        /**
+         * Sets the point's coordinates.
+         * 
+         * @param x the x coordinate
+         * @param y the y coordinate
+         */
+        public void setLocation(float x, float y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void setLocation(double x, double y) {
+            this.x = (float)x;
+            this.y = (float)y;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Point2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends Point2D {
+
+        /** The x coordinate. */
+        public double x;
+        
+        /** The y coordinate. */
+        public double y;
+
+        /**
+         * Instantiates a new double-valued Point2D with its data 
+         * set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Point2D with the specified coordinates.
+         * 
+         * @param x the x coordinate
+         * @param y the y coordinate
+         */
+        public Double(double x, double y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public void setLocation(double x, double y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+
+    /**
+     * Instantiates a new Point2D.
+     */
+    protected Point2D() {
+    }
+
+    /**
+     * Gets the x coordinate.
+     * 
+     * @return the x coordinate
+     */
+    public abstract double getX();
+
+    /**
+     * Gets the y coordinate.
+     * 
+     * @return the y coordinate
+     */
+    public abstract double getY();
+
+    /**
+     * Sets the point's coordinates.
+     * 
+     * @param x the x coordinate
+     * @param y the y coordinate
+     */
+    public abstract void setLocation(double x, double y);
+
+    /**
+     * Sets the point's coordinates by copying them from another point.
+     * 
+     * @param p the point to copy the data from
+     */
+    public void setLocation(Point2D p) {
+        setLocation(p.getX(), p.getY());
+    }
+
+    /**
+     * Finds the square of the distance between the two specified points.
+     * 
+     * @param x1 the x coordinate of the first point
+     * @param y1 the y coordinate of the first point
+     * @param x2 the x coordinate of the second point
+     * @param y2 the y coordinate of the second point
+     * 
+     * @return the square of the distance between the two specified points
+     */
+    public static double distanceSq(double x1, double y1, double x2, double y2) {
+        x2 -= x1;
+        y2 -= y1;
+        return x2 * x2 + y2 * y2;
+    }
+
+    /**
+     * Finds the square of the distance between this point and the specified point.
+     * 
+     * @param px the x coordinate of the point
+     * @param py the y coordinate of the point
+     * 
+     * @return the square of the distance between this point and the specified point
+     */
+    public double distanceSq(double px, double py) {
+        return Point2D.distanceSq(getX(), getY(), px, py);
+    }
+
+    /**
+     * Finds the square of the distance between this point and the specified point.
+     * 
+     * @param p the other point
+     * 
+     * @return the square of the distance between this point and the specified point
+     */
+    public double distanceSq(Point2D p) {
+        return Point2D.distanceSq(getX(), getY(), p.getX(), p.getY());
+    }
+
+    /**
+     * Finds the distance between the two specified points.
+     * 
+     * @param x1 the x coordinate of the first point
+     * @param y1 the y coordinate of the first point
+     * @param x2 the x coordinate of the second point
+     * @param y2 the y coordinate of the second point
+     * 
+     * @return the distance between the two specified points
+     */
+    public static double distance(double x1, double y1, double x2, double y2) {
+        return Math.sqrt(distanceSq(x1, y1, x2, y2));
+    }
+
+    /**
+     * Finds the distance between this point and the specified point.
+     * 
+     * @param px the x coordinate of the point
+     * @param py the y coordinate of the point
+     * 
+     * @return the distance between this point and the specified point
+     */
+    public double distance(double px, double py) {
+        return Math.sqrt(distanceSq(px, py));
+    }
+
+    /**
+     * Finds the distance between this point and the specified point.
+     * 
+     * @param p the other point
+     * 
+     * @return the distance between this point and the specified point
+     */
+    public double distance(Point2D p) {
+        return Math.sqrt(distanceSq(p));
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(getX());
+        hash.append(getY());
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Point2D) {
+            Point2D p = (Point2D) obj;
+            return getX() == p.getX() && getY() == p.getY();
+        }
+        return false;
+    }
+}
+
diff --git a/awt/java/awt/geom/QuadCurve2D.java b/awt/java/awt/geom/QuadCurve2D.java
new file mode 100644
index 0000000..64ea6d6
--- /dev/null
+++ b/awt/java/awt/geom/QuadCurve2D.java
@@ -0,0 +1,824 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class QuadCurve2D is a Shape that represents a segment of a 
+ * quadratic (Bezier) curve. The curved segment is determined by three points:
+ * a start point, an end point, and a control point.  The line from the control 
+ * point to the starting point gives the tangent to the curve at the
+ * starting point, and the line from the control point to the end point 
+ * gives the tangent to the curve at the end point.
+ */
+public abstract class QuadCurve2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of QuadCurve2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends QuadCurve2D {
+
+        /** The x coordinate of the starting point of the curved segment. */
+        public float x1;
+        
+        /** The y coordinate of the starting point of the curved segment. */
+        public float y1;
+        
+        /** The x coordinate of the control point.  */
+        public float ctrlx;
+        
+        /** The y coordinate of the control point. */
+        public float ctrly;
+        
+        /** The x coordinate of the end point of the curved segment. */
+        public float x2;
+        
+        /** The y coordinate of the end point of the curved segment. */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued QuadCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued QuadCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point of the curved segment
+         * @param y1 the y coordinate of the starting point of the curved segment
+         * @param ctrlx the x coordinate of the control point
+         * @param ctrly the y coordinate of the control point
+         * @param x2 the x coordinate of the end point of the curved segment
+         * @param y2 the y coordinate of the end point of the curved segment
+         */
+        public Float(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
+            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX() {
+            return ctrlx;
+        }
+
+        @Override
+        public double getCtrlY() {
+            return ctrly;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlPt() {
+            return new Point2D.Float(ctrlx, ctrly);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.ctrlx = (float)ctrlx;
+            this.ctrly = (float)ctrly;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values of the curve.
+         * 
+         * @param x1 the x coordinate of the starting point of the curved segment
+         * @param y1 the y coordinate of the starting point of the curved segment
+         * @param ctrlx the x coordinate of the control point
+         * @param ctrly the y coordinate of the control point
+         * @param x2 the x coordinate of the end point of the curved segment
+         * @param y2 the y coordinate of the end point of the curved segment
+         */
+        public void setCurve(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx = ctrlx;
+            this.ctrly = ctrly;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx0 = Math.min(Math.min(x1, x2), ctrlx);
+            float ry0 = Math.min(Math.min(y1, y2), ctrly);
+            float rx1 = Math.max(Math.max(x1, x2), ctrlx);
+            float ry1 = Math.max(Math.max(y1, y2), ctrly);
+            return new Rectangle2D.Float(rx0, ry0, rx1 - rx0, ry1 - ry0);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of QuadCurve2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends QuadCurve2D {
+
+        /** The x coordinate of the starting point of the curved segment. */
+        public double x1;
+        
+        /** The y coordinate of the starting point of the curved segment. */
+        public double y1;
+        
+        /** The x coordinate of the control point. */
+        public double ctrlx;
+        
+        /** The y coordinate of the control point. */
+        public double ctrly;
+        
+        /** The x coordinate of the end point of the curved segment. */
+        public double x2;
+        
+        /** The y coordinate of the end point of the curved segment. */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued QuadCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued QuadCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point of the curved segment
+         * @param y1 the y coordinate of the starting point of the curved segment
+         * @param ctrlx the x coordinate of the control point
+         * @param ctrly the y coordinate of the control point
+         * @param x2 the x coordinate of the end point of the curved segment
+         * @param y2 the y coordinate of the end point of the curved segment
+         */
+        public Double(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX() {
+            return ctrlx;
+        }
+
+        @Override
+        public double getCtrlY() {
+            return ctrly;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlPt() {
+            return new Point2D.Double(ctrlx, ctrly);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx = ctrlx;
+            this.ctrly = ctrly;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx0 = Math.min(Math.min(x1, x2), ctrlx);
+            double ry0 = Math.min(Math.min(y1, y2), ctrly);
+            double rx1 = Math.max(Math.max(x1, x2), ctrlx);
+            double ry1 = Math.max(Math.max(y1, y2), ctrly);
+            return new Rectangle2D.Double(rx0, ry0, rx1 - rx0, ry1 - ry0);
+        }
+    }
+
+    /*
+     * QuadCurve2D path iterator 
+     */
+    /**
+     * The PathIterator for a Quad2D curve.
+     */
+    class Iterator implements PathIterator {
+
+        /** The source QuadCurve2D object. */
+        QuadCurve2D c;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segment index. */
+        int index;
+
+        /**
+         * Constructs a new QuadCurve2D.Iterator for given curve and transformation
+         * 
+         * @param q - the source QuadCurve2D object
+         * @param t the AffineTransform that acts on the coordinates before 
+         * returning them (or null)
+         */
+        Iterator(QuadCurve2D q, AffineTransform t) {
+            this.c = q;
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return (index > 1);
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = c.getX1();
+                coords[1] = c.getY1();
+                count = 1;
+            } else {
+                type = SEG_QUADTO;
+                coords[0] = c.getCtrlX();
+                coords[1] = c.getCtrlY();
+                coords[2] = c.getX2();
+                coords[3] = c.getY2();
+                count = 2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)c.getX1();
+                coords[1] = (float)c.getY1();
+                count = 1;
+            } else {
+                type = SEG_QUADTO;
+                coords[0] = (float)c.getCtrlX();
+                coords[1] = (float)c.getCtrlY();
+                coords[2] = (float)c.getX2();
+                coords[3] = (float)c.getY2();
+                count = 2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new quadratic curve.
+     */
+    protected QuadCurve2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the starting point.
+     * 
+     * @return the starting point
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the x coordinate of the control point.
+     * 
+     * @return the x coordinate of the control point
+     */
+    public abstract double getCtrlX();
+
+    /**
+     * Gets the y coordinate of the control point.
+     * 
+     * @return y coordinate of the control point
+     */
+    public abstract double getCtrlY();
+
+    /**
+     * Gets the control point.
+     * 
+     * @return the control point
+     */
+    public abstract Point2D getCtrlPt();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x coordinate of the end point
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the end point.
+     * 
+     * @return the end point
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param x1 the x coordinate of the starting point of the curved segment
+     * @param y1 the y coordinate of the starting point of the curved segment
+     * @param ctrlx the x coordinate of the control point
+     * @param ctrly the y coordinate of the control point
+     * @param x2 the x coordinate of the end point of the curved segment
+     * @param y2 the y coordinate of the end point of the curved segment
+     */
+    public abstract void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2);
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param p1 the starting point of the curved segment
+     * @param cp the control point
+     * @param p2 the end point of the curved segment
+     * 
+     * @throws NullPointerException if any of the three points is null.
+     */
+    public void setCurve(Point2D p1, Point2D cp, Point2D p2) {
+        setCurve(p1.getX(), p1.getY(), cp.getX(), cp.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of values. The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#setCurve(double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of values containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 6.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public void setCurve(double[] coords, int offset) {
+        setCurve(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5]);
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of points. The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#setCurve(Point2D, Point2D, Point2D)}
+     * 
+     * @param points the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + 3.
+     * @throws NullPointerException if the point array is null.
+     */
+    public void setCurve(Point2D[] points, int offset) {
+        setCurve(
+                points[offset + 0].getX(), points[offset + 0].getY(),
+                points[offset + 1].getX(), points[offset + 1].getY(),
+                points[offset + 2].getX(), points[offset + 2].getY());
+    }
+
+    /**
+     * Sets the data of the curve by copying it from another QuadCurve2D.
+     * 
+     * @param curve the curve to copy the data points from
+     * 
+     * @throws NullPointerException if the curve is null.
+     */
+    public void setCurve(QuadCurve2D curve) {
+        setCurve(
+                curve.getX1(), curve.getY1(),
+                curve.getCtrlX(), curve.getCtrlY(),
+                curve.getX2(), curve.getY2());
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * for this curve.
+     * 
+     * @return the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     */
+    public double getFlatnessSq() {
+        return Line2D.ptSegDistSq(
+                getX1(), getY1(),
+                getX2(), getY2(),
+                getCtrlX(), getCtrlY());
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * 
+     * @param x1 the x coordinate of the starting point of the curved segment
+     * @param y1 the y coordinate of the starting point of the curved segment
+     * @param ctrlx the x coordinate of the control point
+     * @param ctrly the y coordinate of the control point
+     * @param x2 the x coordinate of the end point of the curved segment
+     * @param y2 the y coordinate of the end point of the curved segment
+     * 
+     * @return the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     */
+    public static double getFlatnessSq(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+        return Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx, ctrly);
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * by reading the coordinates of the points from an array of values.
+     * The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#getFlatnessSq(double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the coordinates to use for 
+     * the calculation
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 6.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public static double getFlatnessSq(double coords[], int offset) {
+        return Line2D.ptSegDistSq(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 2], coords[offset + 3]);
+    }
+
+    /**
+     * Gets the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * of this QuadCurve2D.
+     * 
+     * @return the the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * of this QuadCurve2D
+     */
+    public double getFlatness() {
+        return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY());
+    }
+
+    /**
+     * Gets the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * 
+     * @param x1 the x coordinate of the starting point of the curved segment
+     * @param y1 the y coordinate of the starting point of the curved segment
+     * @param ctrlx the x coordinate of the control point
+     * @param ctrly the y coordinate of the control point
+     * @param x2 the x coordinate of the end point of the curved segment
+     * @param y2 the y coordinate of the end point of the curved segment
+     * 
+     * @return the the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     */
+    public static double getFlatness(double x1, double y1, double ctrlx,
+            double ctrly, double x2, double y2)
+    {
+        return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly);
+    }
+
+    /**
+     * Gets the the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#getFlatness(double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the coordinates to use for 
+     * the calculation
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 6.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public static double getFlatness(double coords[], int offset) {
+        return Line2D.ptSegDist(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 2], coords[offset + 3]);
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing this
+     * curve in two. The division point is the point on the curve 
+     * that is closest to this curve's control point. The data of 
+     * this curve is left unchanged.
+     * 
+     * @param left the QuadCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the QuadCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if either curve is null.
+     */
+    public void subdivide(QuadCurve2D left, QuadCurve2D right) {
+        subdivide(this, left, right);
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing a source
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the source curve's control point. The data of 
+     * the source curve is left unchanged.
+     * 
+     * @param src the curve that provides the initial data
+     * @param left the QuadCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the QuadCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if one of the curves is null.
+     */
+    public static void subdivide(QuadCurve2D src, QuadCurve2D left, QuadCurve2D right) {
+        double x1 = src.getX1();
+        double y1 = src.getY1();
+        double cx = src.getCtrlX();
+        double cy = src.getCtrlY();
+        double x2 = src.getX2();
+        double y2 = src.getY2();
+        double cx1 = (x1 + cx) / 2.0;
+        double cy1 = (y1 + cy) / 2.0;
+        double cx2 = (x2 + cx) / 2.0;
+        double cy2 = (y2 + cy) / 2.0;
+        cx = (cx1 + cx2) / 2.0;
+        cy = (cy1 + cy2) / 2.0;
+        if (left != null) {
+            left.setCurve(x1, y1, cx1, cy1, cx, cy);
+        }
+        if (right != null) {
+            right.setCurve(cx, cy, cx2, cy2, x2, y2);
+        }
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing a source
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the source curve's control point. The data
+     * for the three curves is read and written from arrays of values in 
+     * the usual order: x1, y1, cx, cy, x2, y2.
+     *  
+     * @param src the array that gives the data values for the source curve
+     * @param srcoff the offset in the src array to read the values from
+     * @param left the array where the coordinates of the start curve should be written
+     * @param leftOff the offset in the left array to start writing the values
+     * @param right the array where the coordinates of the end curve should be written
+     * @param rightOff the offset in the right array to start writing the values
+     * 
+     * @throws ArrayIndexOutOfBoundsException if src.length < srcoff + 6
+     * or if left.length < leftOff + 6 or if right.length < rightOff + 6.
+     * @throws NullPointerException if one of the arrays is null.
+     */
+    public static void subdivide(double src[], int srcoff, double left[],
+            int leftOff, double right[], int rightOff)
+    {
+        double x1 = src[srcoff + 0];
+        double y1 = src[srcoff + 1];
+        double cx = src[srcoff + 2];
+        double cy = src[srcoff + 3];
+        double x2 = src[srcoff + 4];
+        double y2 = src[srcoff + 5];
+        double cx1 = (x1 + cx) / 2.0;
+        double cy1 = (y1 + cy) / 2.0;
+        double cx2 = (x2 + cx) / 2.0;
+        double cy2 = (y2 + cy) / 2.0;
+        cx = (cx1 + cx2) / 2.0;
+        cy = (cy1 + cy2) / 2.0;
+        if (left != null) {
+            left[leftOff + 0] = x1;
+            left[leftOff + 1] = y1;
+            left[leftOff + 2] = cx1;
+            left[leftOff + 3] = cy1;
+            left[leftOff + 4] = cx;
+            left[leftOff + 5] = cy;
+        }
+        if (right != null) {
+            right[rightOff + 0] = cx;
+            right[rightOff + 1] = cy;
+            right[rightOff + 2] = cx2;
+            right[rightOff + 3] = cy2;
+            right[rightOff + 4] = x2;
+            right[rightOff + 5] = y2;
+        }
+    }
+
+    /**
+     * Finds the roots of the quadratic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written back into the array eqn starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been changed by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * quadratic polynomial to solve.
+     * 
+     * @return the number of roots of the quadratic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 3.
+     * @throws NullPointerException if the array is null.
+     */
+    public static int solveQuadratic(double eqn[]) {
+        return solveQuadratic(eqn, eqn);
+    }
+
+    /**
+     * Finds the roots of the quadratic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written into the array res starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been written by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * quadratic polynomial to solve.
+     * @param res the array that this method writes the results into
+     * 
+     * @return the number of roots of the quadratic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 3 or 
+     * if res.length is less than the number of roots.
+     * @throws NullPointerException if either array is null.
+     */
+    public static int solveQuadratic(double eqn[], double res[]) {
+        return Crossing.solveQuad(eqn, res);
+    }
+
+    public boolean contains(double px, double py) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Rectangle2D.java b/awt/java/awt/geom/Rectangle2D.java
new file mode 100644
index 0000000..d33dd91
--- /dev/null
+++ b/awt/java/awt/geom/Rectangle2D.java
@@ -0,0 +1,761 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class Rectangle2D represents a rectangle whose coordinates are given 
+ * with the correct precision to be used with the Graphics2D classes.
+ */
+public abstract class Rectangle2D extends RectangularShape {
+
+    /** The Constant OUT_LEFT is a mask that is used to indicate that a 
+     * given point is outside the rectangle and to its left. */
+    public static final int OUT_LEFT   = 1;
+    
+    /** The Constant OUT_TOP is a mask that is used to indicate that a 
+     * given point is outside the rectangle and above it. */
+    public static final int OUT_TOP    = 2;
+    
+    /** The Constant OUT_RIGHT is a mask that is used to indicate that a 
+     * given point is outside the rectangle and to its right. */
+    public static final int OUT_RIGHT  = 4;
+    
+    /** The Constant OUT_BOTTOM is a mask that is used to indicate that a 
+     * given point is outside the rectangle and above it. */
+    public static final int OUT_BOTTOM = 8;
+
+    /**
+     * The Class Float is the subclass of Rectangle2D that represents a 
+     * rectangle whose data values are given as floats (with float-level
+     * precision).
+     */
+    public static class Float extends Rectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public float x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public float y;
+        
+        /** The width of the rectangle. */
+        public float width;
+        
+        /** The height of the rectangle. */
+        public float height;
+
+        /**
+         * Instantiates a new empty rectangle with float-precision data fields.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new rectangle with the specified float-precision data.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         */
+        public Float(float x, float y, float width, float height) {
+            setRect(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        /**
+         * Sets the rectangle's data to the given values.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         */
+        public void setRect(float x, float y, float width, float height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setRect(double x, double y, double width, double height) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+        }
+
+        @Override
+        public void setRect(Rectangle2D r) {
+            this.x = (float)r.getX();
+            this.y = (float)r.getY();
+            this.width = (float)r.getWidth();
+            this.height = (float)r.getHeight();
+        }
+
+        @Override
+        public int outcode(double px, double py) {
+            int code = 0;
+
+            if (width <= 0.0f) {
+                code |= OUT_LEFT | OUT_RIGHT;
+            } else
+                if (px < x) {
+                    code |= OUT_LEFT;
+                } else
+                    if (px > x + width) {
+                        code |= OUT_RIGHT;
+                    }
+
+            if (height <= 0.0f) {
+                code |= OUT_TOP | OUT_BOTTOM;
+            } else
+                if (py < y) {
+                    code |= OUT_TOP;
+                } else
+                    if (py > y + height) {
+                        code |= OUT_BOTTOM;
+                    }
+
+            return code;
+        }
+
+        @Override
+        public Rectangle2D getBounds2D() {
+            return new Float(x, y, width, height);
+        }
+
+        @Override
+        public Rectangle2D createIntersection(Rectangle2D r) {
+            Rectangle2D dst;
+            if (r instanceof Double) {
+                dst = new Rectangle2D.Double();
+            } else {
+                dst = new Rectangle2D.Float();
+            }
+            Rectangle2D.intersect(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public Rectangle2D createUnion(Rectangle2D r) {
+            Rectangle2D dst;
+            if (r instanceof Double) {
+                dst = new Rectangle2D.Double();
+            } else {
+                dst = new Rectangle2D.Float();
+            }
+            Rectangle2D.union(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public String toString() {
+            // The output format based on 1.5 release behaviour. It could be obtained in the following way
+            // System.out.println(new Rectangle2D.Float().toString())
+            return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Rectangle2D that represents a 
+     * rectangle whose data values are given as doubles (with double-precision-level
+     * precision).
+     */
+    public static class Double extends Rectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public double x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public double y;
+        
+        /** The width of the rectangle. */
+        public double width;
+        
+        /** The height of the rectangle. */
+        public double height;
+
+        /**
+         * Instantiates a new empty rectangle with double-precision data fields.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new rectangle with the given double values.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         */
+        public Double(double x, double y, double width, double height) {
+            setRect(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setRect(double x, double y, double width, double height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setRect(Rectangle2D r) {
+            this.x = r.getX();
+            this.y = r.getY();
+            this.width = r.getWidth();
+            this.height = r.getHeight();
+        }
+
+        @Override
+        public int outcode(double px, double py) {
+            int code = 0;
+
+            if (width <= 0.0) {
+                code |= OUT_LEFT | OUT_RIGHT;
+            } else
+                if (px < x) {
+                    code |= OUT_LEFT;
+                } else
+                    if (px > x + width) {
+                        code |= OUT_RIGHT;
+                    }
+
+            if (height <= 0.0) {
+                code |= OUT_TOP | OUT_BOTTOM;
+            } else
+                if (py < y) {
+                    code |= OUT_TOP;
+                } else
+                    if (py > y + height) {
+                        code |= OUT_BOTTOM;
+                    }
+
+            return code;
+        }
+
+        @Override
+        public Rectangle2D getBounds2D() {
+            return new Double(x, y, width, height);
+        }
+
+        @Override
+        public Rectangle2D createIntersection(Rectangle2D r) {
+            Rectangle2D dst = new Rectangle2D.Double();
+            Rectangle2D.intersect(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public Rectangle2D createUnion(Rectangle2D r) {
+            Rectangle2D dest = new Rectangle2D.Double();
+            Rectangle2D.union(this, r, dest);
+            return dest;
+        }
+
+        @Override
+        public String toString() {
+            // The output format based on 1.5 release behaviour. It could be obtained in the following way
+            // System.out.println(new Rectangle2D.Double().toString())
+            return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    /**
+     * The Class Iterator provides 
+     * access to the coordinates of the Rectangle2D's boundary modified 
+     * by an AffineTransform. 
+     */
+    class Iterator implements PathIterator {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        double x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        double y;
+        
+        
+        /** The width of the rectangle. */
+        double width;
+        
+        /** The height of the rectangle. */
+        double height;
+                
+        /** The AffineTransform that is used to modify the coordinates 
+         * that are returned by the path iterator. */
+        AffineTransform t;
+        
+        /** The current segment index. */
+        int index;
+        
+        /**
+         * Constructs a new Rectangle2D.Iterator for given rectangle and transformation.
+         * 
+         * @param r - the source Rectangle2D object
+         * @param at - the AffineTransform object to apply to the coordinates 
+         * before returning them
+         */
+        Iterator(Rectangle2D r, AffineTransform at) {
+            this.x = r.getX();
+            this.y = r.getY();
+            this.width = r.getWidth();
+            this.height = r.getHeight();
+            this.t = at;
+            if (width < 0.0 || height < 0.0) {
+                index = 6;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 5;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = x;
+                coords[1] = y;
+            } else {
+                type = SEG_LINETO;
+                switch(index) {
+                case 1:
+                    coords[0] = x + width;
+                    coords[1] = y;
+                    break;
+                case 2:
+                    coords[0] = x + width;
+                    coords[1] = y + height;
+                    break;
+                case 3:
+                    coords[0] = x;
+                    coords[1] = y + height;
+                    break;
+                case 4:
+                    coords[0] = x;
+                    coords[1] = y;
+                    break;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            if (index == 0) {
+                coords[0] = (float)x;
+                coords[1] = (float)y;
+                type = SEG_MOVETO;
+            } else {
+                type = SEG_LINETO;
+                switch(index) {
+                case 1:
+                    coords[0] = (float)(x + width);
+                    coords[1] = (float)y;
+                    break;
+                case 2:
+                    coords[0] = (float)(x + width);
+                    coords[1] = (float)(y + height);
+                    break;
+                case 3:
+                    coords[0] = (float)x;
+                    coords[1] = (float)(y + height);
+                    break;
+                case 4:
+                    coords[0] = (float)x;
+                    coords[1] = (float)y;
+                    break;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new rectangle2 d.
+     */
+    protected Rectangle2D() {
+    }
+
+    /**
+     * Sets the rectangle's location and dimension.
+     * 
+     * @param x the x coordinate of the rectangle's upper left corner
+     * @param y the y coordinate of the rectangle's upper left corner
+     * @param width the width of the rectangle
+     * @param height the height of the rectangle
+     */
+    public abstract void setRect(double x, double y, double width, double height);
+
+    /**
+     * Gets the location of the point with respect to the rectangle and 
+     * packs the information into a single int using the bitmasks 
+     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT}, 
+     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}.
+     * If the rectangle has zero or negative width, then every point
+     * is regarded as being both to the left and to the right of the
+     * rectangle. Similarly, if the height is zero or negative then 
+     * all points are considered to be both both above and below it.
+     * 
+     * @param x the x coordinate of the point to check
+     * @param y the y coordinate of the point to check
+     * 
+     * @return the point's location with respect to the rectangle.
+     */
+    public abstract int outcode(double x, double y);
+
+    /**
+     * Creates an new rectangle that is the intersection of this rectangle
+     * with the given rectangle. The resulting rectangle may be empty. 
+     * The data of this rectangle is left unchanged.
+     * 
+     * @param r the rectangle to intersect with this rectangle.
+     * 
+     * @return the new rectangle given by intersection.
+     */
+    public abstract Rectangle2D createIntersection(Rectangle2D r);
+
+    /**
+     * Creates an new rectangle that is the union of this rectangle
+     * with the given rectangle. The new rectangle is the smallest 
+     * rectangle which contains both this rectangle and the rectangle
+     * specified as a parameter. The data of this rectangle is left unchanged.
+     * 
+     * @param r the rectangle to combine with this rectangle
+     * 
+     * @return the new rectangle given by union
+     */
+    public abstract Rectangle2D createUnion(Rectangle2D r);
+
+    /**
+     * Sets the data of this rectangle to match the data of the given 
+     * rectangle.
+     * 
+     * @param r the rectangle whose data is to be copied into this rectangle's fields.
+     */
+    public void setRect(Rectangle2D r) {
+        setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setRect(x, y, width, height);
+    }
+
+    public Rectangle2D getBounds2D() {
+        return (Rectangle2D)clone();
+    }
+
+    /**
+     * Determines whether any part of the line segment  between (and including) 
+     * the two given points touches any 
+     * part of the rectangle, including its boundary.
+     * 
+     * @param x1 the x coordinate of one of the points that determines the 
+     * line segment to test
+     * @param y1 the y coordinate of one of the points that determines the 
+     * line segment to test
+     * @param x2 the x coordinate of one of the points that determines the 
+     * line segment to test
+     * @param y2 the y coordinate of one of the points that determines the 
+     * line segment to test
+     * 
+     * @return true, if at least one point of the line segment between the 
+     * two points matches any point of the interior of the rectangle or the
+     * rectangle's boundary.
+     */
+    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+        return
+            (rx1 <= x1 && x1 <= rx2 && ry1 <= y1 && y1 <= ry2) ||
+            (rx1 <= x2 && x2 <= rx2 && ry1 <= y2 && y2 <= ry2) ||
+            Line2D.linesIntersect(rx1, ry1, rx2, ry2, x1, y1, x2, y2) ||
+            Line2D.linesIntersect(rx2, ry1, rx1, ry2, x1, y1, x2, y2);
+    }
+
+    /**
+     * Determines whether any part of the specified line segment touches any 
+     * part of the rectangle, including its boundary.
+     * 
+     * @param l the line segment to test
+     * 
+     * @return true, if at least one point of the given line segment 
+     * matches any point of the interior of the rectangle or the
+     * rectangle's boundary.
+     */
+    public boolean intersectsLine(Line2D l) {
+        return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
+    }
+
+    /**
+     * Gets the location of the point with respect to the rectangle and 
+     * packs the information into a single int using the bitmasks 
+     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT}, 
+     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}.
+     * If the rectangle has zero or negative width, then every point
+     * is regarded as being both to the left and to the right of the
+     * rectangle. Similarly, if the height is zero or negative then 
+     * all points are considered to be both both above and below it.
+     * 
+     * @param p the point to check
+     * 
+     * @return the point's location with respect to the rectangle.
+     */
+    public int outcode(Point2D p) {
+        return outcode(p.getX(), p.getY());
+    }
+
+    public boolean contains(double x, double y) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return
+            x1 <= x && x < x2 &&
+            y1 <= y && y < y2;
+    }
+
+    public boolean intersects(double x, double y, double width, double height) {
+        if (isEmpty() || width <= 0.0 || height <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return
+            x + width > x1 && x < x2 &&
+            y + height > y1 && y < y2;
+    }
+
+    public boolean contains(double x, double y, double width, double height) {
+        if (isEmpty() || width <= 0.0 || height <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return
+            x1 <= x && x + width <= x2 &&
+            y1 <= y && y + height <= y2;
+    }
+
+    /**
+     * Changes the data values of the destination rectangle to match 
+     * the intersection of the two source rectangles, leaving the 
+     * two source rectangles unchanged. The resulting rectangle may be empty. 
+     * 
+     * @param src1 one of the two source rectangles giving the data to intersect
+     * @param src2 one of the two source rectangles giving the data to intersect
+     * @param dst the destination object where the data of the intersection is written
+     */
+    public static void intersect(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
+        double x1 = Math.max(src1.getMinX(), src2.getMinX());
+        double y1 = Math.max(src1.getMinY(), src2.getMinY());
+        double x2 = Math.min(src1.getMaxX(), src2.getMaxX());
+        double y2 = Math.min(src1.getMaxY(), src2.getMaxY());
+        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Changes the data values of the destination rectangle to match 
+     * the union of the two source rectangles, leaving the 
+     * two source rectangles unchanged. The union is the smallest rectangle
+     * tha completely covers the two source rectangles. 
+     * 
+     * @param src1 one of the two source rectangles giving the data
+     * @param src2 one of the two source rectangles giving the data
+     * @param dst the destination object where the data of the union is written
+     */
+    public static void union(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
+        double x1 = Math.min(src1.getMinX(), src2.getMinX());
+        double y1 = Math.min(src1.getMinY(), src2.getMinY());
+        double x2 = Math.max(src1.getMaxX(), src2.getMaxX());
+        double y2 = Math.max(src1.getMaxY(), src2.getMaxY());
+        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle so that it includes the given point.
+     * 
+     * @param x the x coordinate of the new point to be covered by the rectangle
+     * @param y the y coordinate of the new point to be covered by the rectangle
+     */
+    public void add(double x, double y) {
+        double x1 = Math.min(getMinX(), x);
+        double y1 = Math.min(getMinY(), y);
+        double x2 = Math.max(getMaxX(), x);
+        double y2 = Math.max(getMaxY(), y);
+        setRect(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle so that it includes the given point.
+     * 
+     * @param p the new point to be covered by the rectangle
+     */
+    public void add(Point2D p) {
+        add(p.getX(), p.getY());
+    }
+
+    /**
+     * Enlarges the rectangle so that it covers the given rectangle.
+     * 
+     * @param r the new rectangle to be covered by this rectangle
+     */
+    public void add(Rectangle2D r) {
+        union(this, r, this);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    @Override
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(this, t);
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(getX());
+        hash.append(getY());
+        hash.append(getWidth());
+        hash.append(getHeight());
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Rectangle2D) {
+            Rectangle2D r = (Rectangle2D)obj;
+            return
+                getX() == r.getX() &&
+                getY() == r.getY() &&
+                getWidth() == r.getWidth() &&
+                getHeight() == r.getHeight();
+        }
+        return false;
+    }
+
+}
+
diff --git a/awt/java/awt/geom/RectangularShape.java b/awt/java/awt/geom/RectangularShape.java
new file mode 100644
index 0000000..0a77dfd
--- /dev/null
+++ b/awt/java/awt/geom/RectangularShape.java
@@ -0,0 +1,276 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+/**
+ * The Class RectangularShape represents a Shape whose data is 
+ * (at least partially) described by a rectangular frame. This includes 
+ * shapes which are obviously rectangular (such as Rectangle2D) as well as
+ * shapes like Arc2D which are largely determined by the rectangle they 
+ * fit inside.
+ */
+public abstract class RectangularShape implements Shape, Cloneable {
+
+    /**
+     * Instantiates a new rectangular shape.
+     */
+    protected RectangularShape() {
+    }
+
+    /**
+     * Gets the x coordinate of the upper left corner of the rectangle.
+     * 
+     * @return the x coordinate of the upper left corner of the rectangle.
+     */
+    public abstract double getX();
+
+    /**
+     * Gets the y coordinate of the upper left corner of the rectangle.
+     * 
+     * @return the y coordinate of the upper left corner of the rectangle.
+     */
+    public abstract double getY();
+
+    /**
+     * Gets the width of the rectangle.
+     * 
+     * @return the width of the rectangle.
+     */
+    public abstract double getWidth();
+
+    /**
+     * Gets the height of the rectangle.
+     * 
+     * @return the height of the rectangle.
+     */
+    public abstract double getHeight();
+
+    /**
+     * Checks if this is an empty rectangle: one with zero as its width or height.
+     * 
+     * @return true, if the width or height is empty.
+     */
+    public abstract boolean isEmpty();
+
+    /**
+     * Sets the data for the bounding rectangle in terms of double values. 
+     * 
+     * @param x the x coordinate of the upper left corner of the rectangle.
+     * @param y the y coordinate of the upper left corner of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     */
+    public abstract void setFrame(double x, double y, double w, double h);
+
+    /**
+     * Gets the minimum x value of the bounding rectangle (the x 
+     * coordinate of the upper left corner of the rectangle).
+     * 
+     * @return the minimum x value of the bounding rectangle.
+     */
+    public double getMinX() {
+        return getX();
+    }
+
+    /**
+     * Gets the minimum y value of the bounding rectangle (the y 
+     * coordinate of the upper left corner of the rectangle).
+     * 
+     * @return the minimum y value of the bounding rectangle.
+     */
+    public double getMinY() {
+        return getY();
+    }
+
+    /**
+     * Gets the maximum x value of the bounding rectangle (the x
+     * coordinate of the upper left corner of the rectangle plus the 
+     * rectangle's width).
+     * 
+     * @return the maximum x value of the bounding rectangle.
+     */
+    public double getMaxX() {
+        return getX() + getWidth();
+    }
+
+    /**
+     * Gets the maximum y value of the bounding rectangle (the y
+     * coordinate of the upper left corner of the rectangle plus the 
+     * rectangle's height).
+     * 
+     * @return the maximum y value of the bounding rectangle.
+     */
+    public double getMaxY() {
+        return getY() + getHeight();
+    }
+
+    /**
+     * Gets the x coordinate of the center of the rectangle.
+     * 
+     * @return the x coordinate of the center of the rectangle.
+     */
+    public double getCenterX() {
+        return getX() + getWidth() / 2.0;
+    }
+
+    /**
+     * Gets the y coordinate of the center of the rectangle.
+     * 
+     * @return the y coordinate of the center of the rectangle.
+     */
+    public double getCenterY() {
+        return getY() + getHeight() / 2.0;
+    }
+
+    /**
+     * Places the rectangle's size and location data in a new Rectangle2D
+     * object and returns it.
+     * 
+     * @return the bounding rectangle as a new Rectangle2D object.
+     */
+    public Rectangle2D getFrame() {
+        return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
+    }
+
+    /**
+     * Sets the bounding rectangle in terms of a Point2D which gives its
+     * upper left corner and a Dimension2D object giving its width and height.
+     * 
+     * @param loc the new upper left corner coordinate.
+     * @param size the new size dimensions.
+     */
+    public void setFrame(Point2D loc, Dimension2D size) {
+        setFrame(loc.getX(), loc.getY(), size.getWidth(), size.getHeight());
+    }
+
+    /**
+     * Sets the bounding rectangle to match the data contained in the 
+     * specified Rectangle2D.
+     * 
+     * @param r the rectangle that gives the new frame data.
+     */
+    public void setFrame(Rectangle2D r) {
+        setFrame(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    /**
+     * Sets the framing rectangle given two opposite corners. Any two corners
+     * may be used in any order as long as they are diagonally opposite one another.
+     * 
+     * @param x1 the x coordinate of one of the corner points.
+     * @param y1 the y coordinate of one of the corner points.
+     * @param x2 the x coordinate of the other corner point.
+     * @param y2 the y coordinate of the other corner point.
+     */
+    public void setFrameFromDiagonal(double x1, double y1, double x2, double y2) {
+        double rx, ry, rw, rh;
+        if (x1 < x2) {
+            rx = x1;
+            rw = x2 - x1;
+        } else {
+            rx = x2;
+            rw = x1 - x2;
+        }
+        if (y1 < y2) {
+            ry = y1;
+            rh = y2 - y1;
+        } else {
+            ry = y2;
+            rh = y1 - y2;
+        }
+        setFrame(rx, ry, rw, rh);
+    }
+
+    /**
+     * Sets the framing rectangle given two opposite corners. Any two corners
+     * may be used in any order as long as they are diagonally opposite one another.
+     * 
+     * @param p1 one of the corner points.
+     * @param p2 the other corner point.
+     */
+    public void setFrameFromDiagonal(Point2D p1, Point2D p2) {
+        setFrameFromDiagonal(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the framing rectangle given the center point and one corner. Any
+     * corner may be used.
+     * 
+     * @param centerX the x coordinate of the center point.
+     * @param centerY the y coordinate of the center point.
+     * @param cornerX the x coordinate of one of the corner points.
+     * @param cornerY the y coordinate of one of the corner points.
+     */
+    public void setFrameFromCenter(double centerX, double centerY, double cornerX, double cornerY) {
+        double width = Math.abs(cornerX - centerX);
+        double height = Math.abs(cornerY - centerY);
+        setFrame(centerX - width, centerY - height, width * 2.0, height * 2.0);
+    }
+
+    /**
+     * Sets the framing rectangle given the center point and one corner. Any
+     * corner may be used.
+     * 
+     * @param center the center point.
+     * @param corner a corner point.
+     */
+    public void setFrameFromCenter(Point2D center, Point2D corner) {
+        setFrameFromCenter(center.getX(), center.getY(), corner.getX(), corner.getY());
+    }
+
+    public boolean contains(Point2D point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    public boolean intersects(Rectangle2D rect) {
+        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        int x1 = (int)Math.floor(getMinX());
+        int y1 = (int)Math.floor(getMinY());
+        int x2 = (int)Math.ceil(getMaxX());
+        int y2 = (int)Math.ceil(getMaxY());
+        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/geom/RoundRectangle2D.java b/awt/java/awt/geom/RoundRectangle2D.java
new file mode 100644
index 0000000..680a146
--- /dev/null
+++ b/awt/java/awt/geom/RoundRectangle2D.java
@@ -0,0 +1,552 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RoundRectangle2D describes a rectangle with rounded 
+ * corners with high-precision data that is appropriate for geometric
+ * operations.
+ */
+public abstract class RoundRectangle2D extends RectangularShape {
+
+    /**
+     * The Class Float is the subclass of RoundRectangle2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends RoundRectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public float x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public float y;
+        
+        /** The width of the rectangle. */
+        public float width;
+        
+        /** The height of the rectangle. */
+        public float height;
+        
+        /** The arcwidth of the rounded corners. */
+        public float arcwidth;
+        
+        /** The archeight of the rounded corners. */
+        public float archeight;
+
+        /**
+         * Instantiates a new float-valued RoundRectangle2D with 
+         * its data-values set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued RoundRectangle2D with 
+         * the specified data values
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         * @param arcwidth the arcwidth of the rounded corners
+         * @param archeight the archeight of the rounded corners
+         */
+        public Float(float x, float y, float width, float height, float arcwidth, float archeight) {
+            setRoundRect(x, y, width, height, arcwidth, archeight);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getArcWidth() {
+            return arcwidth;
+        }
+
+        @Override
+        public double getArcHeight() {
+            return archeight;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        /**
+         * Sets the data of the round rect.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         * @param arcwidth the arcwidth of the rounded corners
+         * @param archeight the archeight of the rounded corners
+         */
+        public void setRoundRect(float x, float y, float width, float height, float arcwidth, float archeight) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.arcwidth = arcwidth;
+            this.archeight = archeight;
+        }
+
+        @Override
+        public void setRoundRect(double x, double y, double width, double height, double arcwidth, double archeight) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+            this.arcwidth = (float)arcwidth;
+            this.archeight = (float)archeight;
+        }
+
+        @Override
+        public void setRoundRect(RoundRectangle2D rr) {
+            this.x = (float)rr.getX();
+            this.y = (float)rr.getY();
+            this.width = (float)rr.getWidth();
+            this.height = (float)rr.getHeight();
+            this.arcwidth = (float)rr.getArcWidth();
+            this.archeight = (float)rr.getArcHeight();
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Float(x, y, width, height);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of RoundRectangle2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends RoundRectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public double x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public double y;
+        
+        /** The width of the rectangle. */
+        public double width;
+        
+        /** The height of the rectangle. */
+        public double height;
+        
+        /** The arcwidth of the rounded corners. */
+        public double arcwidth;
+        
+        /** The archeight of the rounded corners. */
+        public double archeight;
+
+        /**
+         * Instantiates a new double-valued RoundRectangle2D with 
+         * its data-values set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued RoundRectangle2D with 
+         * the specified data values.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         * @param arcwidth the arcwidth of the rounded corners
+         * @param archeight the archeight of the rounded corners
+         */
+        public Double(double x, double y, double width, double height, double arcwidth, double archeight) {
+            setRoundRect(x, y, width, height, arcwidth, archeight);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getArcWidth() {
+            return arcwidth;
+        }
+
+        @Override
+        public double getArcHeight() {
+            return archeight;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setRoundRect(double x, double y, double width, double height, double arcwidth, double archeight) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.arcwidth = arcwidth;
+            this.archeight = archeight;
+        }
+
+        @Override
+        public void setRoundRect(RoundRectangle2D rr) {
+            this.x = rr.getX();
+            this.y = rr.getY();
+            this.width = rr.getWidth();
+            this.height = rr.getHeight();
+            this.arcwidth = rr.getArcWidth();
+            this.archeight = rr.getArcHeight();
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+    }
+
+    /*
+     * RoundRectangle2D path iterator 
+     */
+    /**
+     * The subclass of PathIterator to traverse a RoundRectangle2D.
+     */
+    class Iterator implements PathIterator {
+
+        /*
+         * Path for round corners generated the same way as Ellipse2D
+         */
+
+        /** The coefficient to calculate control points of Bezier curves. */
+        double u = 0.5 - 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+
+        /** The points coordinates calculation table. */
+        double points[][] = {
+                { 0.0,  0.5, 0.0,  0.0 }, // MOVETO
+                { 1.0, -0.5, 0.0,  0.0 }, // LINETO
+                { 1.0,   -u, 0.0,  0.0,   // CUBICTO
+                  1.0,  0.0, 0.0,    u,
+                  1.0,  0.0, 0.0,  0.5 },
+                { 1.0,  0.0, 1.0, -0.5 }, // LINETO
+                { 1.0,  0.0, 1.0,   -u,   // CUBICTO
+                  1.0,   -u, 1.0,  0.0,
+                  1.0, -0.5, 1.0,  0.0 },
+                { 0.0,  0.5, 1.0,  0.0 }, // LINETO
+                { 0.0,    u, 1.0,  0.0,   // CUBICTO
+                  0.0,  0.0, 1.0,   -u,
+                  0.0,  0.0, 1.0, -0.5 },
+                { 0.0,  0.0, 0.0,  0.5 }, // LINETO
+                { 0.0,  0.0, 0.0,    u,   // CUBICTO
+                  0.0,    u, 0.0,  0.0,
+                  0.0,  0.5, 0.0,  0.0 } };
+
+        /** The segment types correspond to points array. */
+        int types[] = {
+                SEG_MOVETO,
+                SEG_LINETO,
+                SEG_CUBICTO,
+                SEG_LINETO,
+                SEG_CUBICTO,
+                SEG_LINETO,
+                SEG_CUBICTO,
+                SEG_LINETO,
+                SEG_CUBICTO};
+
+        /** The x coordinate of left-upper corner of the round rectangle bounds. */
+        double x;
+        
+        /** The y coordinate of left-upper corner of the round rectangle bounds. */
+        double y;
+        
+        /** The width of the round rectangle bounds. */
+        double width;
+        
+        /** The height of the round rectangle bounds. */
+        double height;
+        
+        /** The width of arc corners of the round rectangle. */
+        double aw;
+        
+        /** The height of arc corners of the round rectangle. */
+        double ah;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new RoundRectangle2D.Iterator for given round rectangle and transformation.
+         * 
+         * @param rr - the source RoundRectangle2D object
+         * @param at - the AffineTransform object to apply rectangle path
+         */
+        Iterator(RoundRectangle2D rr, AffineTransform at) {
+            this.x = rr.getX();
+            this.y = rr.getY();
+            this.width = rr.getWidth();
+            this.height = rr.getHeight();
+            this.aw = Math.min(width, rr.getArcWidth());
+            this.ah = Math.min(height, rr.getArcHeight());
+            this.t = at;
+            if (width < 0.0 || height < 0.0 || aw < 0.0 || ah < 0.0) {
+                index = points.length;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > points.length;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == points.length) {
+                return SEG_CLOSE;
+            }
+            int j = 0;
+            double p[] = points[index];
+            for (int i = 0; i < p.length; i += 4) {
+                coords[j++] = x + p[i + 0] * width + p[i + 1] * aw;
+                coords[j++] = y + p[i + 2] * height + p[i + 3] * ah;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, j / 2);
+            }
+            return types[index];
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == points.length) {
+                return SEG_CLOSE;
+            }
+            int j = 0;
+            double p[] = points[index];
+            for (int i = 0; i < p.length; i += 4) {
+                coords[j++] = (float)(x + p[i + 0] * width + p[i + 1] * aw);
+                coords[j++] = (float)(y + p[i + 2] * height + p[i + 3] * ah);
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, j / 2);
+            }
+            return types[index];
+        }
+
+    }
+
+    /**
+     * Instantiates a new RoundRectangle2D.
+     */
+    protected RoundRectangle2D() {
+    }
+
+    /**
+     * Gets the arc width.
+     * 
+     * @return the arc width
+     */
+    public abstract double getArcWidth();
+
+    /**
+     * Gets the arc height.
+     * 
+     * @return the arc height
+     */
+    public abstract double getArcHeight();
+
+    /**
+     * Sets the data of the RoundRectangle2D.
+     * 
+     * @param x the x coordinate of the rectangle's upper left corner
+     * @param y the y coordinate of the rectangle's upper left corner
+     * @param width the width of the rectangle
+     * @param height the height of the rectangle
+     * @param arcWidth the arcwidth of the rounded corners
+     * @param arcHeight the archeight of the rounded corners
+     */
+    public abstract void setRoundRect(double x, double y, double width, double height,
+            double arcWidth, double arcHeight);
+
+    /**
+     * Sets the data of the RoundRectangle2D by copying the values
+     * from an existing RoundRectangle2D.
+     * 
+     * @param rr the round rectangle to copy the data from
+     * 
+     * @throws NullPointerException if rr is null
+     */
+    public void setRoundRect(RoundRectangle2D rr) {
+        setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(), rr
+                .getArcWidth(), rr.getArcHeight());
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setRoundRect(x, y, width, height, getArcWidth(), getArcHeight());
+    }
+
+    public boolean contains(double px, double py) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+
+        if (px < rx1 || px >= rx2 || py < ry1 || py >= ry2) {
+            return false;
+        }
+
+        double aw = getArcWidth() / 2.0;
+        double ah = getArcHeight() / 2.0;
+
+        double cx, cy;
+
+        if (px < rx1 + aw) {
+            cx = rx1 + aw;
+        } else
+            if (px > rx2 - aw) {
+                cx = rx2 - aw;
+            } else {
+                return true;
+            }
+
+        if (py < ry1 + ah) {
+            cy = ry1 + ah;
+        } else
+            if (py > ry2 - ah) {
+                cy = ry2 - ah;
+            } else {
+                return true;
+            }
+
+        px = (px - cx) / aw;
+        py = (py - cy) / ah;
+        return px * px + py * py <= 1.0;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        if (rx2 < x1 || x2 < rx1 || ry2 < y1 || y2 < ry1) {
+            return false;
+        }
+
+        double cx = (x1 + x2) / 2.0;
+        double cy = (y1 + y2) / 2.0;
+
+        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
+        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
+
+        return contains(nx, ny);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        return
+            contains(rx1, ry1) &&
+            contains(rx2, ry1) &&
+            contains(rx2, ry2) &&
+            contains(rx1, ry2);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+}
+
diff --git a/awt/java/awt/im/InputContext.java b/awt/java/awt/im/InputContext.java
new file mode 100644
index 0000000..3468474
--- /dev/null
+++ b/awt/java/awt/im/InputContext.java
@@ -0,0 +1,77 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.awt.AWTEvent;
+//???AWT: import java.awt.Component;
+import java.util.Locale;
+
+import org.apache.harmony.awt.im.InputMethodContext;
+
+public class InputContext {
+    protected InputContext() {
+    }
+
+    public static InputContext getInstance() {
+        return new InputMethodContext();
+    }
+
+    public void dispatchEvent(AWTEvent event) {
+    }
+
+    public void dispose() {
+    }
+
+    public void endComposition() {
+    }
+
+    public Object getInputMethodControlObject() {
+        return null;
+    }
+
+    public Locale getLocale() {
+        return null;
+    }
+
+    public boolean isCompositionEnabled() {
+        return false;
+    }
+
+    public void reconvert() {
+    }
+
+    //???AWT
+    /*
+    public void removeNotify(Component client) {
+    }
+    */
+
+    public boolean selectInputMethod(Locale locale) {
+        return false;
+    }
+
+    public void setCharacterSubsets(Character.Subset[] subsets) {
+    }
+    
+    public void setCompositionEnabled(boolean enable) {
+    }
+}
+
diff --git a/awt/java/awt/im/InputMethodHighlight.java b/awt/java/awt/im/InputMethodHighlight.java
new file mode 100644
index 0000000..53bb20b
--- /dev/null
+++ b/awt/java/awt/im/InputMethodHighlight.java
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.util.Map;
+import java.awt.font.TextAttribute;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class InputMethodHighlight {
+
+    public static final int RAW_TEXT = 0;
+
+    public static final int CONVERTED_TEXT = 1;
+
+    public static final InputMethodHighlight
+        UNSELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(false, RAW_TEXT);
+
+    public static final InputMethodHighlight
+        SELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(true, RAW_TEXT);
+
+    public static final InputMethodHighlight
+        UNSELECTED_CONVERTED_TEXT_HIGHLIGHT = 
+            new InputMethodHighlight(false, CONVERTED_TEXT);
+
+    public static final InputMethodHighlight
+        SELECTED_CONVERTED_TEXT_HIGHLIGHT = 
+            new InputMethodHighlight(true, CONVERTED_TEXT);
+    
+    private boolean selected;
+    private int state;
+    private int variation;
+    private Map<TextAttribute,?> style;
+
+    public InputMethodHighlight(boolean selected, int state, int variation) {
+        this(selected, state, variation, null);
+    }
+
+    public InputMethodHighlight(boolean selected, int state,
+                                int variation, Map<java.awt.font.TextAttribute, ?> style) {
+        if ((state != RAW_TEXT) && (state != CONVERTED_TEXT)) {
+            // awt.20B=unknown input method highlight state
+            throw new IllegalArgumentException(Messages.getString("awt.20B")); //$NON-NLS-1$
+        }
+        this.selected = selected;
+        this.state = state;
+        this.variation = variation;
+        this.style = style;
+    }
+
+    public InputMethodHighlight(boolean selected, int state) {
+        this(selected, state, 0, null);
+    }
+
+    public int getState() {
+        return state;
+    }
+
+    public Map<java.awt.font.TextAttribute, ?> getStyle() {
+        return style;
+    }
+
+    public int getVariation() {
+        return variation;
+    }
+
+    public boolean isSelected() {
+        return selected;
+    }
+}
+
diff --git a/awt/java/awt/im/InputMethodRequests.java b/awt/java/awt/im/InputMethodRequests.java
new file mode 100644
index 0000000..bdd25e6
--- /dev/null
+++ b/awt/java/awt/im/InputMethodRequests.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.awt.Rectangle;
+import java.awt.font.TextHitInfo;
+import java.text.AttributedCharacterIterator;
+
+public interface InputMethodRequests {
+
+    public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes);
+
+    public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, AttributedCharacterIterator.Attribute[] attributes);
+
+    public int getCommittedTextLength();
+
+    public int getInsertPositionOffset();
+
+    public TextHitInfo getLocationOffset(int x, int y);
+
+    public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes);
+
+    public Rectangle getTextLocation(TextHitInfo offset);
+}
+
diff --git a/awt/java/awt/im/InputSubset.java b/awt/java/awt/im/InputSubset.java
new file mode 100644
index 0000000..02a1049
--- /dev/null
+++ b/awt/java/awt/im/InputSubset.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt.im;
+
+public final class InputSubset extends Character.Subset {
+
+    public static final InputSubset LATIN = new InputSubset("LATIN"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        LATIN_DIGITS = new InputSubset("LATIN_DIGITS"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        TRADITIONAL_HANZI = new InputSubset("TRADITIONAL_HANZI"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        SIMPLIFIED_HANZI = new InputSubset("SIMPLIFIED_HANZI"); //$NON-NLS-1$
+
+    public static final InputSubset KANJI = new InputSubset("KANJI"); //$NON-NLS-1$
+
+    public static final InputSubset HANJA = new InputSubset("HANJA"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        HALFWIDTH_KATAKANA = new InputSubset("HALFWIDTH_KATAKANA"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        FULLWIDTH_LATIN = new InputSubset("FULLWIDTH_LATIN"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        FULLWIDTH_DIGITS = new InputSubset("FULLWIDTH_DIGITS"); //$NON-NLS-1$
+
+    private InputSubset(String name) {
+        super(name);
+    }
+}
+
diff --git a/awt/java/awt/im/spi/InputMethod.java b/awt/java/awt/im/spi/InputMethod.java
new file mode 100644
index 0000000..2c98c46
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethod.java
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+import java.awt.AWTEvent;
+import java.awt.Rectangle;
+import java.util.Locale;
+
+public interface InputMethod {
+
+    public void activate();
+
+    public void deactivate(boolean isTemporary);
+
+    public void dispatchEvent(AWTEvent event);
+
+    public void dispose();
+
+    public void endComposition();
+
+    public Object getControlObject();
+
+    public Locale getLocale();
+
+    public void hideWindows();
+
+    public boolean isCompositionEnabled();
+
+    public void notifyClientWindowChange(Rectangle bounds);
+
+    public void reconvert();
+
+    public void removeNotify();
+
+    public void setCharacterSubsets(Character.Subset[] subsets);
+
+    public void setCompositionEnabled(boolean enable);
+
+    public void setInputMethodContext(InputMethodContext context);
+
+    public boolean setLocale(Locale locale);
+}
+
diff --git a/awt/java/awt/im/spi/InputMethodContext.java b/awt/java/awt/im/spi/InputMethodContext.java
new file mode 100644
index 0000000..ca33e87
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethodContext.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+//???AWT: import java.awt.Window;
+import java.awt.font.TextHitInfo;
+import java.awt.im.InputMethodRequests;
+import java.text.AttributedCharacterIterator;
+//???AWT: import javax.swing.JFrame;
+
+public interface InputMethodContext extends InputMethodRequests {
+
+//    ???AWT: public JFrame createInputMethodJFrame(String title, boolean attachToInputContext);
+
+//    ???AWT: public Window createInputMethodWindow(String title, boolean attachToInputContext);
+
+    public void dispatchInputMethodEvent(int id, AttributedCharacterIterator text, int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition);
+
+    public void enableClientWindowNotification(InputMethod inputMethod, boolean enable);
+
+}
+
diff --git a/awt/java/awt/im/spi/InputMethodDescriptor.java b/awt/java/awt/im/spi/InputMethodDescriptor.java
new file mode 100644
index 0000000..3068cac
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethodDescriptor.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+import java.awt.AWTException;
+import java.awt.Image;
+import java.util.Locale;
+
+public interface InputMethodDescriptor {
+
+    public Locale[] getAvailableLocales() throws AWTException;
+
+    public InputMethod createInputMethod() throws Exception;
+
+    public String getInputMethodDisplayName(Locale inputLocale, Locale displayLanguage);
+
+    public Image getInputMethodIcon(Locale inputLocale);
+
+    public boolean hasDynamicLocaleList();
+
+}
+
diff --git a/awt/java/awt/image/AffineTransformOp.java b/awt/java/awt/image/AffineTransformOp.java
new file mode 100644
index 0000000..546837a
--- /dev/null
+++ b/awt/java/awt/image/AffineTransformOp.java
@@ -0,0 +1,617 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky, Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.*;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The AffineTransform class translates coordinates from 2D coordinates 
+ * in the source image or Raster to 2D coordinates in the destination 
+ * image or Raster using Affine transformation. The number of bands in 
+ * the source Raster should equal to the number of bands in the destination
+ * Raster.
+ */
+public class AffineTransformOp implements BufferedImageOp, RasterOp {
+    
+    /** 
+     * The Constant TYPE_NEAREST_NEIGHBOR indicates nearest-neighbor 
+     * interpolation type. 
+     */
+    public static final int TYPE_NEAREST_NEIGHBOR = 1;
+    
+    /** 
+     * The Constant TYPE_BILINEAR indicates bilinear interpolation type. 
+     */
+    public static final int TYPE_BILINEAR = 2;
+    
+    /** The Constant TYPE_BICUBIC indicates bicubic interpolation type. */
+    public static final int TYPE_BICUBIC = 3;
+
+    /** The i type. */
+    private int iType; // interpolation type
+    
+    /** The at. */
+    private AffineTransform at;
+    
+    /** The hints. */
+    private RenderingHints hints;
+
+    static {
+        // TODO - uncomment
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new AffineTransformOp with the specified
+     * AffineTransform and RenderingHints object which defines 
+     * the interpolation type.
+     * 
+     * @param xform the AffineTransform.
+     * @param hints the RenderingHints object which defines 
+     * the interpolation type.
+     */
+    public AffineTransformOp(AffineTransform xform, RenderingHints hints) {
+        this(xform, TYPE_NEAREST_NEIGHBOR);
+        this.hints = hints;
+
+        if (hints != null) {
+            Object hint = hints.get(RenderingHints.KEY_INTERPOLATION);
+            if (hint != null) {
+                // Nearest neighbor is default
+                if (hint == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
+                    this.iType = TYPE_BILINEAR;
+                } else if (hint == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
+                    this.iType = TYPE_BICUBIC;
+                }
+            } else {
+                hint = hints.get(RenderingHints.KEY_RENDERING);
+                // Determine from rendering quality
+                if (hint == RenderingHints.VALUE_RENDER_QUALITY) {
+                    this.iType = TYPE_BILINEAR;
+                // For speed use nearest neighbor
+                }
+            }
+        }
+    }
+
+    /**
+     * Instantiates a new AffineTransformOp with the specified
+     * AffineTransform and a specified interpolation type from the 
+     * list of predefined interpolation types.
+     * 
+     * @param xform the AffineTransform.
+     * @param interp the one of predefined interpolation types:
+     * TYPE_NEAREST_NEIGHBOR, TYPE_BILINEAR, or TYPE_BICUBIC.
+     */
+    public AffineTransformOp(AffineTransform xform, int interp) {
+        if (Math.abs(xform.getDeterminant()) <= Double.MIN_VALUE) {
+            // awt.24F=Unable to invert transform {0}
+            throw new ImagingOpException(Messages.getString("awt.24F", xform)); //$NON-NLS-1$
+        }
+
+        this.at = (AffineTransform) xform.clone();
+
+        if (interp != TYPE_NEAREST_NEIGHBOR && interp != TYPE_BILINEAR && interp != TYPE_BICUBIC) {
+            // awt.250=Unknown interpolation type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.250", interp)); //$NON-NLS-1$
+        }
+
+        this.iType = interp;
+    }
+
+    /**
+     * Gets the interpolation type.
+     * 
+     * @return the interpolation type
+     */
+    public final int getInterpolationType() {
+        return iType;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        if (hints == null) {
+            Object value = null;
+
+            switch (iType) {
+                case TYPE_NEAREST_NEIGHBOR:
+                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+                    break;
+                case TYPE_BILINEAR:
+                    value = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
+                    break;
+                case TYPE_BICUBIC:
+                    value = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
+                    break;
+                default:
+                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+            }
+
+            hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, value);
+        }
+
+        return hints;
+    }
+
+    /**
+     * Gets the affine transform associated with this AffineTransformOp.
+     * 
+     * @return the AffineTransform.
+     */
+    public final AffineTransform getTransform() {
+        return (AffineTransform) at.clone();
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        return at.transform(srcPt, dstPt);
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        // We position source raster to (0,0) even if it is translated child raster.
+        // This means that we need only width and height of the src
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        float[] corners = {
+            0, 0,
+            width, 0,
+            width, height,
+            0, height
+        };
+
+        at.transform(corners, 0, corners, 0, 4);
+
+        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
+        bounds.add(corners[2], corners[3]);
+        bounds.add(corners[4], corners[5]);
+        bounds.add(corners[6], corners[7]);
+
+        return bounds;
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
+        Rectangle2D newBounds = getBounds2D(src);
+
+        // Destination image should include (0,0) + positive part
+        // of the area bounded by newBounds (in source coordinate system).
+        double dstWidth = newBounds.getX() + newBounds.getWidth();
+        double dstHeight = newBounds.getY() + newBounds.getHeight();
+
+        if (dstWidth <= 0 || dstHeight <= 0) {
+            // awt.251=Transformed width ({0}) and height ({1}) should be greater than 0
+            throw new RasterFormatException(
+                    Messages.getString("awt.251", dstWidth, dstHeight)); //$NON-NLS-1$
+        }
+
+        if (destCM != null) {
+            return new BufferedImage(destCM,
+                    destCM.createCompatibleWritableRaster((int)dstWidth, (int)dstHeight),
+                    destCM.isAlphaPremultiplied(),
+                    null
+            );
+        }
+
+        ColorModel cm = src.getColorModel();
+
+        // Interpolation other than NN doesn't make any sense for index color
+        if (iType != TYPE_NEAREST_NEIGHBOR && cm instanceof IndexColorModel) {
+            return new BufferedImage((int)dstWidth, (int)dstHeight, BufferedImage.TYPE_INT_ARGB);
+        }
+
+        // OK, we can get source color model
+        return new BufferedImage(cm,
+                src.getRaster().createCompatibleWritableRaster((int)dstWidth, (int)dstHeight),
+                cm.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public WritableRaster createCompatibleDestRaster (Raster src) {
+        // Here approach is other then in createCompatibleDestImage -
+        // destination should include only
+        // transformed image, but not (0,0) in source coordinate system
+
+        Rectangle2D newBounds = getBounds2D(src);
+        return src.createCompatibleWritableRaster(
+                (int) newBounds.getX(), (int) newBounds.getY(),
+                (int) newBounds.getWidth(), (int)newBounds.getHeight()
+        );
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (src == dst) {
+            // awt.252=Source can't be same as the destination
+            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        BufferedImage finalDst = null;
+
+        if (
+                srcCM instanceof IndexColorModel &&
+                (iType != TYPE_NEAREST_NEIGHBOR || srcCM.getPixelSize() % 8 != 0)
+        ) {
+            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
+            srcCM = src.getColorModel();
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestImage(src, srcCM);
+        } else {
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB as same
+                if (
+                   !(
+                     (src.getType() == BufferedImage.TYPE_INT_RGB ||
+                      src.getType() == BufferedImage.TYPE_INT_ARGB) &&
+                     (dst.getType() == BufferedImage.TYPE_INT_RGB ||
+                      dst.getType() == BufferedImage.TYPE_INT_ARGB)
+                    )
+                ) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, srcCM);
+                }
+            }
+        }
+
+        // Skip alpha channel for TYPE_INT_RGB images
+        if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+        // TODO - uncomment
+        //if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) != 0)
+            //throw new ImagingOpException ("Unable to transform source");
+        }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (src == dst) {
+            // awt.252=Source can't be same as the destination
+            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (src.getNumBands() != dst.getNumBands()) {
+            // awt.253=Different number of bands in source and destination
+            throw new IllegalArgumentException(Messages.getString("awt.253")); //$NON-NLS-1$
+        }
+
+        if (slowFilter(src, dst) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        // TODO - uncomment
+        //if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
+        //    throw new ImagingOpException("Unable to transform source");
+        }
+
+        return dst;
+    }
+
+    // TODO remove when method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
+        int srcStride, dstStride;
+        boolean skipChannel = false;
+        int channels;
+        int offsets[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_RGB:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                skipChannel = true;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY:
+            case BufferedImage.TYPE_BYTE_INDEXED: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in native code?
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1, 3 and 4 channels
+                    if (channels != 1 && channels != 3 && channels != 4) {
+                        return slowFilter(src, dst);
+                    }
+
+                    int dataTypeSize = DataBuffer.getDataTypeSize(srcSM.getDataType()) / 8;
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride() * dataTypeSize;
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride() * dataTypeSize;
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+                    // No IPP function for this type
+                    if (sppsm1.getDataType() == DataBuffer.TYPE_USHORT) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = sppsm1.getNumBands();
+                    // Have IPP functions for 1, 3 and 4 channels
+                    if (channels != 1 && channels != 3 && channels != 4) {
+                        return slowFilter(src, dst);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            sppsm1.getDataType() != sppsm2.getDataType() ||
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst);
+                        }
+                    }
+
+                    if (channels == 3) {
+                        channels = 4;
+                    }
+
+                    int dataTypeSize = DataBuffer.getDataTypeSize(sppsm1.getDataType()) / 8;
+
+                    srcStride = sppsm1.getScanlineStride() * dataTypeSize;
+                    dstStride = sppsm2.getScanlineStride() * dataTypeSize;
+                } else {
+                    return slowFilter(src, dst);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        double m00 = at.getScaleX();
+        double m01 = at.getShearX();
+        double m02 = at.getTranslateX();
+        double m10 = at.getShearY();
+        double m11 = at.getScaleY();
+        double m12 = at.getTranslateY();
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        return ippAffineTransform(
+            m00, m01, m02, m10, m11, m12,
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            iType, channels, skipChannel, offsets);
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private int slowFilter(Raster src, WritableRaster dst) {
+        // TODO: make correct interpolation
+        // TODO: what if there are different data types?
+
+        Rectangle srcBounds = src.getBounds();
+        Rectangle dstBounds = dst.getBounds();
+        Rectangle normDstBounds = new Rectangle(0, 0, dstBounds.width, dstBounds.height);
+        Rectangle bounds = getBounds2D(src).getBounds().intersection(normDstBounds);
+
+        AffineTransform inv = null;
+        try {
+             inv = at.createInverse();
+        } catch (NoninvertibleTransformException e) {
+            return -1;
+        }
+
+        double[] m = new double[6];
+        inv.getMatrix(m);
+
+        int minSrcX = srcBounds.x;
+        int minSrcY = srcBounds.y;
+        int maxSrcX = srcBounds.x + srcBounds.width;
+        int maxSrcY = srcBounds.y + srcBounds.height;
+
+        int minX = bounds.x + dstBounds.x;
+        int minY = bounds.y + dstBounds.y;
+        int maxX = minX + bounds.width;
+        int maxY = minY + bounds.height;
+
+        int hx = (int)(m[0] * 256);
+        int hy = (int)(m[1] * 256);
+        int vx = (int)(m[2] * 256);
+        int vy = (int)(m[3] * 256);
+        int sx = (int)(m[4] * 256) + hx * bounds.x + vx * bounds.y + (srcBounds.x) * 256;
+        int sy = (int)(m[5] * 256) + hy * bounds.x + vy * bounds.y + (srcBounds.y) * 256;
+
+        vx -= hx * bounds.width;
+        vy -= hy * bounds.width;
+
+        if (src.getTransferType() == dst.getTransferType()) {
+            for (int y = minY; y < maxY; y++) {
+                for (int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        Object val = src.getDataElements(px , py , null);
+                        dst.setDataElements(x, y, val);
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        } else {
+            float pixel[] = null;
+            for (int y = minY; y < maxY; y++) {
+                for (int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        pixel = src.getPixel(px, py, pixel);
+                        dst.setPixel(x, y, pixel);
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Ipp affine transform.
+     * 
+     * @param m00 the m00
+     * @param m01 the m01
+     * @param m02 the m02
+     * @param m10 the m10
+     * @param m11 the m11
+     * @param m12 the m12
+     * @param src the src
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dst the dst
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param iType the i type
+     * @param channels the channels
+     * @param skipChannel the skip channel
+     * @param offsets the offsets
+     * 
+     * @return the int
+     */
+    private native int ippAffineTransform(
+            double m00, double m01,
+            double m02, double m10,
+            double m11, double m12,
+            Object src, int srcWidth, int srcHeight, int srcStride,
+            Object dst, int dstWidth, int dstHeight, int dstStride,
+            int iType, int channels, boolean skipChannel,
+            int offsets[]);
+}
\ No newline at end of file
diff --git a/awt/java/awt/image/AreaAveragingScaleFilter.java b/awt/java/awt/image/AreaAveragingScaleFilter.java
new file mode 100644
index 0000000..f4933db
--- /dev/null
+++ b/awt/java/awt/image/AreaAveragingScaleFilter.java
@@ -0,0 +1,253 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+
+/**
+ * The AreaAveragingScaleFilter class scales the source image using
+ * area averaging algorithm. This algorithm provides a source image
+ * with a new image containing the resampled image. 
+ */
+public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
+
+    /** The Constant rgbCM. */
+    private static final ColorModel rgbCM = ColorModel.getRGBdefault();
+    
+    /** The Constant averagingFlags. */
+    private static final int averagingFlags = (ImageConsumer.TOPDOWNLEFTRIGHT |
+            ImageConsumer.COMPLETESCANLINES);
+
+    /** The reset. */
+    private boolean reset = true;   // Flag for used superclass filter
+    
+    /** The inited. */
+    private boolean inited = false; // All data inited
+
+    /** The sum_r. */
+    private int sum_r[]; // Array for average Red samples
+    
+    /** The sum_g. */
+    private int sum_g[]; // Array for average Green samples
+    
+    /** The sum_b. */
+    private int sum_b[]; // Array for average Blue samples
+    
+    /** The sum_a. */
+    private int sum_a[]; // Array for average Alpha samples
+
+    /** The buff. */
+    private int buff[];  // Stride buffer
+    
+    /** The avg factor. */
+    private int avgFactor;  // Global averaging factor
+
+    /** The cached dy. */
+    private int cachedDY;      // Cached number of the destination scanline 
+    
+    /** The cached dv rest. */
+    private int cachedDVRest;  // Cached value of rest src scanlines for sum 
+                               // pixel samples 
+                               // Because data if transfering by whole scanlines
+                               // we are caching only Y coordinate values
+    
+    /**
+     * Instantiates a new AreaAveragingScaleFilter object which scales
+     * a source image with the specified width and height.
+     * 
+     * @param width the scaled width of the image.
+     * @param height the scaled height of the image.
+     */
+    public AreaAveragingScaleFilter(int width, int height) {
+        super(width, height);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) {
+        if(reset) {
+            super.setPixels(x, y, w, h, model, pixels, off, scansize);
+        } else {
+            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) {
+        if(reset) {
+            super.setPixels(x, y, w, h, model, pixels, off, scansize);
+        } else {
+            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+        }
+    }
+
+    @Override
+    public void setHints(int hints) {
+        super.setHints(hints);
+        reset = ((hints & averagingFlags) != averagingFlags);
+    }
+
+    /**
+     * This method implements the Area Averaging Scale filter.
+     * The description of algorithm is presented in Java API Specification.
+     * 
+     * Arrays sum_r, sum_g, sum_b, sum_a have length equals width of destination
+     * image. In each array's element is accumulating pixel's component values,
+     * proportional to the area which source pixels will occupy in destination
+     * image. Then that values will divide by Global averaging
+     * factor (area of the destination image) for receiving
+     * average values of destination pixels.
+     * 
+     * @param x - Src pixels X coordinate
+     * @param y - Src pixels Y coordinate
+     * @param w - width of the area of Src pixels
+     * @param h - height of the area of Src pixels
+     * @param model - Color Model of Src pixels
+     * @param pixels - array of Src pixels
+     * @param off - offset into the Src pixels array
+     * @param scansize - length of scanline in the pixels array
+     */
+    private void setFilteredPixels(int x, int y, int w, int h, ColorModel model, Object pixels, int off, int scansize){
+        if(!inited){
+            initialize();
+        }
+
+        int srcX, srcY, dx, dy;
+        int svRest, dvRest, shRest, dhRest, vDif, hDif;
+
+        if(y == 0){
+            dy = 0;
+            dvRest = srcHeight;
+        }else{
+            dy = cachedDY;
+            dvRest = cachedDVRest;
+        }
+
+        srcY = y;
+        svRest = destHeight;
+
+        int srcOff = off;
+        while (srcY < y + h) {
+            if (svRest < dvRest) {
+                vDif = svRest;
+            } else {
+                vDif = dvRest;
+            }
+
+            srcX = 0;
+            dx = 0;
+            shRest = destWidth;
+            dhRest = srcWidth;
+            while (srcX < w) {
+                if (shRest < dhRest) {
+                    hDif = shRest;
+                } else {
+                    hDif = dhRest;
+                }
+                int avg = hDif * vDif; // calculation of contribution factor
+
+                int rgb, pix;
+                if (pixels instanceof int[]) {
+                    pix = ((int[]) pixels)[srcOff + srcX];
+                } else {
+                    pix = ((byte[]) pixels)[srcOff + srcX] & 0xff;
+                }
+
+                rgb = model.getRGB(pix);
+                int a = rgb >>> 24;
+                int r = (rgb >> 16) & 0xff;
+                int g = (rgb >> 8) & 0xff;
+                int b = rgb & 0xff;
+
+                // accumulating pixel's component values
+                sum_a[dx] += a * avg;
+                sum_r[dx] += r * avg;
+                sum_g[dx] += g * avg;
+                sum_b[dx] += b * avg;
+
+                shRest -= hDif;
+                dhRest -= hDif;
+
+                if (shRest == 0) {
+                    srcX++;
+                    shRest = destWidth;
+                }
+
+                if (dhRest == 0) {
+                    dx++;
+                    dhRest = srcWidth;
+                }
+            }
+
+            svRest -= vDif;
+            dvRest -= vDif;
+
+            if (svRest == 0) {
+                svRest = destHeight;
+                srcY++;
+                srcOff += scansize;
+            }
+
+            if (dvRest == 0) {
+                // averaging destination pixel's values
+                for(int i = 0; i < destWidth; i++){
+                    int a = (sum_a[i] / avgFactor) & 0xff;
+                    int r = (sum_r[i] / avgFactor) & 0xff;
+                    int g = (sum_g[i] / avgFactor) & 0xff;
+                    int b = (sum_b[i] / avgFactor) & 0xff;
+                    int frgb = (a << 24) | (r << 16) | (g << 8) | b;
+                    buff[i] = frgb;
+                }
+                consumer.setPixels(0, dy, destWidth, 1, rgbCM, buff, 0,
+                        destWidth);
+                dy++;
+                dvRest = srcHeight;
+                Arrays.fill(sum_a, 0);
+                Arrays.fill(sum_r, 0);
+                Arrays.fill(sum_g, 0);
+                Arrays.fill(sum_b, 0);
+            }
+
+        }
+
+        cachedDY = dy;
+        cachedDVRest = dvRest;
+
+    }
+
+    /**
+     * Initialization of the auxiliary data.
+     */
+    private void initialize(){
+
+        sum_a = new int[destWidth]; 
+        sum_r = new int[destWidth]; 
+        sum_g = new int[destWidth]; 
+        sum_b = new int[destWidth]; 
+
+        buff = new int[destWidth];  
+        outpixbuf = buff;
+        avgFactor = srcWidth * srcHeight; 
+
+        inited = true;
+    }
+}
+
diff --git a/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java b/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
new file mode 100644
index 0000000..ce85ddd
--- /dev/null
+++ b/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
@@ -0,0 +1,153 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 23.11.2005
+ *
+ */
+package java.awt.image;
+
+import java.awt.Image;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferDouble;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.DataBufferUShort;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.gl.GLVolatileImage;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class not part of public API. It useful for receiving package private
+ * data from other packages.
+ */
+class AwtImageBackdoorAccessorImpl extends AwtImageBackdoorAccessor {
+
+    static void init(){
+        inst = new AwtImageBackdoorAccessorImpl();
+    }
+
+    @Override
+    public Surface getImageSurface(Image image) {
+        if (image instanceof BufferedImage){
+            return ((BufferedImage)image).getImageSurface();
+        } else if (image instanceof GLVolatileImage){
+            return ((GLVolatileImage)image).getImageSurface();
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isGrayPallete(IndexColorModel icm){
+        return icm.isGrayPallete();
+    }
+
+    @Override
+    public Object getData(DataBuffer db) {
+        if (db instanceof DataBufferByte){
+            return ((DataBufferByte)db).getData();
+        } else if (db instanceof DataBufferUShort){
+            return ((DataBufferUShort)db).getData();
+        } else if (db instanceof DataBufferShort){
+            return ((DataBufferShort)db).getData();
+        } else if (db instanceof DataBufferInt){
+            return ((DataBufferInt)db).getData();
+        } else if (db instanceof DataBufferFloat){
+            return ((DataBufferFloat)db).getData();
+        } else if (db instanceof DataBufferDouble){
+            return ((DataBufferDouble)db).getData();
+        } else {
+            // awt.235=Wrong Data Buffer type : {0}
+            throw new IllegalArgumentException(Messages.getString("awt.235", //$NON-NLS-1$
+                    db.getClass()));
+        }
+    }
+
+    @Override
+    public int[] getDataInt(DataBuffer db) {
+        if (db instanceof DataBufferInt){
+            return ((DataBufferInt)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public byte[] getDataByte(DataBuffer db) {
+        if (db instanceof DataBufferByte){
+            return ((DataBufferByte)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public short[] getDataShort(DataBuffer db) {
+        if (db instanceof DataBufferShort){
+            return ((DataBufferShort)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public short[] getDataUShort(DataBuffer db) {
+        if (db instanceof DataBufferUShort){
+            return ((DataBufferUShort)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public double[] getDataDouble(DataBuffer db) {
+        if (db instanceof DataBufferDouble){
+            return ((DataBufferDouble)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public float[] getDataFloat(DataBuffer db) {
+        if (db instanceof DataBufferFloat){
+            return ((DataBufferFloat)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public void addDataBufferListener(DataBuffer db, DataBufferListener listener) {
+        db.addDataBufferListener(listener);
+    }
+
+    @Override
+    public void removeDataBufferListener(DataBuffer db) {
+        db.removeDataBufferListener();
+    }
+
+    @Override
+    public void validate(DataBuffer db) {
+        db.validate();
+    }
+
+    @Override
+    public void releaseData(DataBuffer db) {
+        db.releaseData();
+    }
+}
diff --git a/awt/java/awt/image/BandCombineOp.java b/awt/java/awt/image/BandCombineOp.java
new file mode 100644
index 0000000..cd77a21
--- /dev/null
+++ b/awt/java/awt/image/BandCombineOp.java
@@ -0,0 +1,610 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 20, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BandCombineOp class translates coordinates from 
+ * coordinates in the source Raster to coordinates in 
+ * the destination Raster by an arbitrary linear combination 
+ * of the bands in a source Raster, using a specified matrix.
+ * The number of bands in the matrix should equal to 
+ * the number of bands in the source Raster plus 1.
+ */
+public class BandCombineOp implements RasterOp {
+    
+    /** The Constant offsets3c. */
+    static final int offsets3c[] = {16, 8, 0};
+    
+    /** The Constant offsets4ac. */
+    static final int offsets4ac[] = {16, 8, 0, 24};
+    
+    /** The Constant masks3c. */
+    static final int masks3c[] = {0xFF0000, 0xFF00, 0xFF};
+    
+    /** The Constant masks4ac. */
+    static final int masks4ac[] = {0xFF0000, 0xFF00, 0xFF, 0xFF000000};
+    
+    /** The Constant piOffsets. */
+    private static final int piOffsets[] = {0, 1, 2};
+    
+    /** The Constant piInvOffsets. */
+    private static final int piInvOffsets[] = {2, 1, 0};
+
+    /** The Constant TYPE_BYTE3C. */
+    private static final int TYPE_BYTE3C = 0;
+    
+    /** The Constant TYPE_BYTE4AC. */
+    private static final int TYPE_BYTE4AC = 1;
+    
+    /** The Constant TYPE_USHORT3C. */
+    private static final int TYPE_USHORT3C = 2;
+    
+    /** The Constant TYPE_SHORT3C. */
+    private static final int TYPE_SHORT3C = 3;
+
+    /** The mx width. */
+    private int mxWidth;
+    
+    /** The mx height. */
+    private int mxHeight;
+    
+    /** The matrix. */
+    private float matrix[][];
+    
+    /** The r hints. */
+    private RenderingHints rHints;
+
+    static {
+        // XXX - todo
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new BandCombineOp object with the specified
+     * matrix.
+     * 
+     * @param matrix the specified matrix for band combining.
+     * @param hints the RenderingHints.
+     */
+    public BandCombineOp(float matrix[][], RenderingHints hints) {
+        this.mxHeight = matrix.length;
+        this.mxWidth = matrix[0].length;
+        this.matrix = new float[mxHeight][mxWidth];
+
+        for (int i=0; i<mxHeight; i++){
+            System.arraycopy(matrix[i], 0, this.matrix[i], 0, mxWidth);
+        }
+
+        this.rHints = hints;
+    }
+
+    public final RenderingHints getRenderingHints(){
+        return this.rHints;
+    }
+
+    /**
+     * Gets the matrix associated with this BandCombineOp object.
+     * 
+     * @return the matrix associated with this BandCombineOp object.
+     */
+    public final float[][] getMatrix() {
+        float res[][] = new float[mxHeight][mxWidth];
+
+        for (int i=0; i<mxHeight; i++) {
+            System.arraycopy(matrix[i], 0, res[i], 0, mxWidth);
+        }
+
+        return res;
+    }
+
+    public final Point2D getPoint2D (Point2D srcPoint, Point2D dstPoint) {
+        if (dstPoint == null) {
+            dstPoint = new Point2D.Float();
+        }
+
+        dstPoint.setLocation(srcPoint);
+        return dstPoint;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src){
+        return src.getBounds();
+    }
+
+    public WritableRaster createCompatibleDestRaster (Raster src) {
+        int numBands = src.getNumBands();
+        if (mxWidth != numBands && mxWidth != (numBands+1) || numBands != mxHeight) {
+            // awt.254=Number of bands in the source raster ({0}) is
+            //          incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(Messages.getString("awt.254", //$NON-NLS-1$
+                    new Object[]{numBands, mxWidth, mxHeight}));
+        }
+
+        return src.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+    }
+
+    public WritableRaster filter(Raster src, WritableRaster dst) {
+        int numBands = src.getNumBands();
+
+        if (mxWidth != numBands && mxWidth != (numBands+1)) {
+            // awt.254=Number of bands in the source raster ({0}) is
+            //          incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(
+                    Messages.getString("awt.254", //$NON-NLS-1$
+                    new Object[]{numBands, mxWidth, mxHeight}));
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (dst.getNumBands() != mxHeight) {
+            // awt.255=Number of bands in the destination raster ({0}) is incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(Messages.getString("awt.255", //$NON-NLS-1$
+                    new Object[]{dst.getNumBands(), mxWidth, mxHeight}));
+        }
+
+        // XXX - todo
+        //if (ippFilter(src, dst) != 0)
+        if (verySlowFilter(src, dst) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        return dst;
+    }
+
+    /**
+     * The Class SampleModelInfo.
+     */
+    private static final class SampleModelInfo {
+        
+        /** The channels. */
+        int channels;
+        
+        /** The channels order. */
+        int channelsOrder[];
+        
+        /** The stride. */
+        int stride;
+    }
+
+    /**
+     * Check sample model.
+     * 
+     * @param sm the sm
+     * 
+     * @return the sample model info
+     */
+    private final SampleModelInfo checkSampleModel(SampleModel sm) {
+        SampleModelInfo ret = new SampleModelInfo();
+
+        if (sm instanceof PixelInterleavedSampleModel) {
+            // Check PixelInterleavedSampleModel
+            if (sm.getDataType() != DataBuffer.TYPE_BYTE) {
+                return null;
+            }
+
+            ret.channels = sm.getNumBands();
+            ret.stride = ((ComponentSampleModel) sm).getScanlineStride();
+            ret.channelsOrder = ((ComponentSampleModel) sm).getBandOffsets();
+
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            // Check SinglePixelPackedSampleModel
+            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) sm;
+
+            ret.channels = sppsm1.getNumBands();
+            if (sppsm1.getDataType() != DataBuffer.TYPE_INT) {
+                return null;
+            }
+
+            // Check sample models
+            for (int i=0; i<ret.channels; i++) {
+                if (sppsm1.getSampleSize(i) != 8) {
+                    return null;
+                }
+            }
+
+            ret.channelsOrder = new int[ret.channels];
+            int bitOffsets[] = sppsm1.getBitOffsets();
+            for (int i=0; i<ret.channels; i++) {
+                if (bitOffsets[i] % 8 != 0) {
+                    return null;
+                }
+
+                ret.channelsOrder[i] = bitOffsets[i] / 8;
+            }
+
+            ret.channels = 4;
+            ret.stride = sppsm1.getScanlineStride() * 4;
+        } else {
+            return null;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private final int slowFilter(Raster src, WritableRaster dst) {
+        int res = 0;
+
+        SampleModelInfo srcInfo, dstInfo;
+        int offsets[] = null;
+
+        srcInfo = checkSampleModel(src.getSampleModel());
+        dstInfo = checkSampleModel(dst.getSampleModel());
+        if (srcInfo == null || dstInfo == null) {
+            return verySlowFilter(src, dst);
+        }
+
+        // Fill offsets if there's a child raster
+        if (src.getParent() != null || dst.getParent() != null) {
+            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0 ||
+                    dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
+                offsets = new int[4];
+                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+            }
+        }
+
+        int rmxWidth = (srcInfo.channels+1); // width of the reordered matrix
+        float reorderedMatrix[] = new float[rmxWidth*dstInfo.channels];
+        for (int j=0; j<dstInfo.channels; j++) {
+            if (j >= dstInfo.channelsOrder.length) {
+                continue;
+            }
+
+            for (int i=0; i<srcInfo.channels; i++) {
+                if (i >= srcInfo.channelsOrder.length) {
+                    break;
+                }
+
+                reorderedMatrix[dstInfo.channelsOrder[j]*rmxWidth + srcInfo.channelsOrder[i]] =
+                        matrix[j][i];
+            }
+            if (mxWidth == rmxWidth) {
+                reorderedMatrix[(dstInfo.channelsOrder[j]+1)*rmxWidth - 1] = matrix[j][mxWidth-1];
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        simpleCombineBands(
+                srcData, src.getWidth(), src.getHeight(), srcInfo.stride, srcInfo.channels,
+                dstData, dstInfo.stride, dstInfo.channels,
+                reorderedMatrix, offsets
+        );
+
+        return res;
+    }
+
+    /**
+     * Very slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private int verySlowFilter(Raster src, WritableRaster dst) {
+        int numBands = src.getNumBands();
+
+        int srcMinX = src.getMinX();
+        int srcY = src.getMinY();
+
+        int dstMinX = dst.getMinX();
+        int dstY = dst.getMinY();
+
+        int dX = src.getWidth();//< dst.getWidth() ? src.getWidth() : dst.getWidth();
+        int dY = src.getHeight();//< dst.getHeight() ? src.getHeight() : dst.getHeight();
+
+        float sample;
+        int srcPixels[] = new int[numBands*dX*dY];
+        int dstPixels[] = new int[mxHeight*dX*dY];
+
+        srcPixels = src.getPixels(srcMinX, srcY, dX, dY, srcPixels);
+
+        if (numBands == mxWidth) {
+            for (int i=0, j=0; i<srcPixels.length; i+=numBands) {
+                for (int dstB = 0; dstB < mxHeight; dstB++) {
+                    sample = 0f;
+                    for (int srcB = 0; srcB < numBands; srcB++) {
+                        sample += matrix[dstB][srcB] * srcPixels[i+srcB];
+                    }
+                    dstPixels[j++] = (int) sample;
+                }
+            }
+        } else {
+            for (int i=0, j=0; i<srcPixels.length; i+=numBands) {
+                for (int dstB = 0; dstB < mxHeight; dstB++) {
+                    sample = 0f;
+                    for (int srcB = 0; srcB < numBands; srcB++) {
+                        sample += matrix[dstB][srcB] * srcPixels[i+srcB];
+                    }
+                    dstPixels[j++] = (int) (sample + matrix[dstB][numBands]);
+                }
+            }
+        }
+
+        dst.setPixels(dstMinX, dstY, dX, dY, dstPixels);
+
+        return 0;
+    }
+
+    //TODO remove when method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst) {
+        boolean invertChannels;
+        boolean inPlace = (src == dst);
+        int type;
+        int srcStride, dstStride;
+        int offsets[] = null;
+
+        int srcBands = src.getNumBands();
+        int dstBands = dst.getNumBands();
+
+        if (
+                dstBands != 3 ||
+                (srcBands != 3 &&
+                !(srcBands == 4 &&
+                  matrix[0][3] == 0 &&
+                  matrix[1][3] == 0 &&
+                  matrix[2][3] == 0)
+                )
+        ) {
+            return slowFilter(src, dst);
+        }
+
+        SampleModel srcSM = src.getSampleModel();
+        SampleModel dstSM = dst.getSampleModel();
+
+        if (
+                srcSM instanceof SinglePixelPackedSampleModel &&
+                dstSM instanceof SinglePixelPackedSampleModel
+        ) {
+            // Check SinglePixelPackedSampleModel
+            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+            SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+            if (
+                    sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                    sppsm2.getDataType() != DataBuffer.TYPE_INT
+            ) {
+                return slowFilter(src, dst);
+            }
+
+            // Check sample models
+            if (
+                    !Arrays.equals(sppsm2.getBitOffsets(), offsets3c) ||
+                    !Arrays.equals(sppsm2.getBitMasks(), masks3c)
+            ) {
+                return slowFilter(src, dst);
+            }
+
+            if (srcBands == 3) {
+                if (
+                        !Arrays.equals(sppsm1.getBitOffsets(), offsets3c) ||
+                        !Arrays.equals(sppsm1.getBitMasks(), masks3c)
+                ) {
+                    return slowFilter(src, dst);
+                }
+            } else if (srcBands == 4) {
+                if (
+                        !Arrays.equals(sppsm1.getBitOffsets(), offsets4ac) ||
+                        !Arrays.equals(sppsm1.getBitMasks(), masks4ac)
+                ) {
+                    return slowFilter(src, dst);
+                }
+            }
+
+            type = TYPE_BYTE4AC;
+            invertChannels = true;
+
+            srcStride = sppsm1.getScanlineStride() * 4;
+            dstStride = sppsm2.getScanlineStride() * 4;
+        } else if (
+            srcSM instanceof PixelInterleavedSampleModel &&
+            dstSM instanceof PixelInterleavedSampleModel
+        ) {
+            if (srcBands != 3) {
+                return slowFilter(src, dst);
+            }
+
+            int srcDataType = srcSM.getDataType();
+
+            switch (srcDataType) {
+                case DataBuffer.TYPE_BYTE:
+                    type = TYPE_BYTE3C;
+                    break;
+                case DataBuffer.TYPE_USHORT:
+                    type = TYPE_USHORT3C;
+                    break;
+                case DataBuffer.TYPE_SHORT:
+                    type = TYPE_SHORT3C;
+                    break;
+                default:
+                    return slowFilter(src, dst);
+            }
+
+            // Check PixelInterleavedSampleModel
+            PixelInterleavedSampleModel pism1 = (PixelInterleavedSampleModel) srcSM;
+            PixelInterleavedSampleModel pism2 = (PixelInterleavedSampleModel) dstSM;
+
+            if (
+                    srcDataType != pism2.getDataType() ||
+                    pism1.getPixelStride() != 3 ||
+                    pism2.getPixelStride() != 3 ||
+                    !Arrays.equals(pism1.getBandOffsets(), pism2.getBandOffsets())
+            ) {
+                return slowFilter(src, dst);
+            }
+
+            if (Arrays.equals(pism1.getBandOffsets(), piInvOffsets)) {
+                invertChannels = true;
+            } else if (Arrays.equals(pism1.getBandOffsets(), piOffsets)) {
+                invertChannels = false;
+            } else {
+                return slowFilter(src, dst);
+            }
+
+            int dataTypeSize = DataBuffer.getDataTypeSize(srcDataType) / 8;
+
+            srcStride = pism1.getScanlineStride() * dataTypeSize;
+            dstStride = pism2.getScanlineStride() * dataTypeSize;
+        } else { // XXX - todo - IPP allows support for planar data also
+            return slowFilter(src, dst);
+        }
+
+        // Fill offsets if there's a child raster
+        if (src.getParent() != null || dst.getParent() != null) {
+            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0 ||
+               dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
+                offsets = new int[4];
+                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        float ippMatrix[] = new float[12];
+
+        if (invertChannels) {
+            // IPP treats big endian integers like BGR, so we have to
+            // swap columns 1 and 3 and rows 1 and 3
+            for (int i = 0; i < mxHeight; i++) {
+                ippMatrix[i*4] = matrix[2-i][2];
+                ippMatrix[i*4+1] = matrix[2-i][1];
+                ippMatrix[i*4+2] = matrix[2-i][0];
+
+                if (mxWidth == 4) {
+                    ippMatrix[i*4+3] = matrix[2-i][3];
+                } else if (mxWidth == 5) {
+                    ippMatrix[i*4+3] = matrix[2-i][4];
+                }
+            }
+        } else {
+            for (int i = 0; i < mxHeight; i++) {
+                ippMatrix[i*4] = matrix[i][0];
+                ippMatrix[i*4+1] = matrix[i][1];
+                ippMatrix[i*4+2] = matrix[i][2];
+
+                if (mxWidth == 4) {
+                    ippMatrix[i*4+3] = matrix[i][3];
+                } else if (mxWidth == 5) {
+                    ippMatrix[i*4+3] = matrix[i][4];
+                }
+            }
+        }
+
+        return ippColorTwist(
+                srcData, src.getWidth(), src.getHeight(), srcStride,
+                dstData, dst.getWidth(), dst.getHeight(), dstStride,
+                ippMatrix, type, offsets, inPlace);
+    }
+
+    /**
+     * Ipp color twist.
+     * 
+     * @param srcData the src data
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dstData the dst data
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param ippMatrix the ipp matrix
+     * @param type the type
+     * @param offsets the offsets
+     * @param inPlace the in place
+     * 
+     * @return the int
+     */
+    private final native int ippColorTwist(
+            Object srcData, int srcWidth, int srcHeight, int srcStride,
+            Object dstData, int dstWidth, int dstHeight, int dstStride,
+            float ippMatrix[], int type, int offsets[], boolean inPlace
+    );
+
+    /**
+     * Simple combine bands.
+     * 
+     * @param srcData the src data
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param srcChannels the src channels
+     * @param dstData the dst data
+     * @param dstStride the dst stride
+     * @param dstChannels the dst channels
+     * @param m the m
+     * @param offsets the offsets
+     * 
+     * @return the int
+     */
+    private final native int simpleCombineBands(
+            Object srcData, int srcWidth, int srcHeight, int srcStride, int srcChannels,
+            Object dstData, int dstStride, int dstChannels,
+            float m[], int offsets[]
+    );
+}
diff --git a/awt/java/awt/image/BandedSampleModel.java b/awt/java/awt/image/BandedSampleModel.java
new file mode 100644
index 0000000..392e44c
--- /dev/null
+++ b/awt/java/awt/image/BandedSampleModel.java
@@ -0,0 +1,426 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BandedSampleModel class provides samples of pixels in an image 
+ * which is stored in a band interleaved method. Each pixel's sample 
+ * takes one data element of the DataBuffer. The pixel stride for a 
+ * BandedSampleModel is one. 
+ */
+public final class BandedSampleModel extends ComponentSampleModel {
+
+    /**
+     * Creates the indices.
+     * 
+     * @param numBands the num bands
+     * 
+     * @return the int[]
+     */
+    private static int[] createIndices(int numBands) {
+        int indices[] = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            indices[i] = i;
+        }
+        return indices;
+    }
+
+    /**
+     * Creates the offsets.
+     * 
+     * @param numBands the num bands
+     * 
+     * @return the int[]
+     */
+    private static int[] createOffsets(int numBands) {
+        int offsets[] = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            offsets[i] = 0;
+        }
+        return offsets;
+    }
+
+    /**
+     * Instantiates a new BandedSampleModel object with the specified 
+     * data type of samples, the width, height and bands number
+     * of image data.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param numBands the number of bands.
+     */
+    public BandedSampleModel(int dataType, int w, int h, int numBands) {
+        this(dataType, w, h, w, BandedSampleModel.createIndices(numBands),
+                BandedSampleModel.createOffsets(numBands));
+    }
+
+    /**
+     * Instantiates a new BandedSampleModel object with the specified 
+     * data type of samples, the width, height and bands number
+     * of image data.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param scanlineStride the scanline stride of the of the image data.
+     * @param bankIndices the array of the bank indecies.
+     * @param bandOffsets the array of the band offsets.
+     */
+    public BandedSampleModel(int dataType, int w, int h, int scanlineStride,
+            int bankIndices[], int bandOffsets[]) {
+        super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new BandedSampleModel(dataType, w, h, w, bankIndices,
+                bandOffsets);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+        int size = scanlineStride * height;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size, numBanks);
+            break;
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size, numBanks);
+            break;
+        case DataBuffer.TYPE_FLOAT:
+            data = new DataBufferFloat(size, numBanks);
+            break;
+        case DataBuffer.TYPE_DOUBLE:
+            data = new DataBufferDouble(size, numBanks);
+            break;
+        }
+
+        return data;
+
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int[] bands) {
+        if (bands.length > numBands) {
+            // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int indices[] = new int[bands.length];
+        int offsets[] = new int[bands.length];
+
+        for (int i = 0; i < bands.length; i++) {
+            indices[i] = bankIndices[bands[i]];
+            offsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new BandedSampleModel(dataType, width, height, scanlineStride,
+                indices, offsets);
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE: {
+            byte bdata[];
+
+            if (obj == null) {
+                bdata = new byte[numBands];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                bdata[i] = (byte) getSample(x, y, i, data);
+            }
+
+            obj = bdata;
+            break;
+        }
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT: {
+            short sdata[];
+
+            if (obj == null) {
+                sdata = new short[numBands];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                sdata[i] = (short) getSample(x, y, i, data);
+            }
+
+            obj = sdata;
+            break;
+        }
+        case DataBuffer.TYPE_INT: {
+            int idata[];
+
+            if (obj == null) {
+                idata = new int[numBands];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                idata[i] = getSample(x, y, i, data);
+            }
+
+            obj = idata;
+            break;
+        }
+        case DataBuffer.TYPE_FLOAT: {
+            float fdata[];
+
+            if (obj == null) {
+                fdata = new float[numBands];
+            } else {
+                fdata = (float[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                fdata[i] = getSampleFloat(x, y, i, data);
+            }
+
+            obj = fdata;
+            break;
+        }
+        case DataBuffer.TYPE_DOUBLE: {
+            double ddata[];
+
+            if (obj == null) {
+                ddata = new double[numBands];
+            } else {
+                ddata = (double[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                ddata[i] = getSampleDouble(x, y, i, data);
+            }
+
+            obj = ddata;
+            break;
+        }
+        }
+
+        return obj;
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElem(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b]);
+    }
+
+    @Override
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemDouble(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b]);
+    }
+
+    @Override
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemFloat(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b]);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        int tmp = hash >>> 8;
+        hash <<= 8;
+        hash |= tmp;
+
+        return hash ^ 0x55;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[] = (byte[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, bdata[i] & 0xff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sdata[] = (short[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, sdata[i] & 0xffff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int idata[] = (int[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, idata[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fdata[] = (float[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, fdata[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double ddata[] = (double[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, ddata[i], data);
+            }
+            break;
+        }
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemDouble(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemFloat(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElem(bankIndices[b], y * scanlineStride + x +
+                       bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+
+    }
+
+}
+
diff --git a/awt/java/awt/image/BufferStrategy.java b/awt/java/awt/image/BufferStrategy.java
new file mode 100644
index 0000000..e0508f0
--- /dev/null
+++ b/awt/java/awt/image/BufferStrategy.java
@@ -0,0 +1,72 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.BufferCapabilities;
+import java.awt.Graphics;
+
+/**
+ * The BufferStrategy abstract class provides an opportunity 
+ * to organize the buffers for a Canvas or Window. The BufferStrategy
+ * implementation depends on hardware and software limitations.
+ * These limitations are detectible through the capabilities 
+ * object which can be obtained by the GraphicsConfiguration of the Canvas 
+ * or Window.
+ */
+public abstract class BufferStrategy {
+
+    /**
+     * Returns true if the drawing buffer was lost since the last call 
+     * of getDrawGraphics. 
+     * 
+     * @return true if the drawing buffer was lost since the last call 
+     * of getDrawGraphics, false otherwise.
+     */
+    public abstract boolean contentsLost();
+
+    /**
+     * Returns true if the drawing buffer is restored from a lost state. 
+     * 
+     * @return true if the drawing buffer is restored from a lost state,
+     * false otherwise.
+     */
+    public abstract boolean contentsRestored();
+
+    /**
+     * Gets the BufferCapabilities of BufferStrategy.
+     * 
+     * @return the BufferCapabilities of BufferStrategy.
+     */
+    public abstract BufferCapabilities getCapabilities();
+
+    /**
+     * Gets the Graphics object to use to draw to the buffer.
+     * 
+     * @return the Graphics object to use to draw to the buffer.
+     */
+    public abstract Graphics getDrawGraphics();
+
+    /**
+     * Shows the next available buffer.
+     */
+    public abstract void show();
+
+}
diff --git a/awt/java/awt/image/BufferedImage.java b/awt/java/awt/image/BufferedImage.java
new file mode 100644
index 0000000..d305d66
--- /dev/null
+++ b/awt/java/awt/image/BufferedImage.java
@@ -0,0 +1,931 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.BufferedImageSource;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * The BufferedImage class describes an Image which contains a buffer 
+ * of image data and includes a ColorModel and a Raster for this data.
+ * This class provides methods for obtaining and setting the Raster
+ * and for manipulating the ColorModel parameters.
+ */
+public class BufferedImage extends 
+Image implements WritableRenderedImage, Transparency{
+
+    /** 
+     * The Constant TYPE_CUSTOM indicates that Image type 
+     * is unknown. 
+     */
+    public static final int TYPE_CUSTOM = 0;
+
+    /** 
+     * The Constant TYPE_INT_RGB indicates an image with 
+     * 8 bit RGB color components, it has a DirectColorModel 
+     * without alpha. 
+     */
+    public static final int TYPE_INT_RGB = 1;
+
+    /** 
+     * The Constant TYPE_INT_ARGB indicates an image with 
+     * 8 bit RGBA color components, it has a DirectColorModel 
+     * with alpha. 
+     */
+    public static final int TYPE_INT_ARGB = 2;
+
+    /** 
+     * The Constant TYPE_INT_ARGB_PRE indicates an image with 
+     * 8 bit RGBA color components, it has a DirectColorModel 
+     * with alpha, and image data is premultiplied by alpha. 
+     */
+    public static final int TYPE_INT_ARGB_PRE = 3;
+
+    /** 
+     * The Constant TYPE_INT_BGR indicates an image with 
+     * 8 bit RGB color components, BGR color model 
+     * (with the colors Blue, Green, and Red). There is no 
+     * alpha. The image has a DirectColorModel. 
+     */
+    public static final int TYPE_INT_BGR = 4;
+
+    /** 
+     * The Constant TYPE_3BYTE_BGR indicates an image with 
+     * 8 bit RGB color components, BGR color model 
+     * (with the colors Blue, Green, and Red stored in 3 bytes). 
+     * There is no alpha. The image has a ComponentColorModel. 
+     */
+    public static final int TYPE_3BYTE_BGR = 5;
+
+    /** 
+     * The Constant TYPE_4BYTE_ABGR indicates an image with 
+     * 8 bit RGBA color components stored in 3 bytes and 1 byte of alpha.
+     * It has a ComponentColorModel with alpha.  
+     */
+    public static final int TYPE_4BYTE_ABGR = 6;
+
+    /** 
+     * The Constant TYPE_4BYTE_ABGR_PRE indicates an image with 
+     * 8 bit RGBA color components stored in 3 bytes and 1 byte 
+     * for alpha. The image has a ComponentColorModel with alpha. 
+     * The color data is premultiplied with alpha.
+     */
+    public static final int TYPE_4BYTE_ABGR_PRE = 7;
+
+    /** 
+     * The Constant TYPE_USHORT_565_RGB indicates an image with 
+     * 565 RGB color components (5-bits red, 6-bits green, 5-bits blue) 
+     * with no alpha. This image has a DirectColorModel. 
+     */
+    public static final int TYPE_USHORT_565_RGB = 8;
+
+    /** 
+     * The Constant TYPE_USHORT_555_RGB indicates an image with 
+     * 555 RGB color components (5-bits red, 5-bits green, 5-bits blue) 
+     * with no alpha. This image has a DirectColorModel. 
+     */
+    public static final int TYPE_USHORT_555_RGB = 9;
+
+    /** 
+     * The Constant TYPE_BYTE_GRAY indicates a unsigned byte 
+     * image. This image has a ComponentColorModel with 
+     * a CS_GRAY ColorSpace. 
+     */
+    public static final int TYPE_BYTE_GRAY = 10;
+
+    /** 
+     * The Constant TYPE_USHORT_GRAY indicates an unsigned short 
+     * image. This image has a ComponentColorModel with a CS_GRAY 
+     * ColorSpace. 
+     */
+    public static final int TYPE_USHORT_GRAY = 11;
+
+    /** 
+     * The Constant TYPE_BYTE_BINARY indicates an opaque byte-packed
+     * 1, 2 or 4 bit image. The image has an IndexColorModel without 
+     * alpha.  
+     */
+    public static final int TYPE_BYTE_BINARY = 12;
+
+    /** 
+     * The Constant TYPE_BYTE_INDEXED indicates an indexed byte image. 
+     */
+    public static final int TYPE_BYTE_INDEXED = 13;
+
+    /** The Constant ALPHA_MASK. */
+    private static final int ALPHA_MASK = 0xff000000;
+
+    /** The Constant RED_MASK. */
+    private static final int RED_MASK = 0x00ff0000;
+
+    /** The Constant GREEN_MASK. */
+    private static final int GREEN_MASK = 0x0000ff00;
+
+    /** The Constant BLUE_MASK. */
+    private static final int BLUE_MASK = 0x000000ff;
+
+    /** The Constant RED_BGR_MASK. */
+    private static final int RED_BGR_MASK = 0x000000ff;
+
+    /** The Constant GREEN_BGR_MASK. */
+    private static final int GREEN_BGR_MASK = 0x0000ff00;
+
+    /** The Constant BLUE_BGR_MASK. */
+    private static final int BLUE_BGR_MASK = 0x00ff0000;
+
+    /** The Constant RED_565_MASK. */
+    private static final int RED_565_MASK = 0xf800;
+
+    /** The Constant GREEN_565_MASK. */
+    private static final int GREEN_565_MASK = 0x07e0;
+
+    /** The Constant BLUE_565_MASK. */
+    private static final int BLUE_565_MASK = 0x001f;
+
+    /** The Constant RED_555_MASK. */
+    private static final int RED_555_MASK = 0x7c00;
+
+    /** The Constant GREEN_555_MASK. */
+    private static final int GREEN_555_MASK = 0x03e0;
+
+    /** The Constant BLUE_555_MASK. */
+    private static final int BLUE_555_MASK = 0x001f;
+
+    /** The cm. */
+    private ColorModel cm;
+
+    /** The raster. */
+    private final WritableRaster raster;
+
+    /** The image type. */
+    private final int imageType;
+
+    /** The properties. */
+    private Hashtable<?, ?> properties;
+
+    // Surface of the Buffered Image - used for blitting one Buffered Image 
+    // on the other one or on the Component
+    /** The image surf. */
+    private final ImageSurface imageSurf;
+
+    /**
+     * Instantiates a new BufferedImage with the specified ColorModel,
+     * and WritableRaster objects. The Raster data can be
+     * be divided or multiplied by alpha. It depends on the 
+     * alphaPremultiplied state in the ColorModel.
+     * 
+     * @param cm the ColorModel of the new image.
+     * @param raster the WritableRaster of the new image.
+     * @param isRasterPremultiplied if true the data of the specified
+     * Raster is premultiplied by alpha.
+     * @param properties the properties of new Image.
+     */
+    public BufferedImage(ColorModel cm, WritableRaster raster,
+            boolean isRasterPremultiplied, Hashtable<?, ?> properties) {
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.4D=The raster is incompatible with this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+        }
+
+        if (raster.getMinX() != 0 || raster.getMinY() != 0) {
+            // awt.228=minX or minY of this raster not equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.228")); //$NON-NLS-1$
+        }
+
+        this.cm  = cm;
+        this.raster = raster;
+        this.properties = properties;
+
+        coerceData(isRasterPremultiplied);
+
+        imageType = Surface.getType(cm, raster);
+
+        imageSurf = createImageSurface(imageType);
+    }
+
+    /**
+     * Instantiates a new BufferedImage with the specified width, height
+     * predefined image type (TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED) 
+     * and the specified IndexColorModel.
+     * 
+     * @param width the width of new image.
+     * @param height the height of new image.
+     * @param imageType the predefined image type. 
+     * @param cm the specified IndexColorModel.
+     */
+    public BufferedImage(int width, int height, int imageType,
+            IndexColorModel cm) {
+        switch (imageType) {
+        case TYPE_BYTE_BINARY:
+            if (cm.hasAlpha()) {
+                // awt.227=This image type can't have alpha
+                throw new IllegalArgumentException(Messages.getString("awt.227")); //$NON-NLS-1$
+            }
+            int pixel_bits = 0;
+            int mapSize = cm.getMapSize();
+            if (mapSize <= 2) {
+                pixel_bits = 1;
+            } else if (mapSize <= 4) {
+                pixel_bits = 2;
+            } else if (mapSize <= 16) {
+                pixel_bits = 4;
+            } else {
+                // awt.221=The imageType is TYPE_BYTE_BINARY and the color map has more than 16 entries
+                throw new IllegalArgumentException(Messages.getString("awt.221")); //$NON-NLS-1$
+            }
+
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width,
+                    height, 1, pixel_bits, null);
+            break;
+
+        case TYPE_BYTE_INDEXED:
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, 1, null);
+            break;
+
+        default:
+            // awt.222=The imageType is not TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED
+            throw new IllegalArgumentException(Messages.getString("awt.222")); //$NON-NLS-1$
+
+        }
+
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.223=The imageType is not compatible with ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.223")); //$NON-NLS-1$
+        }
+
+        this.cm = cm;
+        this.imageType = imageType;
+        imageSurf = createImageSurface(imageType);
+
+    }
+
+    /**
+     * Instantiates a new BufferedImage with the specified width, height
+     * and predefined image type.
+     * 
+     * @param width the width of new image.
+     * @param height the height of new image.
+     * @param imageType the predefined image type. 
+     */
+    public BufferedImage(int width, int height, int imageType) {
+
+        switch (imageType) {
+        case TYPE_INT_RGB:
+            cm = new DirectColorModel(24, RED_MASK, GREEN_MASK, BLUE_MASK);
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_INT_ARGB:
+            cm = ColorModel.getRGBdefault();
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_INT_ARGB_PRE:
+            cm = new DirectColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    32,
+                    RED_MASK,
+                    GREEN_MASK,
+                    BLUE_MASK,
+                    ALPHA_MASK,
+                    true,
+                    DataBuffer.TYPE_INT);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_INT_BGR:
+            cm = new DirectColorModel(24,
+                    RED_BGR_MASK,
+                    GREEN_BGR_MASK,
+                    BLUE_BGR_MASK);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_3BYTE_BGR: {
+            int bits[] = { 8, 8, 8 };
+            int bandOffsets[] = { 2, 1, 0 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    bits, 
+                    false, 
+                    false, 
+                    Transparency.OPAQUE, 
+                    DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, width * 3, 3, bandOffsets, null);
+            }
+            break;
+
+        case TYPE_4BYTE_ABGR: {
+            int bits[] = { 8, 8, 8, 8 };
+            int bandOffsets[] = { 3, 2, 1, 0 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    bits, 
+                    true, 
+                    false, 
+                    Transparency.TRANSLUCENT, 
+                    DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, width * 4, 4, bandOffsets, null);
+            }
+            break;
+
+        case TYPE_4BYTE_ABGR_PRE: {
+            int bits[] = { 8, 8, 8, 8 };
+            int bandOffsets[] = { 3, 2, 1, 0 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    bits, 
+                    true, 
+                    true, 
+                    Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, width * 4, 4, bandOffsets, null);
+            }
+            break;
+
+        case TYPE_USHORT_565_RGB:
+            cm = new DirectColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    16,
+                    RED_565_MASK,
+                    GREEN_565_MASK,
+                    BLUE_565_MASK,
+                    0,
+                    false,
+                    DataBuffer.TYPE_USHORT);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_USHORT_555_RGB:
+            cm = new DirectColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    15,
+                    RED_555_MASK,
+                    GREEN_555_MASK,
+                    BLUE_555_MASK,
+                    0,
+                    false,
+                    DataBuffer.TYPE_USHORT);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_BYTE_GRAY: {
+            int bits[] = { 8 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                    bits, 
+                    false, 
+                    false, 
+                    Transparency.OPAQUE, 
+                    DataBuffer.TYPE_BYTE);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            }
+            break;
+
+        case TYPE_USHORT_GRAY: {
+            int bits[] = { 16 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                    bits, 
+                    false, 
+                    false, 
+                    Transparency.OPAQUE, 
+                    DataBuffer.TYPE_USHORT);
+            raster = cm.createCompatibleWritableRaster(width, height);
+            }
+            break;
+
+        case TYPE_BYTE_BINARY: {
+            int colorMap[] = { 0, 0xffffff };
+            cm = new IndexColorModel(1, 2, colorMap, 0, false, -1,
+                    DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width,
+                    height, 1, 1, null);
+            }
+            break;
+
+        case TYPE_BYTE_INDEXED: {
+            int colorMap[] = new int[256];
+            int i = 0;
+            for (int r = 0; r < 256; r += 51) {
+                for (int g = 0; g < 256; g += 51) {
+                    for (int b = 0; b < 256; b += 51) {
+                        colorMap[i] = (r << 16) | (g << 8) | b;
+                        i++;
+                    }
+                }
+            }
+
+            int gray = 0x12;
+            for (; i < 256; i++, gray += 6) {
+                colorMap[i] = (gray << 16) | (gray << 8) | gray;
+            }
+            cm = new IndexColorModel(8, 256, colorMap, 0, false, -1,
+                    DataBuffer.TYPE_BYTE);
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, 1, null);
+
+            }
+            break;
+        default:
+            // awt.224=Unknown image type
+            throw new IllegalArgumentException(Messages.getString("awt.224")); //$NON-NLS-1$
+        }
+        this.imageType = imageType;
+        imageSurf = createImageSurface(imageType);
+    }
+
+    @Override
+    public Object getProperty(String name, ImageObserver observer) {
+        return getProperty(name);
+    }
+
+    public Object getProperty(String name) {
+        if(name == null) {
+            // awt.225=Property name is null
+            throw new NullPointerException(Messages.getString("awt.225")); //$NON-NLS-1$
+        }
+        if (properties == null) {
+            return Image.UndefinedProperty;
+        }
+        Object property = properties.get(name);
+        if (property == null) {
+            property = Image.UndefinedProperty;
+        }
+        return property;
+    }
+
+    public WritableRaster copyData(WritableRaster outRaster) {
+        if (outRaster == null) {
+            outRaster = Raster.createWritableRaster(raster.getSampleModel(),
+                    new Point(raster.getSampleModelTranslateX(),
+                            raster.getSampleModelTranslateY()));
+        }
+
+        int w = outRaster.getWidth();
+        int h = outRaster.getHeight();
+        int minX = outRaster.getMinX();
+        int minY = outRaster.getMinY();
+
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outRaster.setDataElements(minX, minY, w, h, data);
+
+        return outRaster;
+    }
+
+    public Raster getData(Rectangle rect) {
+        int minX = rect.x;
+        int minY = rect.y;
+        int w = rect.width;
+        int h = rect.height;
+
+        SampleModel sm = raster.getSampleModel();
+        SampleModel nsm = sm.createCompatibleSampleModel(w, h);
+        WritableRaster outr = Raster.createWritableRaster(nsm, 
+                rect.getLocation());
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outr.setDataElements(minX, minY, w, h, data);
+        return outr;
+    }
+
+    public Vector<RenderedImage> getSources() {
+        return null;
+    }
+
+    public String[] getPropertyNames() {
+        if (properties == null) {
+            return null;
+        }
+        Vector<String> v = new Vector<String>();
+        for (Enumeration<?> e = properties.keys(); e.hasMoreElements();) {
+            try {
+                v.add((String) e.nextElement());
+            } catch (ClassCastException ex) {
+            }
+        }
+        int size = v.size();
+        if (size > 0) {
+            String names[] = new String[size];
+            for (int i = 0; i < size; i++) {
+                names[i] = v.elementAt(i);
+            }
+            return names;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the string representation of this BufferedImage object.
+     * 
+     * @return the string representation of this BufferedImage object.
+     */
+    @Override
+    public String toString() {
+        return "BufferedImage@" + Integer.toHexString(hashCode()) + //$NON-NLS-1$
+            ": type = " + imageType + " " + cm + " " + raster; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    public WritableRaster getWritableTile(int tileX, int tileY) {
+        return raster;
+    }
+
+    /**
+     * Gets the WritableRaster of this BufferedImage.
+     * 
+     * @return the WritableRaster of this BufferedImage.
+     */
+    public WritableRaster getRaster() {
+        return raster;
+    }
+
+    /**
+     * Gets a WritableRaster object which contains the alpha channel of 
+     * BufferedImage object with ColorModel objects that supports 
+     * a separate alpha channel such as ComponentColorModel 
+     * or DirectColorModel.
+     * 
+     * @return the WritableRaster object which contains the alpha 
+     * channel of this BufferedImage. 
+     */
+    public WritableRaster getAlphaRaster() {
+        return cm.getAlphaRaster(raster);
+    }
+
+    public void removeTileObserver(TileObserver to) {
+    }
+
+    public void addTileObserver(TileObserver to) {
+    }
+
+    public SampleModel getSampleModel() {
+        return raster.getSampleModel();
+    }
+
+    public void setData(Raster r) {
+
+        Rectangle from = r.getBounds();
+        Rectangle to = raster.getBounds();
+        Rectangle intersection = to.intersection(from);
+
+        int minX = intersection.x;
+        int minY = intersection.y;
+        int w = intersection.width;
+        int h = intersection.height;
+
+        Object data = null;
+
+        data = r.getDataElements(minX, minY, w, h, data);
+        raster.setDataElements(minX, minY, w, h, data);
+    }
+
+    public Raster getTile(int tileX, int tileY) {
+        if (tileX == 0 && tileY == 0) {
+            return raster;
+        }
+        // awt.226=Both tileX and tileY are not equal to 0
+        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
+    }
+
+    public Raster getData() {
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+
+        WritableRaster outr = Raster.createWritableRaster(
+                raster.getSampleModel(),
+                new Point(raster.getSampleModelTranslateX(),
+                raster.getSampleModelTranslateY()));
+
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outr.setDataElements(minX, minY, w, h, data);
+
+        return outr;
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return new BufferedImageSource(this, properties);
+    }
+
+    @Override
+    public int getWidth(ImageObserver observer) {
+        return raster.getWidth();
+    }
+
+    @Override
+    public int getHeight(ImageObserver observer) {
+        return raster.getHeight();
+    }
+
+    public ColorModel getColorModel() {
+        return cm;
+    }
+
+    /**
+     * Gets the rectangular area of this BufferedImage as a subimage.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param w the width of the subimage.
+     * @param h the height of the subimage.
+     * 
+     * @return the BufferedImage.
+     */
+    public BufferedImage getSubimage(int x, int y, int w, int h) {
+        WritableRaster wr = raster.createWritableChild(x, y, w, h, 0, 0, null);
+        return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), properties);
+    }
+
+    public Point[] getWritableTileIndices() {
+        Point points[] = new Point[1];
+        points[0] = new Point(0, 0);
+        return points;
+    }
+
+    /**
+     * Creates the Graphics2D object which allows to draw into 
+     * this BufferedImage.
+     * 
+     * @return the graphics2D object.
+     */
+    public Graphics2D createGraphics() {
+        GraphicsEnvironment ge = 
+            GraphicsEnvironment.getLocalGraphicsEnvironment();
+        //return ge.createGraphics(this);
+        //???AWT hack, FIXME
+        //return AndroidGraphics2D.getInstance();
+        //throw new RuntimeException("Not implemented!");
+        return null;
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        return createGraphics();
+    }
+
+    /**
+     * Coerces the data to achieve the state which is specified by 
+     * the isAlphaPremultiplied variable. 
+     * 
+     * @param isAlphaPremultiplied the is alpha premultiplied state.
+     */
+    public void coerceData(boolean isAlphaPremultiplied) {
+        if (cm.hasAlpha() && 
+                cm.isAlphaPremultiplied() != isAlphaPremultiplied) {
+            cm = cm.coerceData(raster, isAlphaPremultiplied);
+        }
+    }
+
+    /**
+     * Gets an array of colors in the TYPE_INT_ARGB color model and 
+     * default sRGB colorspace of the specified area of this
+     * BufferedImage. The result array is composed by the following
+     * algirithm:
+     * <p> 
+     * pixel   = rgbArray[offset + (y-startY)*scansize + (x-startX)]
+     * 
+     * @param startX the start X area coordinate. 
+     * @param startY the start Y area coordinate.
+     * @param w the width of the area. 
+     * @param h the height of the area.
+     * @param rgbArray the result array will be stored to this array.
+     * @param offset the offset of the rgbArray array. 
+     * @param scansize the scanline stride for the rgbArray.
+     * 
+     * @return an array of colors for the specified area.
+     */
+    public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray,
+            int offset, int scansize) {
+        if (rgbArray == null) {
+            rgbArray = new int[offset + h * scansize];
+        }
+
+        int off = offset;
+        for (int y = startY; y < startY + h; y++, off += scansize) {
+            int i = off;
+            for (int x = startX; x < startX + w; x++, i++) {
+                rgbArray[i] = cm.getRGB(raster.getDataElements(x, y, null));
+            }
+        }
+        return rgbArray;
+    }
+
+    /**
+     * Sets RGB values from the specified array to the specified
+     * BufferedImage area. The pixels are in the default RGB color model 
+     * (TYPE_INT_ARGB) and default sRGB color space.
+     * 
+     * @param startX the start X coordinate.
+     * @param startY the start Y coordinate.
+     * @param w the width of the BufferedImage area.
+     * @param h the height of the BufferedImage area.
+     * @param rgbArray the array of RGB values.
+     * @param offset the offset of the rgbArray array. 
+     * @param scansize the scanline stride for the rgbArray.
+     */
+    public void setRGB(int startX, int startY, int w, int h, int[] rgbArray,
+            int offset, int scansize) {
+        int off = offset;
+        for (int y = startY; y < startY + h; y++, off += scansize) {
+            int i = off;
+            for (int x = startX; x < startX + w; x++, i++) {
+                raster.setDataElements(x, y, 
+                        cm.getDataElements(rgbArray[i], null));
+            }
+        }
+    }
+
+    /**
+     * Sets a the specified RGB value to the specified pixel of
+     * this BufferedImage. The pixel should be in the default 
+     * RGB color model (TYPE_INT_ARGB) and default sRGB color space. 
+     *  
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param rgb the RGB value to be set.
+     */
+    public synchronized void setRGB(int x, int y, int rgb) {
+        raster.setDataElements(x, y, cm.getDataElements(rgb, null));
+    }
+
+    public boolean isTileWritable(int tileX, int tileY) {
+        if (tileX == 0 && tileY == 0) {
+            return true;
+        }
+        // awt.226=Both tileX and tileY are not equal to 0
+        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
+    }
+
+    public void releaseWritableTile(int tileX, int tileY) {
+    }
+
+    /**
+     * Gets a color in the TYPE_INT_ARGB color model and default 
+     * sRGB colorspace of the specified pixel. 
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * 
+     * @return the color of the specified pixel in the TYPE_INT_ARGB 
+     * color model and default sRGB colorspace. 
+     */
+    public int getRGB(int x, int y) {
+        return cm.getRGB(raster.getDataElements(x, y, null));
+    }
+
+    /**
+     * Returnes true if alpha is premultiplied, 
+     * false if alpha is not premultiplied or there is no alpha.
+     * 
+     * @return true if alpha is premultiplied, 
+     * false if alpha is not premultiplied or there is no alpha.
+     */
+    public boolean isAlphaPremultiplied() {
+        return cm.isAlphaPremultiplied();
+    }
+
+    public boolean hasTileWriters() {
+        return true;
+    }
+
+    @Override
+    public void flush() {
+        imageSurf.dispose();
+    }
+
+    public int getWidth() {
+        return raster.getWidth();
+    }
+
+    /**
+     * Gets the image type.
+     * 
+     * @return the image type.
+     */
+    public int getType() {
+        return imageType;
+    }
+
+    public int getTileWidth() {
+        return raster.getWidth();
+    }
+
+    public int getTileHeight() {
+        return raster.getHeight();
+    }
+
+    public int getTileGridYOffset() {
+        return raster.getSampleModelTranslateY();
+    }
+
+    public int getTileGridXOffset() {
+        return raster.getSampleModelTranslateX();
+    }
+
+    public int getNumYTiles() {
+        return 1;
+    }
+
+    public int getNumXTiles() {
+        return 1;
+    }
+
+    public int getMinY() {
+        return raster.getMinY();
+    }
+
+    public int getMinX() {
+        return raster.getMinX();
+    }
+
+    public int getMinTileY() {
+        return 0;
+    }
+
+    public int getMinTileX() {
+        return 0;
+    }
+
+    public int getHeight() {
+        return raster.getHeight();
+    }
+
+    /**
+     * Creates the image surface.
+     * 
+     * @param type the type
+     * 
+     * @return the image surface
+     */
+    private ImageSurface createImageSurface(int type) {
+        return new ImageSurface(getColorModel(), getRaster(), type);
+    }
+
+    /**
+     * Gets the image surface.
+     * 
+     * @return the image surface
+     */
+    ImageSurface getImageSurface() {
+        return imageSurf;
+    }
+
+    public int getTransparency() {
+        return cm.getTransparency();
+    }
+}
+
diff --git a/awt/java/awt/image/BufferedImageFilter.java b/awt/java/awt/image/BufferedImageFilter.java
new file mode 100644
index 0000000..44b3c2e
--- /dev/null
+++ b/awt/java/awt/image/BufferedImageFilter.java
@@ -0,0 +1,375 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BufferedImageFilter class provides filtering operations to 
+ * the BufferedImage objects using operators which implement
+ * BufferedImageOp interface.
+ */
+public class BufferedImageFilter extends ImageFilter implements Cloneable {
+    
+    /** The Constant accessor. */
+    private static final AwtImageBackdoorAccessor accessor = AwtImageBackdoorAccessor.getInstance();
+
+    /** The op. */
+    private BufferedImageOp op;
+
+    /** The raster. */
+    private WritableRaster raster;
+
+    /** The i data. */
+    private int iData[];
+    
+    /** The b data. */
+    private byte bData[];
+
+    /** The width. */
+    private int width;
+    
+    /** The height. */
+    private int height;
+
+    /** The cm. */
+    private ColorModel cm;
+
+    /** The forced rgb. */
+    private boolean forcedRGB = false;
+    
+    /** The transfer type. */
+    private int transferType = DataBuffer.TYPE_UNDEFINED;
+
+    /**
+     * Instantiates a new BufferedImageFilter with the specified
+     * BufferedImageOp operator.
+     * 
+     * @param op the specified BufferedImageOp operator.
+     * 
+     * @throws NullPointerException if BufferedImageOp is null.
+     */
+    public BufferedImageFilter(BufferedImageOp op) {
+        if (op == null) {
+            throw new NullPointerException(Messages.getString("awt.05")); //$NON-NLS-1$
+        }
+        this.op = op;
+    }
+
+    /**
+     * Gets the BufferedImageOp operator associated with this 
+     * BufferedImageFilter object.
+     * 
+     * @return the BufferedImageOp associated with this 
+     * BufferedImageFilter object.
+     */
+    public BufferedImageOp getBufferedImageOp() {
+        return op;
+    }
+
+    @Override
+    public void setDimensions(int width, int height) {
+        this.width = width;
+        this.height = height;
+        // Stop image consuming if no pixels expected.
+        if (width <= 0 || height <= 0) {
+            consumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            reset();
+        }
+    }
+
+    @Override
+    public void setColorModel(ColorModel model) {
+        if (this.cm != null && this.cm != model && raster != null) {
+            forceRGB();
+        } else {
+            this.cm = model;
+        }
+    }
+
+    @Override
+    public void setPixels(
+            int x, int y, int
+            w, int h,
+            ColorModel model, byte[] pixels,
+            int off, int scansize
+    ) {
+        setPixels(x, y, w, h, model, pixels, off, scansize, true);
+    }
+
+    @Override
+    public void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model, int[] pixels,
+            int off, int scansize
+    ) {
+        setPixels(x, y, w, h, model, pixels, off, scansize, false);
+    }
+
+    @Override
+    public void imageComplete(int status) {
+        if (status == STATICIMAGEDONE || status == SINGLEFRAMEDONE) {
+            BufferedImage bim = new BufferedImage(cm, raster, cm.isAlphaPremultiplied, null);
+            bim = op.filter(bim, null);
+            DataBuffer dstDb = bim.getRaster().getDataBuffer();
+            ColorModel dstCm = bim.getColorModel();
+            int dstW = bim.getWidth();
+            int dstH = bim.getHeight();
+
+            consumer.setDimensions(dstW, dstH);
+
+            if (dstDb.getDataType() == DataBuffer.TYPE_INT) {
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataInt(dstDb), 0, dstW);
+            } else if (dstDb.getDataType() == DataBuffer.TYPE_BYTE) {
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataByte(dstDb), 0, dstW);
+            } else {
+                int dstData[] = bim.getRGB(0, 0, dstW, dstH, null, 0, dstW);
+                dstCm = ColorModel.getRGBdefault();
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, dstData, 0, dstW);
+            }
+        } else if (status == IMAGEERROR || status == IMAGEABORTED) {
+            reset();
+        }
+
+        consumer.imageComplete(status);
+    }
+
+    /**
+     * Sets the pixels.
+     * 
+     * @param x the x
+     * @param y the y
+     * @param w the w
+     * @param h the h
+     * @param model the model
+     * @param pixels the pixels
+     * @param off the off
+     * @param scansize the scansize
+     * @param isByteData the is byte data
+     */
+    private void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model, Object pixels,
+            int off, int scansize, boolean isByteData
+    ) {
+        // Check bounds
+        // Need to copy only the pixels that will fit into the destination area
+        if (x < 0) {
+            w -= x;
+            off += x;
+            x = 0;
+        }
+
+        if (y < 0) {
+            h -= y;
+            off += y * scansize;
+            y = 0;
+        }
+
+        if (x + w > width) {
+            w = width - x;
+        }
+
+        if (y + h > height) {
+            h = height - y;
+        }
+
+        if (w <= 0 || h <= 0) {
+            return;
+        }
+
+        // Check model
+        if (this.cm == null) {
+            setColorModel(model);
+        } else if (model == null) {
+            model = this.cm;
+        } else if (!model.equals(this.cm)) {
+            forceRGB();
+        }
+
+        boolean canArraycopy;
+        // Process pixels
+        switch(transferType) {
+            case DataBuffer.TYPE_UNDEFINED: {
+                if (isByteData) {
+                    transferType = DataBuffer.TYPE_BYTE;
+                    createRaster(transferType);
+                    //bData = new byte[width*height];
+                    canArraycopy = !forcedRGB;
+                    break;
+                }
+                transferType = DataBuffer.TYPE_INT;
+                createRaster(transferType);
+                //iData = new int[width*height];
+                canArraycopy = !forcedRGB || model.equals(ColorModel.getRGBdefault());
+                break;
+            } // And proceed to copy the pixels
+            case DataBuffer.TYPE_INT: {
+                if (isByteData) { // There are int data already but the new data are bytes
+                    forceRGB();
+                    canArraycopy = false;
+                    break;
+                } else if (!forcedRGB || model.equals(ColorModel.getRGBdefault())) {
+                    canArraycopy = true;
+                    break;
+                } // Else fallback to the RGB conversion
+            }
+            case DataBuffer.TYPE_BYTE: {
+                if (isByteData && !forcedRGB) {
+                    canArraycopy = true;
+                    break;
+                }
+
+                // RGB conversion
+                canArraycopy = false;
+                break;
+            } default: {
+                throw new IllegalStateException(Messages.getString("awt.06")); //$NON-NLS-1$
+            }
+        }
+
+        off += x;
+        int maxOffset = off + h * scansize;
+        int dstOffset = x + y * width;
+
+        if (canArraycopy) {
+            Object dstArray = isByteData ? (Object) bData : (Object) iData;
+            for (; off < maxOffset; off += scansize, dstOffset += width) {
+                System.arraycopy(pixels, off, dstArray, dstOffset, w);
+            }
+        } else {
+            // RGB conversion
+            for (; off < maxOffset; off += scansize, dstOffset += width) {
+                int srcPos = off;
+                int dstPos = dstOffset;
+                int maxDstPos = dstOffset + w;
+                for (; dstPos < maxDstPos; dstPos++, srcPos++) {
+                    iData[dstPos] = model.getRGB(
+                            isByteData ?
+                            ((byte[])pixels)[srcPos] :
+                            ((int[])pixels)[srcPos]
+                    );
+                }
+            }
+        }
+    }
+
+    /**
+     * Force rgb.
+     */
+    private void forceRGB() {
+        if (!forcedRGB) {
+            forcedRGB = true;
+            int size = width*height;
+            int rgbData[] = new int[size];
+
+            if (bData != null) {
+                for (int i=0; i<size; i++) {
+                    rgbData[i] = cm.getRGB(bData[i]);
+                }
+            } else if (iData != null) {
+                for (int i=0; i<size; i++) {
+                    rgbData[i] = cm.getRGB(iData[i]);
+                }
+            }
+
+            cm = ColorModel.getRGBdefault();
+            DataBufferInt db = new DataBufferInt(rgbData, size);
+            int masks[] = new int[] {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000};
+            raster = Raster.createPackedRaster(db, width, height, width, masks, null);
+            iData = accessor.getDataInt(db);
+            bData = null;
+            transferType = DataBuffer.TYPE_INT;
+        }
+    }
+
+    /**
+     * Reset.
+     */
+    private void reset() {
+        width = 0;
+        height = 0;
+        forcedRGB = false;
+        cm = null;
+        iData = null;
+        bData = null;
+        transferType = DataBuffer.TYPE_UNDEFINED;
+        raster = null;
+    }
+
+    /**
+     * Creates the raster.
+     * 
+     * @param dataType the data type
+     */
+    private void createRaster(int dataType) {
+        boolean createdValidBuffer = false;
+        try{
+            raster = cm.createCompatibleWritableRaster(width, height);
+            int rasterType = raster.getDataBuffer().getDataType();
+            if (rasterType == dataType) {
+                switch (rasterType) {
+                    case DataBuffer.TYPE_INT: {
+                        iData = accessor.getDataInt(raster.getDataBuffer());
+                        if (iData != null) {
+                            createdValidBuffer = true;
+                        }
+                        break;
+                    }
+                    case DataBuffer.TYPE_BYTE: {
+                        bData = accessor.getDataByte(raster.getDataBuffer());
+                        if (bData != null) {
+                            createdValidBuffer = true;
+                        }
+                        break;
+                    }
+                    default:
+                        createdValidBuffer = false;
+                }
+
+                if(cm == ColorModel.getRGBdefault()){
+                    forcedRGB = true;
+                }
+            } else {
+                createdValidBuffer = false;
+            }
+        } catch(Exception e) {
+            createdValidBuffer = false;
+        }
+
+        if (createdValidBuffer == false) {
+            cm = ColorModel.getRGBdefault();
+            raster = cm.createCompatibleWritableRaster(width, height);
+            iData = accessor.getDataInt(raster.getDataBuffer());
+            bData = null;
+            forcedRGB = true;
+        }
+    }
+}
diff --git a/awt/java/awt/image/BufferedImageOp.java b/awt/java/awt/image/BufferedImageOp.java
new file mode 100644
index 0000000..85b9f4e
--- /dev/null
+++ b/awt/java/awt/image/BufferedImageOp.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The BufferedImageOp interface provides methods for performing transformations
+ * from source data to destination data for BufferedImage objects. An object
+ * implementing this interface can be passed into a BufferedImageFilter 
+ * to operate on a BufferedImage.
+ */
+public interface BufferedImageOp {
+    
+    /**
+     * Creates a destination image with the specified BufferedImage and
+     * ColorModel; this destination image is empty and has the correct size 
+     * and number of bands.   
+     * 
+     * @param src the source BufferedImage.
+     * @param destCM the destination ColorModel.
+     * 
+     * @return the BufferedImage.
+     */
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM);
+
+    /**
+     * Performs a filter operation on the source BufferedImage and stores 
+     * the resulting BufferedImage to the destination BufferedImage. If 
+     * the destination BufferedImage is null, a BufferedImage with an 
+     * appropriate ColorModel is created.
+     * 
+     * @param src the source BufferedImage.
+     * @param dest the destination BufferedImage, where the result is stored.
+     * 
+     * @return the filtered BufferedImage.
+     */
+    public BufferedImage filter(BufferedImage src, BufferedImage dest);
+
+    /**
+     * Gets the bounds of filtered image.
+     * 
+     * @param src the source BufferedImage to be filtered.
+     * 
+     * @return the rectangle bounds of filtered image.
+     */
+    public Rectangle2D getBounds2D(BufferedImage src);
+
+    /**
+     * Gets the point of the destination image which corresponds
+     * to the specified point in the source image. 
+     * 
+     * @param srcPt the point of the source image.
+     * @param dstPt the point where the result will be stored.
+     * 
+     * @return the destination point.
+     */
+    public Point2D getPoint2D(Point2D srcPt, Point2D dstPt);
+
+    /**
+     * Gets the RenderingHints of the BufferedImageOp.
+     * 
+     * @return the RenderingHints of the BufferedImageOp.
+     */
+    public RenderingHints getRenderingHints();
+}
diff --git a/awt/java/awt/image/ByteLookupTable.java b/awt/java/awt/image/ByteLookupTable.java
new file mode 100644
index 0000000..043b533
--- /dev/null
+++ b/awt/java/awt/image/ByteLookupTable.java
@@ -0,0 +1,134 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+/**
+ * The ByteLookupTable class provides functionality for lookup operations, 
+ * and is defined by an input byte array for bands or components of 
+ * image and an offset value.
+ * The offset value will be subtracted from the input values before 
+ * indexing the input arrays. The output of a lookup operation is 
+ * represented as an array of unsigned bytes.
+ */
+public class ByteLookupTable extends LookupTable {
+    
+    /** The data. */
+    private byte data[][];
+    
+    /**
+     * Instantiates a new ByteLookupTable with the specified offset value
+     * and the specified byte array which represents the lookup table for
+     * all bands.
+     * 
+     * @param offset the offset value.
+     * @param data the data array of bytes.
+     */
+    public ByteLookupTable(int offset, byte[] data) {
+        super(offset, 1);
+        if (data.length < 1)
+            throw new IllegalArgumentException("Length of data should not be less then one");
+        this.data = new byte[1][data.length];
+        // The data array stored as a reference
+        this.data[0] = data;
+    }
+
+    /**
+     * Instantiates a new ByteLookupTable with the specified offset value
+     * and the specified byte array of arrays which represents the lookup table
+     * for each band.
+     * 
+     * @param offset the offset value.
+     * @param data the data array of bytes array for each band.
+     */
+    public ByteLookupTable(int offset, byte[][] data) {
+        super(offset, data.length);
+        this.data = new byte[data.length][data[0].length];
+        for (int i = 0; i < data.length; i++) {
+            // The data array for each band stored as a reference
+            this.data[i] = data[i];
+        }
+    }
+
+    /**
+     * Gets the lookup table of this ByteLookupTable object. If 
+     * this ByteLookupTable object has one byte array for all bands, 
+     * the returned array length is one.
+     * 
+     * @return the lookup table of this ByteLookupTable object.
+     */
+    public final byte[][] getTable() {
+        // Returns data by reference
+        return data;
+    }
+
+    @Override
+    public int[] lookupPixel(int[] src, int[] dst) {
+        if (dst == null) {
+            dst = new int[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+
+    /**
+     * Returns a byte array which contains samples of the specified
+     * pixel which is translated with the lookup table of this 
+     * ByteLookupTable object. The resulted array is stored to
+     * the dst array.
+     * 
+     * @param src the source array.
+     * @param dst the destination array where the result can be stored.
+     * 
+     * @return the byte array of translated samples of a pixel.
+     */
+    public byte[] lookupPixel(byte[] src, byte[] dst) {
+        if (dst == null) {
+            dst = new byte[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+}
diff --git a/awt/java/awt/image/ColorConvertOp.java b/awt/java/awt/image/ColorConvertOp.java
new file mode 100644
index 0000000..6d503d7
--- /dev/null
+++ b/awt/java/awt/image/ColorConvertOp.java
@@ -0,0 +1,711 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */  
+package java.awt.image;
+
+
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.gl.color.ColorConverter;
+import org.apache.harmony.awt.gl.color.ColorScaler;
+import org.apache.harmony.awt.gl.color.ICC_Transform;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ColorConvertOp class converts the pixels of the data in the
+ * source image with the specified ColorSpace objects or an array 
+ * of ICC_Profile objects. The result pixels are scaled to the precision
+ * of the destination image.
+ */
+public class ColorConvertOp implements BufferedImageOp, RasterOp {
+    // Unused but required by interfaces
+    /** The rendering hints. */
+    RenderingHints renderingHints;
+        
+    // Sequence consisting of ColorSpace and ICC_Profile elements
+    /** The conversion sequence. */
+    Object conversionSequence[] = new ICC_Profile[0]; // To eliminate checks for null
+    
+    // Not null if ColorConvertOp is constructed from the array of ICC profiles
+    /** The mid profiles. */
+    private ICC_Profile midProfiles[];   
+
+    /** The cc. */
+    private final ColorConverter cc = new ColorConverter();
+    
+    /** The t creator. */
+    private final ICC_TransfomCreator tCreator = new ICC_TransfomCreator();
+    
+    /** The is icc. */
+    private boolean isICC = true;
+    
+    
+    // Cached ICC_Transform
+    /**
+     * The Class ICC_TransfomCreator.
+     */
+    private class ICC_TransfomCreator {
+        
+        /** The transform. */
+        private ICC_Transform transform;
+        
+        /** The max components. */
+        private int maxComponents;
+        
+        /**
+         * For the full ICC case.
+         * 
+         * @param src the src
+         * @param dst the dst
+         * @param convSeq the conv seq
+         * 
+         * @return the transform
+         */
+        public ICC_Transform getTransform(ICC_Profile src, ICC_Profile dst, ICC_Profile convSeq[]) {
+            if (transform != null &&
+               src == transform.getSrc() && 
+               dst == transform.getDst()) {
+                return transform;
+            }
+            
+            int length = convSeq.length;
+            int srcFlg = 0, dstFlg = 0;
+            
+            if (length == 0 || src != convSeq[0]) {
+                if (src != null) {
+                    srcFlg = 1; // need src profile
+                }
+            }
+            if (length == 0 || dst != convSeq[length-1]) {
+                if (dst != null) {
+                    dstFlg = 1; // need dst profile
+                }
+            }
+            
+            ICC_Profile profiles[];
+            int nProfiles = length + srcFlg + dstFlg;
+            if (nProfiles == length) {
+                profiles = convSeq;
+            } else {
+                profiles = new ICC_Profile[nProfiles];
+                int pos = 0;
+                if (srcFlg != 0) {
+                    profiles[pos++] = src;
+                }
+                for (int i=0; i<length; i++) {
+                    profiles[pos++] = convSeq[i];
+                }
+                if (dstFlg != 0) {
+                    profiles[pos++] = dst;
+                }
+            }
+            
+            return transform = new ICC_Transform(profiles);
+        }
+        
+        /**
+         * Used only when there are non-ICC color spaces.
+         * Returns sequence of non-ICC color spaces and ICC transforms
+         * made from src, dst and conversionSequence.
+         * 
+         * @param src the src
+         * @param dst the dst
+         * 
+         * @return the sequence
+         */
+        public Object[] getSequence(Object src, Object dst) {
+            ArrayList<Object> profiles = new ArrayList<Object>(10);
+            ArrayList<Object> sequence = new ArrayList<Object>(10);         
+
+            // We need this profile anyway
+            ICC_Profile xyzProfile = ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
+
+            Object conversionFirst = null, conversionLast = null;
+            int conversionLength = conversionSequence.length;
+            if (conversionLength > 0) {
+                conversionFirst = conversionSequence[0];
+                conversionLast = conversionSequence[conversionLength-1];
+            }
+
+            boolean iccSequenceStarted = false;
+            
+            if (src != conversionFirst && src != null) {
+                if (src instanceof ICC_Profile) {
+                    profiles.add(src);
+                    iccSequenceStarted = true;
+                } else {
+                    profiles.add(xyzProfile);
+                    sequence.add(src); // Add non-ICC color space to the sequence
+                } 
+            } else {
+                profiles.add(xyzProfile);
+            }
+            
+            for (int i=0; i<conversionLength; i++) {
+                if (conversionSequence[i] instanceof ICC_Profile) {
+                    profiles.add(conversionSequence[i]);
+                    iccSequenceStarted = true;
+                } else if (iccSequenceStarted) {
+                    profiles.add(xyzProfile);
+                    
+                    // Eliminate same profiles if there are any
+                    // (e.g. xyzProfile may occur several times)
+                    Object prev = profiles.get(0);
+                    for (int k=1; k<profiles.size(); k++) {                     
+                        if (prev == profiles.get(k)) {
+                            k--;
+                            profiles.remove(k);
+                        }
+                        prev = profiles.get(k);
+                    }
+                    
+                    // If only one profile left we skip the transform -
+                    // it can be only CIEXYZ
+                    if (profiles.size() > 1) {
+                        sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
+
+                        // Add non-ICC color space to the sequence
+                        sequence.add(conversionSequence[i]);
+                    }
+                    
+                    profiles.clear();
+                    profiles.add(xyzProfile);
+                    iccSequenceStarted = false; // Sequence of ICC profiles is processed
+                } else { // Add non-ICC color space to the sequence
+                    sequence.add(conversionSequence[i]); 
+                }               
+            }
+            
+            if (dst != conversionLast && dst != null) { // Add last profile if needed
+                if (dst instanceof ICC_Profile) {
+                    profiles.add(dst);
+                    iccSequenceStarted = true;
+                } else if (iccSequenceStarted) {
+                    profiles.add(xyzProfile);
+                } else {
+                    sequence.add(dst); // Add last non-ICC color space to the sequence
+                }
+            }
+            
+            if (iccSequenceStarted) { // Make last transform if needed
+                sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
+                if (dst != null && !(dst instanceof ICC_Profile)) {
+                    sequence.add(dst); // Add last non-ICC color space to the
+                                        // sequence
+                }
+            }
+
+            // Calculate max number of components
+            // This number will be used for memory allocation
+            maxComponents = 0;
+            Object o;           
+            for (int i=0, size = sequence.size(); i<size; i++) {
+                o = sequence.get(i);
+                if (o instanceof ICC_Transform) {
+                    ICC_Transform t = (ICC_Transform) o; 
+                    maxComponents = 
+                        (maxComponents > t.getNumInputChannels() + 1) ?
+                            maxComponents : 
+                            t.getNumInputChannels() + 1;
+                    maxComponents = 
+                        (maxComponents > t.getNumOutputChannels() + 1) ?
+                            maxComponents : 
+                            t.getNumOutputChannels() + 1;
+                } else {
+                    ColorSpace cs = (ColorSpace) o;
+                    maxComponents = 
+                        (maxComponents > cs.getNumComponents() + 1) ?
+                            maxComponents : 
+                            cs.getNumComponents() + 1;
+                }               
+            }
+            
+            return sequence.toArray();
+        }
+    }
+    
+    /**
+     * Instantiates a new ColorConvertOp object using two specified
+     * ColorSpace objects.
+     * 
+     * @param srcCS the source ColorSpace.
+     * @param dstCS the destination ColorSpace.
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(ColorSpace srcCS, ColorSpace dstCS, RenderingHints hints) {
+        if (srcCS == null || dstCS == null) {
+            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
+        }
+        
+        renderingHints = hints;
+        
+        boolean srcICC = srcCS instanceof ICC_ColorSpace;
+        boolean dstICC = dstCS instanceof ICC_ColorSpace;
+        
+        if (srcICC && dstICC) {
+            conversionSequence = new ICC_Profile[2];
+        } else {
+            conversionSequence = new Object[2];
+            isICC = false;
+        }
+        
+        if (srcICC) {
+            conversionSequence[0] = ((ICC_ColorSpace) srcCS).getProfile();
+        } else {
+            conversionSequence[0] = srcCS;
+        }
+        
+        if (dstICC) {
+            conversionSequence[1] = ((ICC_ColorSpace) dstCS).getProfile();
+        } else {
+            conversionSequence[1] = dstCS;
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object from the specified 
+     * ICC_Profile objects.
+     * 
+     * @param profiles the array of ICC_Profile objects.
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(ICC_Profile profiles[], RenderingHints hints) {
+        if (profiles == null) {
+            throw new NullPointerException(Messages.getString("awt.25C")); //$NON-NLS-1$
+        }
+
+        renderingHints = hints;
+        
+        // This array is not used in the program logic, so don't need to copy it
+        // Store it only to return back
+        midProfiles = profiles;  
+        
+        conversionSequence = new ICC_Profile[midProfiles.length];
+        
+        // Add profiles to the conversion sequence
+        for (int i=0, length=midProfiles.length; i<length; i++) {
+            conversionSequence[i] = midProfiles[i];
+        }       
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object using the specified
+     * ColorSpace object.
+     * 
+     * @param cs the destination ColorSpace or an intermediate ColorSpace.
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(ColorSpace cs, RenderingHints hints) {
+        if (cs == null) {
+            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
+        }
+        
+        renderingHints = hints;
+                        
+        if (cs instanceof ICC_ColorSpace) {
+            conversionSequence = new ICC_Profile[1];
+            conversionSequence[0] = ((ICC_ColorSpace) cs).getProfile();
+        } else {
+            conversionSequence = new Object[1];
+            conversionSequence[0] = cs;
+            isICC = false;
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object which converts from 
+     * a source color space to a destination color space.
+     * 
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(RenderingHints hints) {
+        renderingHints = hints;
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (conversionSequence.length < 2) {
+            throw new IllegalArgumentException(Messages.getString("awt.25D")); //$NON-NLS-1$
+        }
+
+        ICC_Profile srcPf = null, dstPf = null; // unused if isICC is false
+        int nSrcColorComps, nDstColorComps;
+        Object first = conversionSequence[0];
+        Object last = conversionSequence[conversionSequence.length - 1];
+        
+        // Get the number of input/output color components
+        if (isICC) {
+            srcPf = (ICC_Profile) first;
+            dstPf = (ICC_Profile) last;
+            nSrcColorComps = srcPf.getNumComponents();
+            nDstColorComps = dstPf.getNumComponents();
+        } else {
+            if (first instanceof ICC_Profile) {
+                srcPf = (ICC_Profile) first;
+                nSrcColorComps = srcPf.getNumComponents();
+            } else {
+                nSrcColorComps = ((ColorSpace) first).getNumComponents();
+            }
+            
+            if (last instanceof ICC_Profile) {
+                dstPf = (ICC_Profile) last;
+                nDstColorComps = dstPf.getNumComponents();
+            } else {
+                nDstColorComps = ((ColorSpace) last).getNumComponents();
+            }
+        }
+
+        // Check that source and destination rasters are compatible with
+        // transforms and with each other
+        if (src.getNumBands() != nSrcColorComps) {
+            // awt.25E=Incorrect number of source raster bands. Should be equal
+            //          to the number of color components of source colorspace.
+            throw new IllegalArgumentException(Messages.getString("awt.25E")); //$NON-NLS-1$
+        }
+        
+        if (dst != null) { // Check destination raster
+            if (dst.getNumBands() !=
+                nDstColorComps) {
+                // awt.25F=Incorrect number of destination raster bands. Should
+                //          be equal to the number of color components of destination
+                //          colorspace.
+                throw new IllegalArgumentException(Messages.getString("awt.25F")); //$NON-NLS-1$
+            }
+            
+            if (src.getWidth() != dst.getWidth() ||
+               src.getHeight() != dst.getHeight()) {
+                throw new IllegalArgumentException(Messages.getString("awt.260")); //$NON-NLS-1$
+            }
+            
+        } else {
+          dst = createCompatibleDestRaster(src);
+        }
+        
+        if (isICC) {
+            // Create transform
+            ICC_Transform t = tCreator.getTransform(srcPf, dstPf, 
+                    (ICC_Profile[])conversionSequence); 
+            cc.translateColor(t, src, dst);         
+        } else {
+            Object[] sequence = tCreator.getSequence(null, null);
+            
+            // Get data from the source raster
+            ColorScaler scaler = new ColorScaler();
+            scaler.loadScalingData(src, null);
+            float tmpData[][] = scaler.scaleNormalize(src);
+            
+            // Get source and destination color spaces
+            ColorSpace srcCS = (srcPf == null) ? 
+                    (ColorSpace) first:
+                    new ICC_ColorSpace(srcPf);
+            ColorSpace dstCS = (dstPf == null) ? 
+                    (ColorSpace) last:
+                    new ICC_ColorSpace(dstPf);
+                    
+            applySequence(sequence, tmpData, srcCS, dstCS);
+            
+            scaler.loadScalingData(dst, null);
+            scaler.unscaleNormalized(dst, tmpData);
+        }
+
+        return dst;
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
+        // If destination color model is passed only one line needed
+        if (destCM != null) {
+            return new BufferedImage(destCM,
+                    destCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()),
+                    destCM.isAlphaPremultiplied(), 
+                    null);
+        }
+        
+        int nSpaces = conversionSequence.length;
+        
+        if (nSpaces < 1) {
+            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
+        }
+        
+        // Get destination color space
+        Object destination = conversionSequence[nSpaces-1];
+        ColorSpace dstCS = 
+            (destination instanceof ColorSpace) ? 
+                    (ColorSpace) destination : 
+                    new ICC_ColorSpace((ICC_Profile) destination);
+        
+        ColorModel srcCM = src.getColorModel();     
+        ColorModel dstCM = new ComponentColorModel(dstCS, 
+                srcCM.hasAlpha(), 
+                srcCM.isAlphaPremultiplied(),
+                srcCM.getTransparency(),
+                srcCM.getTransferType());
+        
+        return new BufferedImage(dstCM,
+                destCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()),
+                destCM.isAlphaPremultiplied(), 
+                null);
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (dst == null && conversionSequence.length < 1) {
+            throw new IllegalArgumentException(Messages.getString("awt.262")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        // First handle index color model
+        if (srcCM instanceof IndexColorModel) {            
+            src = ((IndexColorModel) srcCM).convertToIntDiscrete(src.getRaster(), false);
+        }
+        ColorSpace srcCS = srcCM.getColorSpace();        
+                
+        BufferedImage res;
+        boolean isDstIndex = false;
+        if (dst != null) {
+          
+          if (src.getWidth() != dst.getWidth() ||
+             src.getHeight() != dst.getHeight()) {
+              throw new IllegalArgumentException(Messages.getString("awt.263")); //$NON-NLS-1$
+          }
+
+            if (dst.getColorModel() instanceof IndexColorModel) {
+                isDstIndex = true;
+                res = createCompatibleDestImage(src, null);
+            } else {                
+                res = dst;
+            }           
+        } else {
+            res = createCompatibleDestImage(src, null);
+        }
+        ColorModel dstCM = res.getColorModel();
+        ColorSpace dstCS = dstCM.getColorSpace();
+        
+        ICC_Profile srcPf = null, dstPf = null;
+        if (srcCS instanceof ICC_ColorSpace) {
+            srcPf = ((ICC_ColorSpace)srcCS).getProfile();
+        }
+        if (dstCS instanceof ICC_ColorSpace) {
+            dstPf = ((ICC_ColorSpace)dstCS).getProfile();
+        }
+        
+        boolean isFullICC = isICC && srcPf != null && dstPf != null;
+        
+        if (isFullICC) {
+            ICC_Transform t =
+                    tCreator.getTransform(srcPf, dstPf, (ICC_Profile[]) conversionSequence);
+            cc.translateColor(t, src, res);
+        } else { // Perform non-ICC transform
+            Object sequence[] = tCreator.getSequence(
+                    srcPf == null ? (Object) srcCS : srcPf,
+                    dstPf == null ? (Object) dstCS : dstPf);            
+            
+            int srcW = src.getWidth();
+            int srcH = src.getHeight();
+            int numPixels = srcW*srcH;
+
+            // Load all pixel data into array tmpData 
+            float tmpData[][] = 
+                new float[numPixels][tCreator.maxComponents];
+            for (int row=0, dataPos=0; row<srcW; row++) {
+                for (int col=0; col<srcH; col++) {
+                    tmpData[dataPos] = 
+                        srcCM.getNormalizedComponents(
+                                src.getRaster().getDataElements(row, col, null), 
+                                tmpData[dataPos], 0);
+                    dataPos++;
+                }
+            }
+
+            // Copy alpha channel if needed
+            float alpha[] = null;
+            int alphaIdx = srcCM.numComponents - 1;
+            if (srcCM.hasAlpha() && dstCM.hasAlpha()) {
+                alpha = new float[numPixels];
+                for (int i=0; i<numPixels; i++) {
+                    alpha[i] = tmpData[i][alphaIdx];
+                }
+            }
+            
+            // Translate colors
+            applySequence(sequence, tmpData, srcCS, dstCS);
+
+            // Copy alpha if needed
+            if (dstCM.hasAlpha()) {
+                alphaIdx = dstCM.numComponents - 1;
+                if (alpha != null) {
+                    for (int i=0; i<numPixels; i++) {
+                        tmpData[i][alphaIdx] = alpha[i];
+                    }                   
+                } else {
+                    for (int i=0; i<numPixels; i++) {
+                        tmpData[i][alphaIdx] = 1f;
+                    }                                       
+                }
+            }
+            
+            // Store data back to the image            
+            for (int row=0, dataPos=0; row<srcW; row++) {
+                for (int col=0; col<srcH; col++) {
+                    res.getRaster().setDataElements(row, col, 
+                            dstCM.getDataElements(tmpData[dataPos++], 0 , null));
+                }
+            }
+        }               
+
+        if (isDstIndex) { // Convert image into indexed color
+            Graphics2D g2d = dst.createGraphics();
+            g2d.drawImage(res, 0, 0, null);
+            g2d.dispose();
+            return dst;
+        }
+        
+        return res;
+    }
+
+    /**
+     * Apply sequence.
+     * 
+     * @param sequence the sequence
+     * @param tmpData the tmp data
+     * @param srcCS the src cs
+     * @param dstCS the dst cs
+     */
+    private void applySequence(
+            Object sequence[], 
+            float tmpData[][],
+            ColorSpace srcCS, 
+            ColorSpace dstCS
+            ) {
+        ColorSpace xyzCS = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
+        
+        int numPixels = tmpData.length;
+        
+        // First transform...
+        if (sequence[0] instanceof ICC_Transform) { // ICC
+            ICC_Transform t = (ICC_Transform)sequence[0];
+            cc.translateColor(t, tmpData, srcCS, xyzCS, numPixels);
+        } else { // non ICC
+            for (int k=0; k<numPixels; k++) {
+                tmpData[k] = srcCS.toCIEXYZ(tmpData[k]); 
+            }
+            cc.loadScalingData(xyzCS); // prepare for scaling XYZ
+        }
+        
+        for (Object element : sequence) {
+            if (element instanceof ICC_Transform) {
+                ICC_Transform t = (ICC_Transform)element;
+                cc.translateColor(t, tmpData, null, null, numPixels);
+            } else {
+                ColorSpace cs = (ColorSpace) element;
+                for (int k=0; k<numPixels; k++) {
+                    tmpData[k] = cs.fromCIEXYZ(tmpData[k]);
+                    tmpData[k] = cs.toCIEXYZ(tmpData[k]); 
+                }
+            }
+        }
+        
+        // Last transform...
+        if (sequence[sequence.length-1] instanceof ICC_Transform) { // ICC
+            ICC_Transform t = (ICC_Transform)sequence[sequence.length-1];
+            cc.translateColor(t, tmpData, xyzCS, dstCS, numPixels);
+        } else { // non ICC
+            for (int k=0; k<numPixels; k++) {
+                tmpData[k] = dstCS.fromCIEXYZ(tmpData[k]); 
+            }
+        }
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt != null) {
+            dstPt.setLocation(srcPt);
+            return dstPt;
+        }
+        return new Point2D.Float((float) srcPt.getX(), (float) srcPt.getY());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        int nComps = 0;
+        int nSpaces = conversionSequence.length;
+        
+        if (nSpaces < 2) {
+            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
+        }
+        
+        Object lastCS = conversionSequence[nSpaces-1];
+        if (lastCS instanceof ColorSpace) {
+            nComps = ((ColorSpace) lastCS).getNumComponents();
+        } else {
+            nComps = ((ICC_Profile) lastCS).getNumComponents(); 
+        }
+        
+        // Calculate correct data type
+        int dstDataType = src.getDataBuffer().getDataType();
+        if (dstDataType != DataBuffer.TYPE_BYTE &&
+           dstDataType != DataBuffer.TYPE_SHORT) {
+                dstDataType = DataBuffer.TYPE_SHORT;
+        }
+        
+        return Raster.createInterleavedRaster(
+                dstDataType, 
+                src.getWidth(),
+                src.getHeight(),
+                nComps,
+                new Point(src.getMinX(), src.getMinY())
+            );
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return src.getRaster().getBounds();
+    }
+
+    /**
+     * Gets an array of ICC_Profiles objects which constructs
+     * this ColorConvertOp object or returns null if this ColorConvertOp 
+     * is not constructed from array of ICC_Profiles.
+     * 
+     * @return an array of ICC_Profiles objects which constructs
+     * this ColorConvertOp object or returns null if this ColorConvertOp 
+     * is not constructed from array of ICC_Profiles.
+     */
+    public final ICC_Profile[] getICC_Profiles() {
+        if (midProfiles != null) {
+            return midProfiles;
+        }
+        return null;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return renderingHints;
+    }    
+}
diff --git a/awt/java/awt/image/ColorModel.java b/awt/java/awt/image/ColorModel.java
new file mode 100644
index 0000000..945c087
--- /dev/null
+++ b/awt/java/awt/image/ColorModel.java
@@ -0,0 +1,911 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class ColorModel.
+ */
+public abstract class ColorModel implements Transparency {
+
+    /** The pixel_bits. */
+    protected int pixel_bits;  // Pixel length in bits
+
+    /** The transfer type. */
+    protected int transferType;
+
+    /** The cs. */
+    ColorSpace cs;
+
+    /** The has alpha. */
+    boolean hasAlpha;
+
+    /** The is alpha premultiplied. */
+    boolean isAlphaPremultiplied;
+
+    /** The transparency. */
+    int transparency;
+
+    /** The num color components. */
+    int numColorComponents;
+
+    /** The num components. */
+    int numComponents;
+
+    /** The bits. */
+    int[] bits;             // Array of components masks 
+
+    /** The max values. */
+    int[] maxValues = null; // Max values that may be represent by color
+                            // components
+
+    /** The max bit length. */
+    int maxBitLength;       // Max length color components in bits
+
+    /** The RG bdefault. */
+    private static ColorModel RGBdefault;
+
+    /**
+     * Instantiates a new color model with the specified values.
+     * 
+     * @param pixel_bits the pixel length in bits
+     * @param bits the array of component masks
+     * @param cspace the colorspace
+     * @param hasAlpha whether the color model has alpha
+     * @param isAlphaPremultiplied whether the alpha is premultiplied
+     * @param transparency the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     */
+    protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace,
+            boolean hasAlpha, boolean isAlphaPremultiplied, int transparency,
+            int transferType) {
+
+        if (pixel_bits < 1) {
+            // awt.26B=The number of bits in the pixel values is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.26B")); //$NON-NLS-1$
+        }
+
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        int sum = 0;
+        for (int element : bits) {
+            if (element < 0) {
+                // awt.26D=The elements in bits is less than 0
+                throw new IllegalArgumentException(Messages.getString("awt.26D")); //$NON-NLS-1$
+            }
+            sum += element;
+        }
+
+        if (sum < 1) {
+            // awt.26E=The sum of the number of bits in bits is less than 1
+            throw new NullPointerException(Messages.getString("awt.26E")); //$NON-NLS-1$
+        }
+
+        if (cspace == null) {
+            // awt.26F=The cspace is null
+            throw new IllegalArgumentException(Messages.getString("awt.26F")); //$NON-NLS-1$
+        }
+
+        if (transparency < Transparency.OPAQUE ||
+               transparency > Transparency.TRANSLUCENT) {
+            // awt.270=The transparency is not a valid value
+            throw new IllegalArgumentException(Messages.getString("awt.270")); //$NON-NLS-1$
+        }
+
+        this.pixel_bits = pixel_bits;
+        this.bits = bits.clone();
+
+        maxValues = new int[bits.length];
+        maxBitLength = 0;
+        for (int i = 0; i < maxValues.length; i++) {
+            maxValues[i] = (1 << bits[i]) - 1;
+            if (bits[i] > maxBitLength) {
+                maxBitLength = bits[i];
+            }
+        }
+
+        cs = cspace;
+        this.hasAlpha = hasAlpha;
+        this.isAlphaPremultiplied = isAlphaPremultiplied;
+        numColorComponents = cs.getNumComponents();
+
+        if (hasAlpha) {
+            numComponents = numColorComponents + 1;
+        } else {
+            numComponents = numColorComponents;
+        }
+
+        this.transparency = transparency;
+        this.transferType = transferType;
+
+    }
+
+    /**
+     * Instantiates a new color model with the specified pixel bit depth.
+     * The transferType is chosen based on the pixel bits, and the other
+     * data fields are given default values.
+     * 
+     * @param bits the array of component masks
+     */
+    public ColorModel(int bits) {
+
+        if (bits < 1) {
+            // awt.271=The number of bits in bits is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.271")); //$NON-NLS-1$
+        }
+
+        pixel_bits = bits;
+        transferType = getTransferType(bits);
+        cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        hasAlpha = true;
+        isAlphaPremultiplied = false;
+        transparency = Transparency.TRANSLUCENT;
+
+        numColorComponents = 3;
+        numComponents = 4;
+
+        this.bits = null;
+    }
+
+    /**
+     * Gets the data elements from the specified component array, transforming
+     * them according to rules of the color model.
+     * 
+     * @param components the components
+     * @param offset the offset in the normComponents array
+     * @param obj the array that the result is written to: an array of values
+     * whose length must be the number of components used by the color model and 
+     * whose type depends on the transfer type (based on the pixel bit depth),
+     * or null to have the appropriate array created
+     * 
+     * @return the array of data elements
+     */
+    public Object getDataElements(int[] components, int offset, Object obj) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the data elements from the specified array of normalized components.
+     * 
+     * @param normComponents the array normalized components
+     * @param normOffset the offset in the normComponents array
+     * @param obj the array that the result is written to: an array of values
+     * whose length must be the number of components used by the color model and 
+     * whose type depends on the transfer type (based on the pixel bit depth),
+     * or null to have the appropriate array created
+     * 
+     * @return the array of data elements
+     */
+    public Object getDataElements(float[] normComponents, int normOffset,
+            Object obj) {
+        int unnormComponents[] = getUnnormalizedComponents(normComponents,
+                normOffset, null, 0);
+        return getDataElements(unnormComponents, 0, obj);
+    }
+
+    /**
+     * Gets the data elements corresponding to the pixel determined by the 
+     * RGB data.
+     * 
+     * @param rgb the rgb int that defines the pixel
+     * @param pixel the array that the result is written to: an array of values
+     * whose length must be the number of components used by the color model and 
+     * whose type depends on the transfer type (based on the pixel bit depth),
+     * or null to have the appropriate array created
+     * 
+     * @return the array of data elements
+     */
+    public Object getDataElements(int rgb, Object pixel) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the child raster corresponding to the alpha channel of the 
+     * specified writable raster, or null if alpha is not supported.
+     * 
+     * @param raster the raster
+     * 
+     * @return the alpha raster
+     */
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        return null;
+    }
+
+    /**
+     * Creates a new color model by coercing the data in the writable raster 
+     * in accordance with the alpha strategy of this color model.
+     * 
+     * @param raster the raster
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this 
+     * color model
+     * 
+     * @return the new color model
+     */
+    public ColorModel coerceData(WritableRaster raster,
+            boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. 
+        // It could be reveled such way:
+        // ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB,
+        // false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+        // System.out.println(cm.toString());
+        return "ColorModel: Color Space = " + cs.toString() + "; has alpha = " //$NON-NLS-1$ //$NON-NLS-2$
+                + hasAlpha + "; is alpha premultipied = " //$NON-NLS-1$
+                + isAlphaPremultiplied + "; transparency = " + transparency //$NON-NLS-1$
+                + "; number color components = " + numColorComponents //$NON-NLS-1$
+                + "; pixel bits = " + pixel_bits + "; transfer type = " //$NON-NLS-1$ //$NON-NLS-2$
+                + transferType;
+    }
+
+    /**
+     * Gets the components of the pixel determined by the data array.
+     * 
+     * @param pixel the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * @param components the the array where the resulting components
+     * are written (or null to prompt the method to create the return array)
+     * @param offset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the array of components
+     */
+    public int[] getComponents(Object pixel, int[] components, int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the normalized components of the pixel determined by the data array.
+     * 
+     * @param pixel the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * @param normComponents the array where the resulting normalised components
+     * are written (or null to prompt the method to create the return array)
+     * @param normOffset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the array of normalized components
+     */
+    public float[] getNormalizedComponents(Object pixel,
+            float[] normComponents, int normOffset) {
+
+        if (pixel == null) {
+            // awt.294=pixel is null
+            throw new NullPointerException(Messages.getString("awt.294")); //$NON-NLS-1$
+        }
+
+        int unnormComponents[] = getComponents(pixel, null, 0);
+        return getNormalizedComponents(unnormComponents, 0, normComponents,
+                normOffset);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ColorModel)) {
+            return false;
+        }
+        ColorModel cm = (ColorModel) obj;
+
+        return (pixel_bits == cm.getPixelSize() &&
+               transferType == cm.getTransferType() &&
+               cs.getType() == cm.getColorSpace().getType() &&
+               hasAlpha == cm.hasAlpha() &&
+               isAlphaPremultiplied == cm.isAlphaPremultiplied() &&
+               transparency == cm.getTransparency() &&
+               numColorComponents == cm.getNumColorComponents() &&
+               numComponents == cm.getNumComponents() &&
+               Arrays.equals(bits, cm.getComponentSize()));
+    }
+
+    /**
+     * Gets the red component of the pixel determined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the red
+     */
+    public int getRed(Object inData) {
+        return getRed(constructPixel(inData));
+    }
+
+    /**
+     * Gets the RGB int corresponding to the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the int that gives the pixel's colors in RGB format
+     */
+    public int getRGB(Object inData) {
+        return (getAlpha(inData) << 24 | getRed(inData) << 16 |
+               getGreen(inData) << 8 | getBlue(inData));
+    }
+
+    /**
+     * Gets the green component of the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the green
+     */
+    public int getGreen(Object inData) {
+        return getGreen(constructPixel(inData));
+    }
+
+    /**
+     * Gets the blue component of the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the blue
+     */
+    public int getBlue(Object inData) {
+        return getBlue(constructPixel(inData));
+    }
+
+    /**
+     * Gets the alpha component of the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the alpha
+     */
+    public int getAlpha(Object inData) {
+        return getAlpha(constructPixel(inData));
+    }
+
+    /**
+     * Creates a compatible writable raster.
+     * 
+     * @param w the width of the desired writable raster
+     * @param h the height of the desired writable raster
+     * 
+     * @return the writable raster
+     */
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if the sample model is compatible with this color model.
+     * 
+     * @param sm the sample model
+     * 
+     * @return true, if the sample model is compatible with this color model
+     */
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates the compatible sample model.
+     * 
+     * @param w the width of the desired sample model
+     * @param h the height of the desired sample model
+     * 
+     * @return the sample model
+     */
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if the specified raster is compatible with this color model.
+     * 
+     * @param raster the raster to inspect
+     * 
+     * @return true, if the raster is compatible with this color model
+     */
+    public boolean isCompatibleRaster(Raster raster) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the color space of this color model.
+     * 
+     * @return the color space
+     */
+    public final ColorSpace getColorSpace() {
+        return cs;
+    }
+
+    /**
+     * Gets the normalized components corresponding to the specified 
+     * unnormalized components.
+     * 
+     * @param components the array of unnormalized components
+     * @param offset the offset where the components should be read 
+     * from the array of unnormalized components
+     * @param normComponents the array where the resulting normalised components
+     * are written (or null to prompt the method to create the return array)
+     * @param normOffset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the normalized components
+     */
+    public float[] getNormalizedComponents(int[] components, int offset,
+            float normComponents[], int normOffset) {
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (normComponents == null) {
+            normComponents = new float[numComponents + normOffset];
+        }
+
+        if (hasAlpha && isAlphaPremultiplied) {
+            float normAlpha =
+                (float) components[offset + numColorComponents] /
+                    maxValues[numColorComponents];
+            if (normAlpha != 0.0f) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComponents[normOffset + i] =
+                        components[offset + i] /
+                            (normAlpha * maxValues[i]);
+                }
+                normComponents[normOffset + numColorComponents] = normAlpha;
+            } else {
+                for (int i = 0; i < numComponents; i++) {
+                    normComponents[normOffset + i] = 0.0f;
+                }
+            }
+        } else {
+            for (int i = 0; i < numComponents; i++) {
+                normComponents[normOffset + i] =
+                    (float) components[offset + i] /
+                        maxValues[i];
+            }
+        }
+
+        return normComponents;
+    }
+
+    /**
+     * Gets the data element corresponding to the unnormalized components.
+     * 
+     * @param components the components
+     * @param offset the offset to start reading the components from the 
+     * array of components
+     * 
+     * @return the data element
+     */
+    public int getDataElement(int[] components, int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the unnormalized components corresponding to the specified 
+     * normalized components.
+     * 
+     * @param normComponents the array of normalized components
+     * @param normOffset the offset where the components should be read 
+     * from the array of normalized components
+     * @param components the array where the resulting unnormalised components
+     * are written (or null to prompt the method to create the return array)
+     * @param offset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the unnormalized components
+     */
+    public int[] getUnnormalizedComponents(float normComponents[],
+            int normOffset, int components[], int offset) {
+
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (normComponents.length - normOffset < numComponents) {
+            // awt.273=The length of normComponents minus normOffset is less than numComponents
+            throw new IllegalArgumentException(Messages.getString("awt.273")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[numComponents + offset];
+        } else {
+            if (components.length - offset < numComponents) {
+                // awt.272=The length of components minus offset is less than numComponents
+                throw new IllegalArgumentException(Messages.getString("awt.272")); //$NON-NLS-1$
+            }
+        }
+
+        if (hasAlpha && isAlphaPremultiplied) {
+            float alpha = normComponents[normOffset + numColorComponents];
+            for (int i = 0; i < numColorComponents; i++) {
+                components[offset + i] = (int) (normComponents[normOffset + i]
+                        * maxValues[i] * alpha + 0.5f);
+            }
+            components[offset + numColorComponents] =
+                (int) (normComponents[normOffset + numColorComponents] *
+                        maxValues[numColorComponents] + 0.5f);
+        } else {
+            for (int i = 0; i < numComponents; i++) {
+                components[offset + i] =
+                    (int) (normComponents[normOffset + i] *
+                            maxValues[i] + 0.5f);
+            }
+        }
+
+        return components;
+    }
+
+    /**
+     * Gets the data element corresponding to the normalized components.
+     * 
+     * @param normComponents the normalized components
+     * @param normOffset the offset where the normalized components should
+     * be read from the normalized component array
+     * 
+     * @return the data element
+     */
+    public int getDataElement(float normComponents[], int normOffset) {
+        int unnormComponents[] = getUnnormalizedComponents(normComponents,
+                normOffset, null, 0);
+        return getDataElement(unnormComponents, 0);
+    }
+
+    /**
+     * Takes a pixel whose data is defined by an int, and writes the 
+     * corresponding components into the components array, starting 
+     * from the index offset.
+     * 
+     * @param pixel the pixel data
+     * @param components the data array to write the components to (or
+     * null to have the method create the return array)
+     * @param offset the offset that determines where the results are 
+     * written in the components array
+     * 
+     * @return the array of components corresponding to the pixel
+     */
+    public int[] getComponents(int pixel, int components[], int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the red component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel data
+     * 
+     * @return the red component of the pixel
+     */
+    public abstract int getRed(int pixel);
+
+    /**
+     * Takes the pixel data and returns the int corresponding 
+     * to the pixel's color in RGB format.
+     * 
+     * @param pixel the pixel data
+     * 
+     * @return the corresponding RGB int
+     */
+    public int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24 | getRed(pixel) << 16
+                | getGreen(pixel) << 8 | getBlue(pixel));
+    }
+
+    /**
+     * Gets the green component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel data
+     * 
+     * @return the green component of the pixel
+     */
+    public abstract int getGreen(int pixel);
+
+    /**
+     * Gets the size of the desired component of this color model.
+     * 
+     * @param componentIdx the index that determines which component size to get
+     * 
+     * @return the component size corresponding to the index
+     * 
+     * @throws NullPointerException if this color model doesn't support
+     * an array of separate components.
+     * @throws ArrayIndexOutOfBoundsException if the index is negative or
+     * greater than or equal to the number of components
+     */
+    public int getComponentSize(int componentIdx) {
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (componentIdx < 0 || componentIdx >= bits.length) {
+            // awt.274=componentIdx is greater than the number of components or less than zero
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.274")); //$NON-NLS-1$
+        }
+
+        return bits[componentIdx];
+    }
+
+    /**
+     * Gets the blue component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel
+     * 
+     * @return the blue component of the pixel
+     */
+    public abstract int getBlue(int pixel);
+
+    /**
+     * Gets the alpha component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel
+     * 
+     * @return the alpha component of the pixel
+     */
+    public abstract int getAlpha(int pixel);
+
+    /**
+     * Gets the array of sizes of the different components.
+     * 
+     * @return the array of sizes of the different components
+     */
+    public int[] getComponentSize() {
+        if (bits != null) {
+            return bits.clone();
+        }
+        return null;
+    }
+
+    /**
+     * Checks if the alpha component is premultiplied.
+     * 
+     * @return true, if the alpha component is premultiplied
+     */
+    public final boolean isAlphaPremultiplied() {
+        return isAlphaPremultiplied;
+    }
+
+    /**
+     * Checks whether this color model supports alpha.
+     * 
+     * @return true, if this color model has alpha
+     */
+    public final boolean hasAlpha() {
+        return hasAlpha;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp;
+
+        if (hasAlpha) {
+            hash ^= 1;
+            hash <<= 8;
+        }
+        if (isAlphaPremultiplied) {
+            hash ^= 1;
+            hash <<= 8;
+        }
+
+        tmp = hash >>> 24;
+        hash ^= numColorComponents;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= transparency;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= cs.getType();
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= pixel_bits;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= transferType;
+        hash <<= 8;
+        hash |= tmp;
+
+        if (bits != null) {
+
+            for (int element : bits) {
+                tmp = hash >>> 24;
+                hash ^= element;
+                hash <<= 8;
+                hash |= tmp;
+            }
+
+        }
+
+        return hash;
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+
+    /**
+     * Gets the transfer type, which is the type of Java primitive
+     * value that corresponds to the bit length per pixel: either 
+     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT}, 
+     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
+     * 
+     * @return the transfer type
+     */
+    public final int getTransferType() {
+        return transferType;
+    }
+
+    /**
+     * Gets the pixel size in bits.
+     * 
+     * @return the pixel size
+     */
+    public int getPixelSize() {
+        return pixel_bits;
+    }
+
+    /**
+     * Gets the number of components of this color model.
+     * 
+     * @return the number of components
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+    /**
+     * Gets the number of color components of this color model.
+     * 
+     * @return the number color components
+     */
+    public int getNumColorComponents() {
+        return numColorComponents;
+    }
+
+    /**
+     * Gets the default RGB color model.
+     * 
+     * @return the default RGB color model
+     */
+    public static ColorModel getRGBdefault() {
+        if (RGBdefault == null) {
+            RGBdefault = new DirectColorModel(32, 0x00ff0000, 0x0000ff00,
+                    0x000000ff, 0xff000000);
+        }
+        return RGBdefault;
+    }
+
+    /*
+     * Construct INT pixel representation from Object
+     * @param obj
+     *
+     * @return
+     */
+    /**
+     * Construct pixel.
+     * 
+     * @param obj the obj
+     * 
+     * @return the int
+     */
+    private int constructPixel(Object obj) {
+        int pixel = 0;
+
+        switch (getTransferType()) {
+
+        case DataBuffer.TYPE_BYTE:
+            byte[] bPixel = (byte[]) obj;
+            if(bPixel.length > 1) {
+                // awt.275=This pixel representation is not suuported by tis Color Model
+                throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+            }
+            pixel = bPixel[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short[] sPixel = (short[]) obj;
+            if(sPixel.length > 1) {
+                // awt.275=This pixel representation is not suuported by tis Color Model
+                throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+            }
+            pixel = sPixel[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int[] iPixel = (int[]) obj;
+            if(iPixel.length > 1) {
+                // awt.275=This pixel representation is not suuported by tis Color Model
+                throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+            }
+            pixel = iPixel[0];
+            break;
+
+        default:
+            // awt.22D=This transferType ( {0} ) is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
+                   transferType));
+
+        }
+        return pixel;
+    }
+
+    /**
+     * Gets the transfer type, which is the type of Java primitive
+     * value that corresponds to the bit length per pixel: either 
+     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT}, 
+     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
+     * 
+     * @param bits the array of component masks
+     * 
+     * @return the transfer type
+     */
+    static int getTransferType(int bits) {
+        if (bits <= 8) {
+            return DataBuffer.TYPE_BYTE;
+        } else if (bits <= 16) {
+            return DataBuffer.TYPE_USHORT;
+        } else if (bits <= 32) {
+            return DataBuffer.TYPE_INT;
+        } else {
+            return DataBuffer.TYPE_UNDEFINED;
+        }
+    }
+
+    @Override
+    public void finalize() {
+        // This method is added for the API compatibility
+        // Don't need to call super since Object's finalize is always empty
+    }
+}
diff --git a/awt/java/awt/image/ComponentColorModel.java b/awt/java/awt/image/ComponentColorModel.java
new file mode 100644
index 0000000..a152f55
--- /dev/null
+++ b/awt/java/awt/image/ComponentColorModel.java
@@ -0,0 +1,1471 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.color.ColorSpace;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class ComponentColorModel represents a color model that is defined 
+ * in terms of its components.
+ */
+public class ComponentColorModel extends ColorModel {
+
+    /** The signed. */
+    private boolean signed;   // Pixel samples are signed.
+                              // Samples with TransferType DataBuffer.TYPE_BYTE,
+                              // DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT - 
+                              // unsigned. Samples with others TransferType - 
+                              // signed.
+
+    /** The integral. */
+    private boolean integral; // Pixel samples are integral.
+                              // Samples with TransferType DataBuffer.TYPE_BYTE,
+                              // DataBuffer.TYPE_USHORT, DataBuffer.Short and 
+                              // DataBuffer.TYPE_INT - integral.
+
+    /** The scale factors. */
+    private float scaleFactors[]; // Array of factors for reduction components 
+                                  // values into the form scaled from 0 to 255
+
+    /** The donot support unnormalized. */
+    private boolean donotSupportUnnormalized; // This Color Model don't support
+                                              // unnormolized form 
+
+    /** The need alpha divide. */
+    private boolean needAlphaDivide; // hasAlpha && isAlphaPremultiplied
+
+    /** The calc value. */
+    private boolean calcValue;       // Value was culculated
+
+    /** The need scale. */
+    private boolean needScale;       // Normalized value need to scale
+
+    /** The min vals. */
+    private float minVals[];         // Array of Min normalized values
+
+    /** The ranges. */
+    private float ranges[];          // Array of range normalized values  
+
+    /** The alpha lut. */
+    private byte alphaLUT[];         // Lookup table for scale alpha value
+
+    /** The color lu ts. */
+    private byte colorLUTs[][];      // Lookup tables for scale color values
+
+    /** The from_ linea r_ rg b_ lut. */
+    private byte from_LINEAR_RGB_LUT[];  // Lookup table for conversion from
+                                         // Linear RGB Color Space into sRGB
+
+    /** The to_ linea r_8 rg b_ lut. */
+    private byte to_LINEAR_8RGB_LUT[];   // Lookup table for conversion from
+                                         // sRGB Color Space into Linear RGB 
+                                         // 8 bit 
+
+    /** The to_ linea r_16 rg b_ lut. */
+    private short to_LINEAR_16RGB_LUT[]; // Lookup table for conversion from
+                                         // sRGB Color Space into Linear RGB 
+                                         // 16 bit 
+
+    /** The LINEA r_ rg b_ length. */
+    private int LINEAR_RGB_Length;       // Linear RGB bit length
+
+    /** The factor. */
+    private float fFactor;               // Scale factor
+
+    /** The is_s rgb. */
+    private boolean is_sRGB;             // ColorModel has sRGB ColorSpace  
+
+    /** The is_ linea r_ rgb. */
+    private boolean is_LINEAR_RGB;       // Color Model has Linear RGB Color 
+                                         // Space 
+
+    /**
+     * Instantiates a new component color model.
+     * 
+     * @param colorSpace the color space
+     * @param bits the array of component masks
+     * @param hasAlpha whether the color model has alpha
+     * @param isAlphaPremultiplied whether the alpha is premultiplied
+     * @param transparency the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     */
+     public ComponentColorModel(ColorSpace colorSpace, int bits[],
+            boolean hasAlpha, boolean isAlphaPremultiplied, int transparency,
+            int transferType) {
+        super(createPixelBits(colorSpace, hasAlpha, transferType),
+                validateBits(bits, colorSpace, hasAlpha, transferType),
+                colorSpace, hasAlpha, isAlphaPremultiplied, transparency,
+                transferType);
+
+        needScale = false;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_INT:
+            signed = false;
+            integral = true;
+            donotSupportUnnormalized = false;
+            scaleFactors = new float[numComponents];
+            for (int i = 0; i < numColorComponents; i++) {
+                scaleFactors[i] = 1.0f / maxValues[i];
+                if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                    donotSupportUnnormalized = true;
+                }
+            }
+            if (hasAlpha) {
+                maxValues[numColorComponents] =
+                    (1 << bits[numColorComponents]) - 1;
+                scaleFactors[numColorComponents] =
+                    1.0f / maxValues[numColorComponents];
+            }
+            break;
+        case DataBuffer.TYPE_SHORT:
+            signed = true;
+            integral = true;
+            donotSupportUnnormalized = true;
+            scaleFactors = new float[numComponents];
+            for (int i = 0; i < numComponents; i++) {
+                maxValues[i] = Short.MAX_VALUE;
+                scaleFactors[i] = 1.0f / maxValues[i];
+                if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                    needScale = true;
+                }
+            }
+            if (needScale) {
+                minVals = new float[numColorComponents];
+                ranges = new float[numColorComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    minVals[i] = cs.getMinValue(i);
+                    ranges[i] = cs.getMaxValue(i) - minVals[i];
+                }
+            }
+            break;
+        case DataBuffer.TYPE_FLOAT:
+        case DataBuffer.TYPE_DOUBLE:
+            signed = true;
+            integral = false;
+            donotSupportUnnormalized = true;
+            break;
+        default:
+            // awt.215=transferType is not one of DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
+            //          DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
+            //          DataBuffer.TYPE_DOUBLE
+            throw new IllegalArgumentException(Messages.getString("awt.215")); //$NON-NLS-1$
+        }
+
+        needAlphaDivide = hasAlpha && isAlphaPremultiplied;
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new component color model.
+     * 
+     * @param colorSpace the color space
+     * @param hasAlpha whether the color model has alpha
+     * @param isAlphaPremultiplied whether the alpha is premultiplied
+     * @param transparency the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     */
+    public ComponentColorModel(ColorSpace colorSpace, boolean hasAlpha,
+            boolean isAlphaPremultiplied, int transparency, int transferType) {
+        
+        this(colorSpace, 
+                createPixelBitsArray(colorSpace, hasAlpha, transferType), 
+                hasAlpha, 
+                isAlphaPremultiplied, 
+                transparency,
+                transferType);
+    }
+
+    /**
+     * Validate bits.
+     * 
+     * @param bits the bits
+     * @param colorSpace the color space
+     * @param hasAlpha the has alpha
+     * @param transferType the transfer type
+     * 
+     * @return the int[]
+     */
+    private static int[] validateBits(int bits[], ColorSpace colorSpace,
+            boolean hasAlpha, int transferType) {
+        if (bits != null) {
+            return bits;
+        }
+
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+        bits = new int[numComponents];
+
+        int componentLength = DataBuffer.getDataTypeSize(transferType);
+
+        for (int i = 0; i < numComponents; i++) {
+            bits[i] = componentLength;
+        }
+
+        return bits;
+    }
+
+    /**
+     * Creates the pixel bits.
+     * 
+     * @param colorSpace the color space
+     * @param hasAlpha the has alpha
+     * @param transferType the transfer type
+     * 
+     * @return the int
+     */
+    private static int createPixelBits(ColorSpace colorSpace, boolean hasAlpha,
+            int transferType) {
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+        int componentLength = DataBuffer.getDataTypeSize(transferType);
+        return numComponents * componentLength;
+    }
+
+    /**
+     * Creates the pixel bits array.
+     * 
+     * @param colorSpace the color space
+     * @param hasAlpha the has alpha
+     * @param transferType the transfer type
+     * 
+     * @return the int[]
+     */
+    private static int[] createPixelBitsArray(ColorSpace colorSpace, 
+            boolean hasAlpha, int transferType) {
+        
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+
+        int bits[] = new int[numComponents];
+        for(int i = 0; i < numComponents; i++){
+            bits[i] = DataBuffer.getDataTypeSize(transferType);
+        }
+        return bits;
+    }
+
+    @Override
+    public Object getDataElements(int components[], int offset, Object obj) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (offset + numComponents > components.length) {
+            // awt.216=The components array is not large enough to hold all the color and alpha components
+            throw new IllegalArgumentException(Messages.getString("awt.216")); //$NON-NLS-1$
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (obj == null) {
+                ba = new byte[numComponents];
+            } else {
+                ba = (byte[]) obj;
+            }
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                ba[i] = (byte) components[idx];
+            }
+            return ba;
+        case DataBuffer.TYPE_USHORT:
+            short sa[];
+            if (obj == null) {
+                sa = new short[numComponents];
+            } else {
+                sa = (short[]) obj;
+            }
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                sa[i] = (short) components[idx];
+            }
+            return sa;
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (obj == null) {
+                ia = new int[numComponents];
+            } else {
+                ia = (int[]) obj;
+            }
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                ia[i] = components[idx];
+            }
+            return ia;
+        default:
+            // awt.217=The transfer type of this ComponentColorModel is not one
+            //          of the following transfer types: DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+            throw new UnsupportedOperationException(Messages
+                    .getString("awt.217")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public Object getDataElements(float normComponents[], int normOffset,
+            Object obj) {
+        if (needScale) {
+            for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                normComponents[idx] =
+                    (normComponents[idx] - minVals[i]) / ranges[i];
+            }
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (obj == null) {
+                ba = new byte[numComponents];
+            } else {
+                ba = (byte[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = normOffset; i < numColorComponents;
+                    i++, idx++) {
+                    ba[i] = (byte) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                ba[numColorComponents] =
+                    (byte) (normComponents[normOffset + numColorComponents] *
+                            maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    ba[idx] =
+                        (byte) (normComponents[idx] * maxValues[i] + 0.5f);
+                }
+            }
+            return ba;
+
+        case DataBuffer.TYPE_USHORT:
+            short usa[];
+            if (obj == null) {
+                usa = new short[numComponents];
+            } else {
+                usa = (short[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    usa[i] = (short) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                usa[numColorComponents] = (short) (alpha *
+                        maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    usa[i] = (short) (normComponents[idx] *
+                            maxValues[i] + 0.5f);
+                }
+            }
+            return usa;
+
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (obj == null) {
+                ia = new int[numComponents];
+            } else {
+                ia = (int[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    ia[i] = (int) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                ia[numColorComponents] = (int) (alpha *
+                        maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    ia[i] = (int) (normComponents[idx] * maxValues[i] + 0.5f);
+                }
+            }
+            return ia;
+
+        case DataBuffer.TYPE_SHORT:
+            short sa[];
+            if (obj == null) {
+                sa = new short[numComponents];
+            } else {
+                sa = (short[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    sa[i] = (short) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                sa[numColorComponents] = (short) (alpha *
+                        maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    sa[i] = (short) (normComponents[idx] *
+                            maxValues[i] + 0.5f);
+                }
+            }
+            return sa;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fa[];
+            if (obj == null) {
+                fa = new float[numComponents];
+            } else {
+                fa = (float[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    fa[i] = normComponents[idx] * alpha;
+                }
+                fa[numColorComponents] = alpha;
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    fa[i] = normComponents[idx];
+                }
+            }
+            return fa;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double da[];
+            if (obj == null) {
+                da = new double[numComponents];
+            } else {
+                da = (double[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                double alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    da[i] = normComponents[idx] * alpha;
+                }
+                da[numColorComponents] = alpha;
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    da[i] = normComponents[idx];
+                }
+            }
+            return da;
+
+        default:
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public Object getDataElements(int rgb, Object pixel) {
+        float normComp[];
+        float comp[];
+
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+        int alpha = (rgb >> 24) & 0xff;
+
+        comp = new float[3];
+        if (is_sRGB || is_LINEAR_RGB) {
+            if (is_LINEAR_RGB) {
+                if (LINEAR_RGB_Length == 8) {
+                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
+                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
+                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
+                } else {
+                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
+                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
+                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
+                }
+            }
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            if (!hasAlpha) {
+                normComp = comp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = comp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        } else {
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            float[] defComp = cs.fromRGB(comp);
+            if (!hasAlpha) {
+                normComp = defComp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = defComp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        }
+        if(hasAlpha && isAlphaPremultiplied){
+            normComp[0] *= normComp[numColorComponents];
+            normComp[1] *= normComp[numColorComponents];
+            normComp[2] *= normComp[numColorComponents];
+        }
+
+        return getDataElements(normComp, 0, pixel);
+    }
+
+    @Override
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        if(!hasAlpha) {
+            return null;
+        }
+
+        int x = raster.getMinX();
+        int y = raster.getMinY();
+        int bandList[] = new int[1];
+        bandList[0] = raster.getNumBands() - 1;
+
+        return raster.createWritableChild(x, y, raster.getWidth(),
+                raster.getHeight(), x, y, bandList);
+    }
+
+    @Override
+    public ColorModel coerceData(WritableRaster raster,
+            boolean isAlphaPremultiplied) {
+        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
+            return this;
+        }
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        if (isAlphaPremultiplied) {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                float alphaFactor = maxValues[numColorComponents];
+                int iComponents[] = null;
+                int iTransparentComponents[] = new int[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        iComponents = raster.getPixel(x, minY,
+                                iComponents);
+                        if (iComponents[numColorComponents] == 0) {
+                            raster.setPixel(x, minY, iTransparentComponents);
+                        } else {
+                            float alpha =
+                                iComponents[numColorComponents] /
+                                    alphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                iComponents[n] =
+                                    (int) (alpha * iComponents[n] + 0.5f);
+                            }
+                            raster.setPixel(x, minY, iComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+                float sAlphaFactor = maxValues[numColorComponents];
+                short sComponents[] = null;
+                short sTransparentComponents[] = new short[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        sComponents = (short[]) raster.getDataElements(x, minY,
+                                sComponents);
+                        if (sComponents[numColorComponents] == 0) {
+                            raster.setDataElements(x, minY,
+                                    sTransparentComponents);
+                        } else {
+                            float alpha =
+                                sComponents[numColorComponents] /
+                                sAlphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                sComponents[n] =
+                                    (byte) (alpha * sComponents[n] + 0.5f);
+                            }
+                            raster.setDataElements(x, minY, sComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fComponents[] = null;
+                float fTransparentComponents[] = new float[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        fComponents = raster.getPixel(x, minY, fComponents);
+                        if (fComponents[numColorComponents] == 0.0f) {
+                            raster.setDataElements(x, minY,
+                                    fTransparentComponents);
+                        } else {
+                            float alpha = fComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                fComponents[n] = fComponents[n] * alpha;
+                            }
+                            raster.setPixel(x, minY, fComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double dComponents[] = null;
+                double dTransparentComponents[] = new double[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        dComponents = raster.getPixel(x, minY, dComponents);
+                        if (dComponents[numColorComponents] == 0.0) {
+                            raster.setPixel(x, minY, dTransparentComponents);
+                        } else {
+                            double alpha = dComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                dComponents[n] = dComponents[n] * alpha;
+                            }
+                            raster.setPixel(x, minY, dComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            default:
+                // awt.219=This transferType is not supported by this color model
+                throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+            }
+        } else {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                float alphaFactor = maxValues[numColorComponents];
+                int iComponents[] = null;
+                int iTransparentComponents[] = new int[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        iComponents = raster.getPixel(x, minY,
+                                iComponents);
+                        if (iComponents[numColorComponents] == 0) {
+                            raster.setPixel(x, minY, iTransparentComponents);
+                        } else {
+                            float alpha =
+                                iComponents[numColorComponents] /
+                                    alphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                iComponents[n] =
+                                    (int) (iComponents[n] /
+                                            alpha + 0.5f);
+                            }
+                            raster.setPixel(x, minY, iComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+                float sAlphaFactor = maxValues[numColorComponents];
+                short sComponents[] = null;
+                short sTransparentComponents[] = new short[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        sComponents = (short[]) raster.getDataElements(x, minY,
+                                sComponents);
+                        if (sComponents[numColorComponents] == 0) {
+                            raster.setDataElements(x, minY,
+                                    sTransparentComponents);
+                        } else {
+                            float alpha =
+                                sComponents[numColorComponents] /
+                                    sAlphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                sComponents[n] =
+                                    (byte) (sComponents[n] /
+                                            alpha + 0.5f);
+                            }
+                            raster.setDataElements(x, minY, sComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fComponents[] = null;
+                float fTransparentComponents[] = new float[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        fComponents = raster.getPixel(x, minY, fComponents);
+                        if (fComponents[numColorComponents] == 0.0f) {
+                            raster.setDataElements(x, minY,
+                                    fTransparentComponents);
+                        } else {
+                            float alpha = fComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                fComponents[n] = fComponents[n] / alpha;
+                            }
+                            raster.setPixel(x, minY, fComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double dComponents[] = null;
+                double dTransparentComponents[] = new double[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        dComponents = raster.getPixel(x, minY, dComponents);
+                        if (dComponents[numColorComponents] == 0.0) {
+                            raster.setPixel(x, minY, dTransparentComponents);
+                        } else {
+                            double alpha = dComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                dComponents[n] = dComponents[n] / alpha;
+                            }
+                            raster.setPixel(x, minY, dComponents);
+                        }
+                    }
+
+                }
+                break;
+            default:
+                // awt.219=This transferType is not supported by this color model
+                throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+            }
+        }
+
+        if (!signed) {
+            return new ComponentColorModel(cs, bits, hasAlpha,
+                    isAlphaPremultiplied, transparency, transferType);
+        }
+
+        return new ComponentColorModel(cs, null, hasAlpha,
+                isAlphaPremultiplied, transparency, transferType);
+    }
+
+    @Override
+    public int[] getComponents(Object pixel, int[] components, int offset) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[offset + numComponents];
+        } else if (offset + numComponents > components.length) {
+            // awt.218=The components array is not large enough to hold all the color and alpha components
+            throw new IllegalArgumentException(Messages.getString("awt.218")); //$NON-NLS-1$
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                components[idx] = ba[i] & 0xff;
+            }
+            return components;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) pixel;
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                components[idx] = sa[i] & 0xffff;
+            }
+            return components;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                components[idx] = ia[i];
+            }
+            return components;
+
+        default:
+            // awt.217=The transfer type of this ComponentColorModel is not one
+            //          of the following transfer types: DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+            throw new UnsupportedOperationException(Messages
+                    .getString("awt.217")); //$NON-NLS-1$
+        }
+
+    }
+
+    @Override
+    public float[] getNormalizedComponents(Object pixel,
+            float normComponents[], int normOffset) {
+
+        if (normComponents == null) {
+            normComponents = new float[numComponents + normOffset];
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = (ba[i] & 0xff) * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short usa[] = (short[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = (usa[i] & 0xffff)
+                        * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = ia[i] * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+            short sa[] = (short[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = sa[i] * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fa[] = (float[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = fa[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double da[] = (double[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = (float) da[i];
+            }
+            break;
+
+        default:
+            // awt.21A=This ComponentColorModel does not support this transferType
+            throw new IllegalArgumentException(Messages.getString("awt.21A")); //$NON-NLS-1$
+        }
+
+        if (needAlphaDivide) {
+            float alpha = normComponents[normOffset + numColorComponents];
+            for (int i = 0, idx = normOffset; i < numColorComponents;
+                i++, idx++) {
+                normComponents[idx] /= alpha;
+            }
+        }
+
+        if (needScale) {
+            for (int i = 0, idx = normOffset; i < numColorComponents;
+                i++, idx++) {
+                normComponents[idx] = minVals[i] +
+                    ranges[i] * normComponents[idx];
+            }
+        }
+        return normComponents;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ComponentColorModel)) {
+            return false;
+        }
+        return super.equals(obj);
+    }
+
+    @Override
+    public int getRed(Object inData) {
+        return getRGBComponent(inData, 0);
+    }
+
+    @Override
+    public int getRGB(Object inData) {
+        int alpha = getAlpha(inData);
+        if (cs.getType() == ColorSpace.TYPE_GRAY) {
+            int gray = getRed(inData);
+            return (alpha << 24 | gray << 16 | gray << 8 | gray);
+        }
+        return (alpha << 24 | getRed(inData) << 16 | getGreen(inData) << 8 |
+                getBlue(inData));
+    }
+
+    @Override
+    public int getGreen(Object inData) {
+        return getRGBComponent(inData, 1);
+    }
+
+    @Override
+    public int getBlue(Object inData) {
+        return getRGBComponent(inData, 2);
+    }
+
+    @Override
+    public int getAlpha(Object inData) {
+        if (!hasAlpha) {
+            return 255;
+        }
+        int alpha = 0;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE: {
+            byte ba[] = (byte[]) inData;
+            alpha = ba[numColorComponents] & 0xff;
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_USHORT: {
+            short usa[] = (short[]) inData;
+            alpha = usa[numColorComponents] & 0xffff;
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_INT: {
+            int ia[] = (int[]) inData;
+            alpha = ia[numColorComponents];
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_SHORT: {
+            short sa[] = (short[]) inData;
+            alpha = sa[numColorComponents];
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_FLOAT: {
+            float fa[] = (float[]) inData;
+            return (int) (fa[numColorComponents] * 255.0f + 0.5f);
+        }
+        case DataBuffer.TYPE_DOUBLE: {
+            double da[] = (double[]) inData;
+            return (int) (da[numColorComponents] * 255.0 + 0.5);
+        }
+        default: {
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        }
+    }
+
+    @Override
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        SampleModel sm = createCompatibleSampleModel(w, h);
+        DataBuffer db = sm.createDataBuffer();
+        return Raster.createWritableRaster(sm, db, null);
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (!(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+        if (numComponents != sm.getNumBands()) {
+            return false;
+        }
+        if (transferType != sm.getTransferType()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        int bandOffsets[] = new int[numComponents];
+        for (int i = 0; i < numComponents; i++) {
+            bandOffsets[i] = i;
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_USHORT:
+            return new PixelInterleavedSampleModel(transferType, w, h,
+                    numComponents, w * numComponents, bandOffsets);
+
+        default:
+            return new ComponentSampleModel(transferType, w, h, numComponents,
+                    w * numComponents, bandOffsets);
+        }
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        SampleModel sm = raster.getSampleModel();
+        if (!(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+
+        if (sm.getNumBands() != numComponents) {
+            return false;
+        }
+        if (raster.getTransferType() != transferType) {
+            return false;
+        }
+
+        int sampleSizes[] = sm.getSampleSize();
+        for (int i = 0; i < numComponents; i++) {
+            if (bits[i] != sampleSizes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public float[] getNormalizedComponents(int components[], int offset,
+            float normComponents[], int normOffset) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        return super.getNormalizedComponents(components, offset,
+                normComponents, normOffset);
+    }
+
+    @Override
+    public int getDataElement(int[] components, int offset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+        return components[offset];
+    }
+
+    @Override
+    public int[] getUnnormalizedComponents(float[] normComponents,
+            int normOffset, int[] components, int offset) {
+
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (normComponents.length - normOffset < numComponents) {
+            // awt.21B=The length of normComponents minus normOffset is less than numComponents
+            throw new IllegalArgumentException(Messages.getString("awt.21B")); //$NON-NLS-1$
+        }
+
+        return super.getUnnormalizedComponents(normComponents, normOffset,
+                components, offset);
+    }
+
+    @Override
+    public int getDataElement(float normComponents[], int normOffset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        Object pixel = getDataElements(normComponents, normOffset, null);
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            return ba[0] & 0xff;
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) pixel;
+            return sa[0] & 0xffff;
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            return ia[0];
+        default:
+            // awt.211=Pixel values for this ColorModel are not conveniently
+            //          representable as a single int
+            throw new IllegalArgumentException(Messages.getString("awt.211")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public int[] getComponents(int pixel, int components[], int offset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[offset + 1];
+        }
+
+        components[offset] = pixel & maxValues[0];
+        return components;
+    }
+
+    @Override
+    public int getRed(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int) (rgb[0] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) |
+               (getGreen(pixel) << 8) | getBlue(pixel);
+    }
+
+    @Override
+    public int getGreen(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int) (rgb[1] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getBlue(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int) (rgb[2] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getAlpha(int pixel) {
+
+        // This method throw IllegalArgumentException according to 
+        // Java API Spacification
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+
+        return 255;
+    }
+
+    /**
+     * Initialization of Lookup tables.
+     */
+    private void initLUTs() {
+        is_sRGB = cs.isCS_sRGB();
+        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
+
+        if (hasAlpha && bits[numColorComponents] != 8 && integral) {
+            alphaLUT = new byte[maxValues[numColorComponents] + 1];
+            for (int i = 0; i <= maxValues[numColorComponents]; i++) {
+                alphaLUT[i] = (byte) (scaleFactors[numColorComponents] * i + 
+                        0.5f);
+            }
+        }
+
+        if (is_LINEAR_RGB) {
+            if (maxBitLength > 8) {
+                LINEAR_RGB_Length = 16;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom16lRGBtosRGB_LUT();
+                to_LINEAR_16RGB_LUT =
+                    LUTColorConverter.getFromsRGBto16lRGB_LUT();
+            } else {
+                LINEAR_RGB_Length = 8;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom8lRGBtosRGB_LUT();
+                to_LINEAR_8RGB_LUT =
+                    LUTColorConverter.getFromsRGBto8lRGB_LUT();
+            }
+            fFactor = ((1 << LINEAR_RGB_Length) - 1);
+        } else {
+            fFactor = 255.0f;
+        }
+
+        if (!isAlphaPremultiplied && integral) {
+            colorLUTs = new byte[3][];
+
+            if (is_sRGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != 8) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            colorLUTs[i][j] =
+                                (byte) (scaleFactors[i] * j + 0.5f);
+                        }
+                    }
+                }
+            }
+
+            if (is_LINEAR_RGB) {
+
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != LINEAR_RGB_Length) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            int idx;
+                            if (LINEAR_RGB_Length == 8) {
+                                idx = (int) (scaleFactors[i] * j + 0.5f);
+                            } else {
+                                idx = (int) (scaleFactors[i] * j * 257.0f +
+                                        0.5f);
+                            }
+                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * To rgb.
+     * 
+     * @param pixel - int representation of pixel
+     * 
+     * @return - array of normalized sRGB components
+     */
+    private float[] toRGB(int pixel) {
+        
+        // This method throw IllegalArgumentException according to 
+        // Java API Spacification
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+
+        Object obj = null;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = new byte[1];
+            ba[0] = (byte) pixel;
+            obj = ba;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = new short[1];
+            sa[0] = (short) pixel;
+            obj = sa;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = new int[1];
+            ia[0] = pixel;
+            obj = ia;
+            break;
+
+        }
+
+        return cs.toRGB(getNormalizedComponents(obj, null, 0));
+    }
+
+    /**
+     * Gets the rgb component.
+     * 
+     * @param pixel - pixel
+     * @param idx - index of component
+     * 
+     * @return - RGB value from 0 to 255 pixel's component
+     */
+    private int getRGBComponent(Object pixel, int idx) {
+        if (is_sRGB) {
+            int comp = getDefComponent(pixel, idx);
+            if (calcValue || bits[idx] == 8) {
+                return comp;
+            }
+            return colorLUTs[idx][comp] & 0xff;
+        } else if (is_LINEAR_RGB) {
+            int comp = getDefComponent(pixel, idx);
+            if (calcValue || bits[idx] == LINEAR_RGB_Length) {
+                return from_LINEAR_RGB_LUT[comp] & 0xff;
+            }
+            return colorLUTs[idx][comp] & 0xff;
+        }
+
+        float normComp[] = getNormalizedComponents(pixel, null, 0);
+        float rgbComp[] = cs.toRGB(normComp);
+        return (int) (rgbComp[idx] * 255.0f + 0.5f);
+    }
+
+    /**
+     * Gets the def component.
+     * 
+     * @param pixel - pixel
+     * @param idx - index of component
+     * 
+     * @return - tentative value of the pixel component
+     */
+    private int getDefComponent(Object pixel, int idx) {
+        int comp = 0;
+        calcValue = false;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            comp = ba[idx] & 0xff;
+            if (needAlphaDivide) {
+                int alpha = ba[numColorComponents] & 0xff;
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_USHORT:
+            short usa[] = (short[]) pixel;
+            comp = usa[idx] & 0xffff;
+            if (needAlphaDivide) {
+                int alpha = usa[numColorComponents] & 0xffff;
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            comp = ia[idx];
+            if (needAlphaDivide) {
+                int alpha = ia[numColorComponents];
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_SHORT:
+            short sa[] = (short[]) pixel;
+            comp = sa[idx];
+            if (needAlphaDivide) {
+                int alpha = sa[numColorComponents];
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fa[] = (float[]) pixel;
+            if (needAlphaDivide) {
+                float alpha = fa[numColorComponents];
+                if (fa[numColorComponents] == 0.0f) {
+                    comp = 0;
+                } else {
+                    comp = (int) (fa[idx] * fFactor / alpha + 0.5f);
+                }
+            } else {
+                comp = (int) (fa[idx] * fFactor + 0.5f);
+            }
+            calcValue = true;
+            return comp;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double da[] = (double[]) pixel;
+            if (needAlphaDivide) {
+                if (da[numColorComponents] == 0.0) {
+                    comp = 0;
+                } else {
+                    comp = (int) (da[idx] * fFactor / da[numColorComponents] + 
+                            0.5);
+                }
+            } else {
+                comp = (int) (da[idx] * fFactor + 0.5);
+            }
+            calcValue = true;
+            return comp;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/image/ComponentSampleModel.java b/awt/java/awt/image/ComponentSampleModel.java
new file mode 100644
index 0000000..2ff4f1a
--- /dev/null
+++ b/awt/java/awt/image/ComponentSampleModel.java
@@ -0,0 +1,690 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ComponentSampleModel class represents a set of image data whose 
+ * each element - the sample of a pixel - takes one data element of 
+ * the DataBuffer. 
+ * <p>
+ * The Bank indices denote the correspondence between the bank of data 
+ * buffers and a band of image data. The Pixel stride is the number of data 
+ * array elements between two samples for the same band on the same 
+ * scanline. The pixel stride for a BandedSampleModel is one. The Scanline 
+ * stride represents the number of data array elements between a  
+ * specified sample and the corresponding sample in the same column in 
+ * the next scanline. The array of band offsets gives the starting 
+ * offsets within each data banks of the in the DataBuffer. The bank 
+ * indices represents the indices within each bank of the DataBuffer 
+ * corresponding to a band of image data.
+ */
+public class ComponentSampleModel extends SampleModel {
+
+    /** The band offsets array of this ComponentSampleModel. */
+    protected int bandOffsets[];
+
+    /** The bank indices array of this ComponentSampleModel. */
+    protected int bankIndices[];
+
+    /** The number of bands in this ComponentSampleModel. */
+    protected int numBands;
+
+    /** The number banks of this ComponentSampleModel. */
+    protected int numBanks;
+
+    /** The scanline stride of this ComponentSampleModel. */
+    protected int scanlineStride;
+
+    /** The pixel stride of this ComponentSampleModel. */
+    protected int pixelStride;
+
+    /**
+     * Instantiates a new ComponentSampleModel with the specified
+     * properties.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param pixelStride the pixel stride of the image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bankIndices the array of the bank indices.
+     * @param bandOffsets the array of the band offsets.
+     */
+    public ComponentSampleModel(int dataType, int w, int h, int pixelStride,
+            int scanlineStride, int bankIndices[], int bandOffsets[]) {
+
+        super(dataType, w, h, bandOffsets.length);
+
+        if (pixelStride < 0) {
+            // awt.24B=Pixel stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
+        }
+
+        if (scanlineStride < 0) {
+            // awt.24C=Scanline stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
+        }
+
+        if (bankIndices.length != bandOffsets.length) {
+            // awt.24D=Bank Indices length must be equal Bank Offsets length
+            throw new IllegalArgumentException(Messages.getString("awt.24D")); //$NON-NLS-1$
+        }
+
+        this.pixelStride = pixelStride;
+        this.scanlineStride = scanlineStride;
+        this.bandOffsets = bandOffsets.clone();
+        this.bankIndices = bankIndices.clone();
+        this.numBands = bandOffsets.length;
+
+        int maxBank = 0;
+        for (int i = 0; i < bankIndices.length; i++) {
+            if (bankIndices[i] < 0) {
+                // awt.24E=Index of {0} bank must be >= 0
+                throw new IllegalArgumentException(Messages.getString("awt.24E", i)); //$NON-NLS-1$
+            }
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+        }
+        this.numBanks = maxBank + 1;
+
+    }
+
+    /**
+     * Instantiates a new ComponentSampleModel with the specified
+     * properties.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param pixelStride the pixel stride of the image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bandOffsets the band offsets.
+     */
+    public ComponentSampleModel(int dataType, int w, int h, int pixelStride,
+            int scanlineStride, int bandOffsets[]) {
+
+        super(dataType, w, h, bandOffsets.length);
+        if (pixelStride < 0) {
+            // awt.24B=Pixel stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
+        }
+
+        if (scanlineStride < 0) {
+            // awt.24C=Scanline stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
+        }
+
+        this.pixelStride = pixelStride;
+        this.scanlineStride = scanlineStride;
+        this.bandOffsets = bandOffsets.clone();
+        this.numBands = bandOffsets.length;
+        this.numBanks = 1;
+
+        this.bankIndices = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            bankIndices[i] = 0;
+        }
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            if (obj == null) {
+                bdata = new byte[numBands];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                bdata[i] = (byte) getSample(x, y, i, data);
+            }
+
+            obj = bdata;
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            if (obj == null) {
+                sdata = new short[numBands];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                sdata[i] = (short) getSample(x, y, i, data);
+            }
+
+            obj = sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            if (obj == null) {
+                idata = new int[numBands];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                idata[i] = getSample(x, y, i, data);
+            }
+
+            obj = idata;
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fdata[];
+            if (obj == null) {
+                fdata = new float[numBands];
+            } else {
+                fdata = (float[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                fdata[i] = getSampleFloat(x, y, i, data);
+            }
+
+            obj = fdata;
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double ddata[];
+            if (obj == null) {
+                ddata = new double[numBands];
+            } else {
+                ddata = (double[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                ddata[i] = getSampleDouble(x, y, i, data);
+            }
+
+            obj = ddata;
+            break;
+        }
+
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            byte barr[] = (byte[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, barr[i] & 0xff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sarr[] = (short[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, sarr[i] & 0xffff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int iarr[] = (int[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, iarr[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float farr[] = (float[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, farr[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double darr[] = (double[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, darr[i], data);
+            }
+            break;
+        }
+    }
+
+    /**
+     * Compares this ComponentSampleModel with the specified Object.
+     * 
+     * @param o the Object.
+     * 
+     * @return true, if the object is a ComponentSampleModel with 
+     * identical data values to this ComponentSampleModel, false otherwise. 
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof ComponentSampleModel)) {
+            return false;
+        }
+        ComponentSampleModel model = (ComponentSampleModel) o;
+        return this.width == model.width && this.height == model.height &&
+               this.numBands == model.numBands &&
+               this.dataType == model.dataType &&
+               Arrays.equals(this.bandOffsets, model.bandOffsets) &&
+               Arrays.equals(this.bankIndices, model.bankIndices) &&
+               this.numBands == model.numBands &&
+               this.numBanks == model.numBanks &&
+               this.scanlineStride == model.scanlineStride &&
+               this.pixelStride == model.pixelStride;
+    }
+
+    /** 
+     * @see java.awt.image.SampleModel#createSubsetSampleModel(int[])
+     */
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > this.numBands) {
+            // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int indices[] = new int[bands.length];
+        int offsets[] = new int[bands.length];
+
+        for (int i = 0; i < bands.length; i++) {
+            indices[i] = bankIndices[bands[i]];
+            offsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new ComponentSampleModel(dataType, width, height, pixelStride,
+                scanlineStride, indices, offsets);
+
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new ComponentSampleModel(dataType, w, h, pixelStride,
+                pixelStride * w, bankIndices, bandOffsets);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        int pixel[];
+
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElem(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemFloat(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemDouble(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public int[] getPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x > this.width || x + w > this.width
+                || y > this.height || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixels[] = null;
+        int idx = 0;
+
+        if (iArray == null) {
+            pixels = new int[w * h * numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+
+        return pixels;
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElem(bankIndices[b], y * scanlineStride + x * pixelStride
+                + bandOffsets[b], s);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+        
+        if (data == null) {
+            // awt.295=data is null
+            throw new NullPointerException(Messages.getString("awt.295")); //$NON-NLS-1$
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemFloat(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemDouble(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b], s);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+
+        int maxOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+        }
+        int size = (height - 1) * scanlineStride +
+        (width - 1) * pixelStride + maxOffset + 1;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size, numBanks);
+            break;
+        case DataBuffer.TYPE_SHORT:
+            data = new DataBufferShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size, numBanks);
+            break;
+        case DataBuffer.TYPE_FLOAT:
+            data = new DataBufferFloat(size, numBanks);
+            break;
+        case DataBuffer.TYPE_DOUBLE:
+            data = new DataBufferDouble(size, numBanks);
+            break;
+        }
+
+        return data;
+
+    }
+
+    /**
+     * Gets the offset of the specified band of the specified pixel.
+     * 
+     * @param x the X coordinate of the pixel. 
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the offset of the specified band of the specified pixel.
+     */
+    public int getOffset(int x, int y, int b) {
+        return y * scanlineStride + x * pixelStride + bandOffsets[b];
+    }
+
+    /**
+     * Gets the offset of the first band of the specified pixel.
+     * 
+     * @param x the X coordinate of pixel. 
+     * @param y the Y coordinate of pixel.
+     * 
+     * @return the offset of the first band of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return y * scanlineStride + x * pixelStride + bandOffsets[0];
+    }
+
+    @Override
+    public final int getSampleSize(int band) {
+        return DataBuffer.getDataTypeSize(dataType);
+    }
+
+    @Override
+    public final int[] getSampleSize() {
+        int sampleSizes[] = new int[numBands];
+        int size = DataBuffer.getDataTypeSize(dataType);
+
+        for (int i = 0; i < numBands; i++) {
+            sampleSizes[i] = size;
+        }
+        return sampleSizes;
+    }
+
+    /**
+     * Gets an array of bank indices corresponding to this 
+     * ComponentSampleModel.
+     * 
+     * @return the array of bank indices.
+     */
+    public final int[] getBankIndices() {
+        return bankIndices.clone();
+    }
+
+    /**
+     * Gets an array of the band offsets corresponding to this 
+     * ComponentSampleModel.
+     * 
+     * @return the array of band offsets.
+     */
+    public final int[] getBandOffsets() {
+        return bandOffsets.clone();
+    }
+
+    /**
+     * Gets a hash code of this ComponentSampleModel object.
+     * 
+     * @return a hash code of this ComponentSampleModel object.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        for (int element : bandOffsets) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bankIndices) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        hash ^= pixelStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+
+        hash ^= scanlineStride;
+        return hash;
+    }
+
+    /**
+     * Gets the scanline stride of this ComponentSampleModel.
+     * 
+     * @return the scanline stride of this ComponentSampleModel.
+     */
+    public final int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /**
+     * Gets the pixel stride.
+     * 
+     * @return the pixel stride
+     */
+    public final int getPixelStride() {
+        return pixelStride;
+    }
+
+    @Override
+    public final int getNumDataElements() {
+        return numBands;
+    }
+
+}
+
+
+
diff --git a/awt/java/awt/image/ConvolveOp.java b/awt/java/awt/image/ConvolveOp.java
new file mode 100644
index 0000000..bb588bc
--- /dev/null
+++ b/awt/java/awt/image/ConvolveOp.java
@@ -0,0 +1,545 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 29, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ConvolveOp class convolves from the source data
+ * to the destination using a convolution kernel. 
+ * Each output pixel is represented as the result of multiplying 
+ * the kernel and the surround of the input pixel.
+ */
+public class ConvolveOp implements BufferedImageOp, RasterOp {
+
+    /** 
+     * The Constant EDGE_ZERO_FILL indicates that pixels at the edge of 
+     * the destination image are set to zero. 
+     */
+    public static final int EDGE_ZERO_FILL = 0;
+
+    /** 
+     * The Constant EDGE_NO_OP indicates that pixels at the edge of 
+     * the source image are converted to the edge pixels in the 
+     * destination without modification.
+     */
+    public static final int EDGE_NO_OP = 1;
+
+    /** The kernel. */
+    private Kernel kernel;
+    
+    /** The edge cond. */
+    private int edgeCond;
+    
+    /** The rhs. */
+    private RenderingHints rhs = null;
+
+    static {
+        // TODO
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new ConvolveOp object with the specified Kernel
+     * and specified edges condition.
+     * 
+     * @param kernel the specified Kernel.
+     * @param edgeCondition the specified edge condition.
+     * @param hints the RenderingHints object, or null.
+     */
+    public ConvolveOp(Kernel kernel, int edgeCondition, RenderingHints hints) {
+        this.kernel = kernel;
+        this.edgeCond = edgeCondition;
+        this.rhs = hints;
+    }
+
+    /**
+     * Instantiates a new ConvolveOp object with the specified Kernel
+     * and EDGE_ZERO_FILL edge condition.
+     * 
+     * @param kernel the specified Kernel.
+     */
+    public ConvolveOp(Kernel kernel) {
+        this.kernel = kernel;
+        this.edgeCond = EDGE_ZERO_FILL;
+    }
+
+    /**
+     * Gets the Kernel object of this ConvolveOp.
+     * 
+     * @return the Kernel object of this ConvolveOp.
+     */
+    public final Kernel getKernel() {
+        return (Kernel) kernel.clone();
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return rhs;
+    }
+
+    /**
+     * Gets the edge condition of this ConvolveOp.
+     * 
+     * @return the edge condition: EDGE_NO_OP or EDGE_ZERO_FILL.
+     */
+    public int getEdgeCondition() {
+        return edgeCond;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+        }
+
+        if (dstCM instanceof IndexColorModel) {
+            dstCM = ColorModel.getRGBdefault();
+        }
+
+        WritableRaster r =
+                dstCM.isCompatibleSampleModel(src.getSampleModel()) ?
+                src.getRaster().createCompatibleWritableRaster(src.getWidth(), src.getHeight()) :
+                dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(
+                dstCM,
+                r,
+                dstCM.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (src == null) { // Should throw according to spec
+            // awt.256=Source raster is null
+            throw new NullPointerException(Messages.getString("awt.256")); //$NON-NLS-1$
+        }
+
+        if (src == dst){
+            // awt.257=Source raster is equal to destination
+            throw new IllegalArgumentException(Messages.getString("awt.257")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (src.getNumBands() != dst.getNumBands()) {
+            // awt.258=Number of source bands ({0}) is not equal to number of destination bands ({1})
+            throw new IllegalArgumentException(
+                Messages.getString("awt.258", src.getNumBands(), dst.getNumBands())); //$NON-NLS-1$
+        }
+
+        // TODO
+        //if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
+            if (slowFilter(src, dst) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private int slowFilter(Raster src, WritableRaster dst) {
+        try {
+            SampleModel sm = src.getSampleModel();
+
+            int numBands = src.getNumBands();
+            int srcHeight = src.getHeight();
+            int srcWidth = src.getWidth();
+
+            int xOrigin = kernel.getXOrigin();
+            int yOrigin = kernel.getYOrigin();
+            int kWidth = kernel.getWidth();
+            int kHeight = kernel.getHeight();
+            float[] data = kernel.getKernelData(null);
+
+            int srcMinX = src.getMinX();
+            int srcMinY = src.getMinY();
+            int dstMinX = dst.getMinX();
+            int dstMinY = dst.getMinY();
+
+            int srcConvMaxX = srcWidth - (kWidth - xOrigin - 1);
+            int srcConvMaxY = srcHeight - (kHeight - yOrigin - 1);
+
+            int[] maxValues = new int[numBands];
+            int[] masks = new int[numBands];
+            int[] sampleSizes = sm.getSampleSize();
+
+            for (int i=0; i < numBands; i++){
+                maxValues[i] = (1 << sampleSizes[i]) - 1;
+                masks[i] = ~(maxValues[i]);
+            }
+
+            // Processing bounds
+            float[] pixels = null;
+            pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
+            float[] newPixels = new float[pixels.length];
+            int rowLength = srcWidth*numBands;
+            if (this.edgeCond == ConvolveOp.EDGE_NO_OP){
+                // top
+                int start = 0;
+                int length = yOrigin*rowLength;
+                System.arraycopy(pixels, start, newPixels, start, length);
+                // bottom
+                start = (srcHeight - (kHeight - yOrigin - 1))*rowLength;
+                length = (kHeight - yOrigin - 1)*rowLength;
+                System.arraycopy(pixels, start, newPixels, start, length);
+                // middle
+                length = xOrigin*numBands;
+                int length1 = (kWidth - xOrigin - 1)*numBands;
+                start = yOrigin*rowLength;
+                int start1 = (yOrigin+1)*rowLength - length1;
+                for (int i = yOrigin; i < (srcHeight - (kHeight - yOrigin - 1)); i ++) {
+                    System.arraycopy(pixels, start, newPixels, start, length);
+                    System.arraycopy(pixels, start1, newPixels, start1, length1);
+                    start +=rowLength;
+                    start1 +=rowLength;
+                }
+
+            }
+
+            // Cycle over pixels to be calculated
+            for (int i = yOrigin; i < srcConvMaxY; i++){
+                for (int j = xOrigin; j < srcConvMaxX; j++){
+
+                    // Take kernel data in backward direction, convolution
+                    int kernelIdx = data.length - 1;
+
+                    int pixelIndex = i * rowLength + j * numBands;
+                    for (int hIdx = 0, rasterHIdx = i - yOrigin;
+                         hIdx < kHeight;
+                         hIdx++, rasterHIdx++
+                            ){
+                        for (int wIdx = 0, rasterWIdx = j - xOrigin;
+                             wIdx < kWidth;
+                             wIdx++, rasterWIdx++
+                                ){
+                            int curIndex = rasterHIdx * rowLength + rasterWIdx * numBands;
+                            for (int idx=0; idx < numBands; idx++){
+                                newPixels[pixelIndex+idx] += data[kernelIdx] * pixels[curIndex+idx];
+                            }
+                            kernelIdx--;
+                        }
+                    }
+
+                    // Check for overflow now
+                    for (int idx=0; idx < numBands; idx++){
+                        if (((int)newPixels[pixelIndex+idx] & masks[idx]) != 0) {
+                            if (newPixels[pixelIndex+idx] < 0) {
+                                newPixels[pixelIndex+idx] = 0;
+                            } else {
+                                newPixels[pixelIndex+idx] = maxValues[idx];
+                            }
+                        }
+                    }
+                }
+            }
+
+            dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, newPixels);
+        } catch (Exception e) { // Something goes wrong, signal error
+            return 1;
+        }
+        return 0;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (src == null) {
+            // awt.259=Source image is null
+            throw new NullPointerException(Messages.getString("awt.259")); //$NON-NLS-1$
+        }
+
+        if (src == dst){
+            // awt.25A=Source equals to destination
+            throw new IllegalArgumentException(Messages.getString("awt.25A")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        BufferedImage finalDst = null;
+
+        if (srcCM instanceof IndexColorModel) {
+            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
+            srcCM = src.getColorModel();
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestImage(src, srcCM);
+        } else {
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB as same
+                if (
+                        !((src.getType() == BufferedImage.TYPE_INT_RGB ||
+                           src.getType() == BufferedImage.TYPE_INT_ARGB) &&
+                          (dst.getType() == BufferedImage.TYPE_INT_RGB ||
+                           dst.getType() == BufferedImage.TYPE_INT_ARGB))
+                ) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, srcCM);
+                }
+            }
+        }
+
+        // Skip alpha channel for TYPE_INT_RGB images
+        // TODO
+        //if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) != 0)
+            if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
+        int srcStride, dstStride;
+        boolean skipChannel = false;
+        int channels;
+        int offsets[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_RGB:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                skipChannel = true;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in native code?
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1, 3 and 4 channels
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst);
+                    }
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                     // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (
+                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
+                            !(channels == 3 || channels == 4)
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst);
+                        }
+                    }
+
+                    if (channels == 3) { // Cannot skip channel, don't know which is alpha...
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        return ippFilter32f(
+            kernel.data, kernel.getWidth(), kernel.getHeight(),
+            kernel.getXOrigin(), kernel.getYOrigin(), edgeCond,
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            channels, skipChannel, offsets
+        );
+    }
+
+    /**
+     * Ipp filter32f.
+     * 
+     * @param kernel the kernel
+     * @param kWidth the k width
+     * @param kHeight the k height
+     * @param anchorX the anchor x
+     * @param anchorY the anchor y
+     * @param borderType the border type
+     * @param src the src
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dst the dst
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param channels the channels
+     * @param skipChannel the skip channel
+     * @param offsets the offsets
+     * 
+     * @return the int
+     */
+    private native int ippFilter32f(
+                float kernel[], int kWidth, int kHeight,
+                int anchorX, int anchorY, int borderType,
+                Object src, int srcWidth, int srcHeight, int srcStride,
+                Object dst, int dstWidth, int dstHeight, int dstStride,
+                int channels, boolean skipChannel, int offsets[]
+            );
+}
+
diff --git a/awt/java/awt/image/CropImageFilter.java b/awt/java/awt/image/CropImageFilter.java
new file mode 100644
index 0000000..e90c44a
--- /dev/null
+++ b/awt/java/awt/image/CropImageFilter.java
@@ -0,0 +1,193 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The CropImageFilter class crops a rectangular region of an source
+ * Image and provides a source for a new image containing the extracted 
+ * region.
+ */
+public class CropImageFilter extends ImageFilter {
+
+    /** The HEIGHT. */
+    private final int X, Y, WIDTH, HEIGHT;
+
+    /**
+     * Instantiates a new CropImageFilter object with the specified
+     * rectangular area.
+     * 
+     * @param x the X coordinate of rectangular area. 
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     */
+    public CropImageFilter(int x, int y, int w, int h) {
+        X = x;
+        Y = y;
+        WIDTH = w;
+        HEIGHT = h;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if(props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>) props.clone();
+        }
+        String propName = "Crop Filters"; //$NON-NLS-1$
+        String prop = "x=" + X + "; y=" + Y + "; width=" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        WIDTH + "; height=" + HEIGHT; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if(o != null){
+            if(o instanceof String){
+                prop = (String)o + "; " + prop; //$NON-NLS-1$
+            }else{
+                prop =  o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) {
+
+        if(x + w < X || X + WIDTH < x ||
+                y + h < Y || Y + HEIGHT < y) {
+            return;
+        }
+
+        int destX, destY, destWidth, destHeight, endX, endY,
+        srcEndX, srcEndY;
+
+        int newOffset = off;
+
+        endX = X + WIDTH;
+        endY = Y + HEIGHT;
+
+        srcEndX = x + w;
+        srcEndY = y + h;
+
+        if(x <= X){
+            destX = 0;
+            newOffset += X;
+            if(endX >= srcEndX){
+                destWidth = srcEndX - X;
+            }else{
+                destWidth = WIDTH;
+            }
+        }else{
+            destX = x - X;
+            if(endX >= srcEndX){
+                destWidth = w;
+            }else{
+                destWidth = endX - x;
+            }
+        }
+
+
+        if(y <= Y){
+            newOffset += scansize * (Y - y);
+            destY = 0;
+            if(endY >= srcEndY){
+                destHeight = srcEndY - Y;
+            }else{
+                destHeight = HEIGHT;
+            }
+        }else{
+            destY = y - Y;
+            if(endY >= srcEndY){
+                destHeight = h;
+            }else{
+                destHeight = endY - y;
+            }
+        }
+        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) {
+
+        if(x + w < X || X + WIDTH < x ||
+                y + h < Y || Y + HEIGHT < y) {
+            return;
+        }
+
+        int destX, destY, destWidth, destHeight, endX, endY,
+        srcEndX, srcEndY;
+
+        int newOffset = off;
+
+        endX = X + WIDTH;
+        endY = Y + HEIGHT;
+
+        srcEndX = x + w;
+        srcEndY = y + h;
+
+        if(x <= X){
+            destX = 0;
+            newOffset += X;
+            if(endX >= srcEndX){
+                destWidth = srcEndX - X;
+            }else{
+                destWidth = WIDTH;
+            }
+        }else{
+            destX = x - X;
+            if(endX >= srcEndX){
+                destWidth = w;
+            }else{
+                destWidth = endX - x;
+            }
+        }
+
+
+        if(y <= Y){
+            newOffset += scansize * (Y - y);
+            destY = 0;
+            if(endY >= srcEndY){
+                destHeight = srcEndY - Y;
+            }else{
+                destHeight = HEIGHT;
+            }
+        }else{
+            destY = y - Y;
+            if(endY >= srcEndY){
+                destHeight = h;
+            }else{
+                destHeight = endY - y;
+            }
+        }
+        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
+    }
+
+    @Override
+    public void setDimensions(int w, int h) {
+        consumer.setDimensions(WIDTH, HEIGHT);
+    }
+
+}
+
diff --git a/awt/java/awt/image/DataBuffer.java b/awt/java/awt/image/DataBuffer.java
new file mode 100644
index 0000000..6856aee
--- /dev/null
+++ b/awt/java/awt/image/DataBuffer.java
@@ -0,0 +1,442 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DataBuffer is a wrapper class for a data array
+ * to be used for the situation where a suite of functionality
+ * acts on a set of data in a consistent way even though the 
+ * primitive type of the data may vary from one use to the next. 
+ */
+public abstract class DataBuffer {
+
+    /** The Constant TYPE_BYTE. */
+    public static final int TYPE_BYTE = 0;
+
+    /** The Constant TYPE_USHORT. */
+    public static final int TYPE_USHORT = 1;
+
+    /** The Constant TYPE_SHORT. */
+    public static final int TYPE_SHORT = 2;
+
+    /** The Constant TYPE_INT. */
+    public static final int TYPE_INT = 3;
+
+    /** The Constant TYPE_FLOAT. */
+    public static final int TYPE_FLOAT = 4;
+
+    /** The Constant TYPE_DOUBLE. */
+    public static final int TYPE_DOUBLE = 5;
+
+    /** The Constant TYPE_UNDEFINED. */
+    public static final int TYPE_UNDEFINED = 32;
+
+    /** The data type indicates the primitive type of the 
+     * data in this DataBuffer. */
+    protected int dataType;
+
+    /** The number of data arrays in this DataBuffer. */
+    protected int banks;
+
+    /** The starting index for reading the 
+     * data from the first (or only) internal data array. */
+    protected int offset;
+
+    /** The length (number of elements) of the data arrays. */
+    protected int size;
+
+    /** The starting indices for reading the 
+     * data from the internal data arrays. */
+    protected int offsets[];
+    
+    /** The data changed. */
+    boolean dataChanged = true;
+    
+    /** The data taken. */
+    boolean dataTaken = false;
+    
+    /** The listener. */
+    DataBufferListener listener;
+
+    static {
+        AwtImageBackdoorAccessorImpl.init();
+    }
+
+    /**
+     * Instantiates a new data buffer.
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     * @param numBanks the number of data arrays to create
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offsets = offsets.clone();
+        this.offset = offsets[0];
+    }
+
+    /**
+     * Instantiates a new data buffer with all of the 
+     * data arrays starting at the same index.
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     * @param numBanks the number of data arrays to create
+     * @param offset the offset to use for all of the data arrays
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int offset) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offset = offset;
+        this.offsets = new int[numBanks];
+        int i = 0;
+        while (i < numBanks) {
+            offsets[i++] = offset;
+        }
+    }
+
+    /**
+     * Instantiates a new data buffer with all of the 
+     * data arrays read from the beginning (at offset zero).
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    protected DataBuffer(int dataType, int size, int numBanks) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offset = 0;
+        this.offsets = new int[numBanks];
+    }
+
+    /**
+     * Instantiates a new data buffer with one internal data array
+     * read from the beginning (at offset zero).
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     */
+    protected DataBuffer(int dataType, int size) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = 1;
+        this.offset = 0;
+        this.offsets = new int[1];
+    }
+
+    /**
+     * Sets the data value in the specified array at the 
+     * specified index.
+     * 
+     * @param bank the internal array to the data to
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public abstract void setElem(int bank, int i, int val);
+
+    /**
+     * Sets the float data value in the specified array at the 
+     * specified index.
+     * 
+     * @param bank the internal array to the data to
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemFloat(int bank, int i, float val) {
+        setElem(bank, i, (int) val);
+    }
+
+    /**
+     * Sets the double data value in the specified array at the 
+     * specified index.
+     * 
+     * @param bank the internal array to the data to
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemDouble(int bank, int i, double val) {
+        setElem(bank, i, (int) val);
+    }
+
+    /**
+     * Sets the data value in the first array at the 
+     * specified index.
+     * 
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElem(int i, int val) {
+        setElem(0, i, val);
+    }
+
+    /**
+     * Gets the data value from the specified data array at the 
+     * specified index.
+     * 
+     * @param bank the data array to read from
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public abstract int getElem(int bank, int i);
+
+    /**
+     * Gets the float-type data value from the specified 
+     * data array at the specified index.
+     * 
+     * @param bank the data array to read from
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public float getElemFloat(int bank, int i) {
+        return getElem(bank, i);
+    }
+
+    /**
+     * Gets the double-type data value from the specified 
+     * data array at the specified index.
+     * 
+     * @param bank the data array to read from
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public double getElemDouble(int bank, int i) {
+        return getElem(bank, i);
+    }
+
+    /**
+     * Sets the float data value in the first array at the 
+     * specified index.
+     * 
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemFloat(int i, float val) {
+        setElemFloat(0, i, val);
+    }
+
+    /**
+     * Sets the double data value in the first array at the 
+     * specified index.
+     * 
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemDouble(int i, double val) {
+        setElemDouble(0, i, val);
+    }
+
+    /**
+     * Gets the data value from the first 
+     * data array at the specified index and returns it
+     * as an int.
+     * 
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public int getElem(int i) {
+        return getElem(0, i);
+    }
+
+    /**
+     * Gets the data value from the first 
+     * data array at the specified index and returns it
+     * as a float.
+     * 
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public float getElemFloat(int i) {
+        return getElem(0, i);
+    }
+
+    /**
+     * Gets the data value from the first 
+     * data array at the specified index and returns it
+     * as a double.
+     * 
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public double getElemDouble(int i) {
+        return getElem(i);
+    }
+
+    /**
+     * Gets the array giving the offsets corresponding 
+     * to the internal data arrays.
+     * 
+     * @return the array of offsets
+     */
+    public int[] getOffsets() {
+        return offsets;
+    }
+
+    /**
+     * Gets the size in bits of the primitive data type.
+     * 
+     * @return the size in bits of the primitive data type
+
+     */
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * Gets the offset corresponding to the first internal 
+     * data array.
+     * 
+     * @return the offset
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Gets the number of data arrays in this DataBuffer.
+     * 
+     * @return the number of data arrays
+     */
+    public int getNumBanks() {
+        return banks;
+    }
+
+    /**
+     * Gets the primitive type of this buffer's data.
+     * 
+     * @return the data type
+     */
+    public int getDataType() {
+        return this.dataType;
+    }
+
+    /**
+     * Gets the size in bits of the primitive data type.
+     * 
+     * @param type the primitive type
+     * 
+     * @return the size in bits of the primitive data type
+     */
+    public static int getDataTypeSize(int type) {
+        switch (type) {
+
+        case TYPE_BYTE:
+            return 8;
+
+        case TYPE_USHORT:
+        case TYPE_SHORT:
+            return 16;
+
+        case TYPE_INT:
+        case TYPE_FLOAT:
+            return 32;
+
+        case TYPE_DOUBLE:
+            return 64;
+
+        default:
+            // awt.22C=Unknown data type {0}
+            throw new IllegalArgumentException(Messages.getString("awt.22C", type)); //$NON-NLS-1$
+        }
+    }
+    
+    /**
+     * Notifies the listener that the data has changed.
+     */
+    void notifyChanged(){
+        if(listener != null && !dataChanged){
+            dataChanged = true;
+            listener.dataChanged();
+        }
+    }
+    
+    /**
+     * Notifies the listener that the data has been released.
+     */
+    void notifyTaken(){
+        if(listener != null && !dataTaken){
+            dataTaken = true;
+            listener.dataTaken();
+        }
+    }
+    
+    /**
+     * Release the data.
+     */
+    void releaseData(){
+        if(listener != null && dataTaken){
+            dataTaken = false;
+            listener.dataReleased();
+        }
+    }
+    
+    /**
+     * Adds the data buffer listener.
+     * 
+     * @param listener the listener
+     */
+    void addDataBufferListener(DataBufferListener listener){
+        this.listener = listener;
+    }
+    
+    /**
+     * Removes the data buffer listener.
+     */
+    void removeDataBufferListener(){
+        listener = null;
+    }
+    
+    /**
+     * Validate.
+     */
+    void validate(){
+        dataChanged = false;
+    }
+    
+}
+
diff --git a/awt/java/awt/image/DataBufferByte.java b/awt/java/awt/image/DataBufferByte.java
new file mode 100644
index 0000000..4d29c9c
--- /dev/null
+++ b/awt/java/awt/image/DataBufferByte.java
@@ -0,0 +1,171 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferByte is the subclass of DataBuffer
+ * for the case where the underlying data is of type byte.
+ */
+public final class DataBufferByte extends DataBuffer {
+
+    /** The data. */
+    byte data[][];
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferByte(byte dataArrays[][], int size, int offsets[]) {
+        super(TYPE_BYTE, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferByte(byte dataArrays[][], int size) {
+        super(TYPE_BYTE, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferByte(byte dataArray[], int size, int offset) {
+        super(TYPE_BYTE, size, 1, offset);
+        data = new byte[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferByte(byte dataArray[], int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferByte(int size, int numBanks) {
+        super(TYPE_BYTE, size, numBanks);
+        data = new byte[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new byte[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferByte(int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[1][];
+        data[0] = new byte[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (byte) val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (byte) val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]) & 0xff;
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public byte[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]) & 0xff;
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public byte[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public byte[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+
+}
+
diff --git a/awt/java/awt/image/DataBufferDouble.java b/awt/java/awt/image/DataBufferDouble.java
new file mode 100644
index 0000000..fa3d324
--- /dev/null
+++ b/awt/java/awt/image/DataBufferDouble.java
@@ -0,0 +1,214 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferDouble is the subclass of DataBuffer
+ * for the case where the underlying data is of type double.
+ */
+public final class DataBufferDouble extends DataBuffer {
+
+    /** The data. */
+    double data[][];
+
+    /**
+     * Instantiates a new data buffer of type double.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+    */
+    public DataBufferDouble(double dataArrays[][], int size, int offsets[]) {
+        super(TYPE_DOUBLE, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type double.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferDouble(double dataArrays[][], int size) {
+        super(TYPE_DOUBLE, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type double
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferDouble(double dataArray[], int size, int offset) {
+        super(TYPE_DOUBLE, size, 1, offset);
+        data = new double[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type double
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferDouble(double dataArray[], int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type double
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferDouble(int size, int numBanks) {
+        super(TYPE_DOUBLE, size, numBanks);
+        data = new double[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new double[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type double
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferDouble(int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[1][];
+        data[0] = new double[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemFloat(int bank, int i, float val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int bank, int i, double val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) (data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public float getElemFloat(int bank, int i) {
+        return (float) (data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public double getElemDouble(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public void setElemFloat(int i, float val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int i, double val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public double[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (int) (data[0][offset + i]);
+    }
+
+    @Override
+    public float getElemFloat(int i) {
+        return (float) (data[0][offset + i]);
+    }
+
+    @Override
+    public double getElemDouble(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public double[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public double[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferFloat.java b/awt/java/awt/image/DataBufferFloat.java
new file mode 100644
index 0000000..e34245c
--- /dev/null
+++ b/awt/java/awt/image/DataBufferFloat.java
@@ -0,0 +1,214 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferFloat is the subclass of DataBuffer
+ * for the case where the underlying data is float.
+ */
+public final class DataBufferFloat extends DataBuffer {
+
+    /** The data. */
+    float data[][];
+
+    /**
+     * Instantiates a new data buffer of type float.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferFloat(float dataArrays[][], int size, int offsets[]) {
+        super(TYPE_FLOAT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type float.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferFloat(float dataArrays[][], int size) {
+        super(TYPE_FLOAT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type float
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferFloat(float dataArray[], int size, int offset) {
+        super(TYPE_FLOAT, size, 1, offset);
+        data = new float[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type float
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferFloat(float dataArray[], int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type float
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferFloat(int size, int numBanks) {
+        super(TYPE_FLOAT, size, numBanks);
+        data = new float[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new float[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type float
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferFloat(int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[1][];
+        data[0] = new float[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemFloat(int bank, int i, float val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int bank, int i, double val) {
+        data[bank][offsets[bank] + i] = (float) val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) (data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public float getElemFloat(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public double getElemDouble(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public void setElemFloat(int i, float val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int i, double val) {
+        data[0][offset + i] = (float) val;
+        notifyChanged();
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired array
+     * 
+     * @return the data
+     */
+    public float[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (int) (data[0][offset + i]);
+    }
+
+    @Override
+    public float getElemFloat(int i) {
+        return data[0][offset + i];
+    }
+
+    @Override
+    public double getElemDouble(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public float[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public float[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferInt.java b/awt/java/awt/image/DataBufferInt.java
new file mode 100644
index 0000000..43dc188
--- /dev/null
+++ b/awt/java/awt/image/DataBufferInt.java
@@ -0,0 +1,170 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferInt is the subclass of DataBuffer
+ * for the case where the underlying data is of type int.
+ */
+public final class DataBufferInt extends DataBuffer {
+
+    /** The data. */
+    int data[][];
+
+    /**
+     * Instantiates a new data buffer of type int.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferInt(int dataArrays[][], int size, int offsets[]) {
+        super(TYPE_INT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type int.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferInt(int dataArrays[][], int size) {
+        super(TYPE_INT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type int
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferInt(int dataArray[], int size, int offset) {
+        super(TYPE_INT, size, 1, offset);
+        data = new int[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type int
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferInt(int dataArray[], int size) {
+        super(TYPE_INT, size);
+        data = new int[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type int
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferInt(int size, int numBanks) {
+        super(TYPE_INT, size, numBanks);
+        data = new int[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new int[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type int
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferInt(int size) {
+        super(TYPE_INT, size);
+        data = new int[1][];
+        data[0] = new int[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public int[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public int[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public int[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferShort.java b/awt/java/awt/image/DataBufferShort.java
new file mode 100644
index 0000000..819ba4a
--- /dev/null
+++ b/awt/java/awt/image/DataBufferShort.java
@@ -0,0 +1,172 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferShort is the subclass of DataBuffer
+ * for the case where the underlying data is short.
+ */
+public final class DataBufferShort extends DataBuffer {
+
+    /** The data. */
+    short data[][];
+
+    /**
+     * Instantiates a new data buffer of type short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferShort(short dataArrays[][], int size, int offsets[]) {
+        super(TYPE_SHORT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferShort(short dataArrays[][], int size) {
+        super(TYPE_SHORT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type short
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+
+     */
+    public DataBufferShort(short dataArray[], int size, int offset) {
+        super(TYPE_SHORT, size, 1, offset);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+
+     */
+    public DataBufferShort(short dataArray[], int size) {
+        super(TYPE_SHORT, size);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type short
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferShort(int size, int numBanks) {
+        super(TYPE_SHORT, size, numBanks);
+        data = new short[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new short[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferShort(int size) {
+        super(TYPE_SHORT, size);
+        data = new short[1][];
+        data[0] = new short[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (short) val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (short) val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]);
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public short[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]);
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public short[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public short[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferUShort.java b/awt/java/awt/image/DataBufferUShort.java
new file mode 100644
index 0000000..7982678
--- /dev/null
+++ b/awt/java/awt/image/DataBufferUShort.java
@@ -0,0 +1,182 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DataBufferUShort is the subclass of DataBuffer
+ * for the case where the underlying data is unsigned short.
+ */
+public final class DataBufferUShort extends DataBuffer {
+
+    /** The data. */
+    short data[][];
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferUShort(short dataArrays[][], int size, int offsets[]) {
+        super(TYPE_USHORT, size, dataArrays.length, offsets);
+        for(int i = 0; i < dataArrays.length; i++){
+            if(dataArrays[i].length < offsets[i] + size){
+                // awt.28d=Length of dataArray[{0}] is less than size + offset[{1}]
+                throw new IllegalArgumentException(Messages.getString("awt.28D", i, i));  //$NON-NLS-1$
+            }
+        }
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferUShort(short dataArrays[][], int size) {
+        super(TYPE_USHORT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferUShort(short dataArray[], int size, int offset) {
+        super(TYPE_USHORT, size, 1, offset);
+        if(dataArray.length < size + offset){
+            // awt.28E=Length of dataArray is less than size + offset
+            throw new IllegalArgumentException(Messages.getString("awt.28E")); //$NON-NLS-1$
+        }
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferUShort(short dataArray[], int size) {
+        super(TYPE_USHORT, size);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferUShort(int size, int numBanks) {
+        super(TYPE_USHORT, size, numBanks);
+        data = new short[numBanks][];
+        int i= 0;
+        while( i < numBanks) {
+            data[i++] = new short[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferUShort(int size) {
+        super(TYPE_USHORT, size);
+        data = new short[1][];
+        data[0] = new short[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]) & 0xffff;
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public short[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]) & 0xffff;
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public short[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public short[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DirectColorModel.java b/awt/java/awt/image/DirectColorModel.java
new file mode 100644
index 0000000..7a287c0
--- /dev/null
+++ b/awt/java/awt/image/DirectColorModel.java
@@ -0,0 +1,862 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.color.ColorSpace;
+import java.awt.Transparency;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DirectColorModel represents a standard (packed) RGB
+ * color model with additional support for converting between sRGB
+ * color space and 8 or 16 bit linear RGB color space using lookup tables.
+ */
+public class DirectColorModel extends PackedColorModel {
+
+    /** The from_ linea r_ rg b_ lut. */
+    private byte from_LINEAR_RGB_LUT[]; // Lookup table for conversion from
+                                        // Linear RGB Color Space into sRGB
+
+    /** The to_ linea r_8 rg b_ lut. */
+    private byte to_LINEAR_8RGB_LUT[];  // Lookup table for conversion from
+                                        // sRGB Color Space into Linear RGB 
+                                        // 8 bit
+
+    /** The to_ linea r_16 rg b_ lut. */
+    private short to_LINEAR_16RGB_LUT[];  // Lookup table for conversion from
+                                          // sRGB Color Space into Linear RGB 
+                                          // 16 bit 
+
+    /** The alpha lut. */
+    private byte alphaLUT[];            // Lookup table for scale alpha value  
+
+    /** The color lu ts. */
+    private byte colorLUTs[][];         // Lookup tables for scale color values 
+
+    /** The is_s rgb. */
+    private boolean is_sRGB;            // ColorModel has sRGB ColorSpace
+
+    /** The is_ linea r_ rgb. */
+    private boolean is_LINEAR_RGB;      // Color Model has Linear RGB Color 
+                                        // Space
+
+    /** The LINEA r_ rg b_ length. */
+    private int LINEAR_RGB_Length;      // Linear RGB bit length
+
+    /** The factor. */
+    private float fFactor;              // Scale factor
+
+    /**
+     * Instantiates a new direct color model.
+     * 
+     * @param space the color space
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     * @param amask the bitmask corresponding to the alpha band
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this color model
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the number of bits in the combined 
+     * bitmasks for the color bands is less than one or greater than 32
+     */
+    public DirectColorModel(ColorSpace space, int bits, int rmask, int gmask,
+            int bmask, int amask, boolean isAlphaPremultiplied,
+            int transferType) {
+
+        super(space, bits, rmask, gmask, bmask, amask, isAlphaPremultiplied,
+                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
+                transferType);
+
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new direct color model, determining the transfer 
+     * type from the bits array, the transparency from the alpha mask, 
+     * and the default color space {@link ColorSpace#CS_sRGB}.
+     * 
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     * @param amask the bitmask corresponding to the alpha band
+     */
+    public DirectColorModel(int bits, int rmask, int gmask, int bmask,
+            int amask) {
+
+        super(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits, rmask, gmask,
+                bmask, amask, false,
+                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
+                ColorModel.getTransferType(bits));
+
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new direct color model with no alpha channel, 
+     * determining the transfer type from the bits array, 
+     * the default color space {@link ColorSpace#CS_sRGB}, 
+     * and with the transparency set to {@link Transparency#OPAQUE}.
+     * 
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     */
+    public DirectColorModel(int bits, int rmask, int gmask, int bmask) {
+        this(bits, rmask, gmask, bmask, 0);
+    }
+
+    @Override
+    public Object getDataElements(int components[], int offset, Object obj) {
+        int pixel = 0;
+        for (int i = 0; i < numComponents; i++) {
+            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (obj == null) {
+                ba = new byte[1];
+            } else {
+                ba = (byte[]) obj;
+            }
+            ba[0] = (byte) pixel;
+            obj = ba;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[];
+            if (obj == null) {
+                sa = new short[1];
+            } else {
+                sa = (short[]) obj;
+            }
+            sa[0] = (short) pixel;
+            obj = sa;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (obj == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[]) obj;
+            }
+            ia[0] = pixel;
+            obj = ia;
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+
+        return obj;
+    }
+
+    @Override
+    public Object getDataElements(int rgb, Object pixel) {
+        if (equals(ColorModel.getRGBdefault())) {
+            int ia[];
+            if (pixel == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[]) pixel;
+            }
+            ia[0] = rgb;
+            return ia;
+        }
+
+        int alpha = (rgb >> 24) & 0xff;
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+
+        float comp[] = new float[numColorComponents];
+        float normComp[] = null;
+
+        if (is_sRGB || is_LINEAR_RGB) {
+            if (is_LINEAR_RGB) {
+                if (LINEAR_RGB_Length == 8) {
+                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
+                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
+                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
+                } else {
+                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
+                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
+                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
+                }
+            }
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            if (!hasAlpha) {
+                normComp = comp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = comp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        } else {
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            float rgbComp[] = cs.fromRGB(comp);
+            if (!hasAlpha) {
+                normComp = rgbComp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = rgbComp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        }
+
+        int pxl = 0;
+        if (hasAlpha) {
+            float normAlpha = normComp[numColorComponents];
+            alpha = (int) (normAlpha * maxValues[numColorComponents] + 0.5f);
+            if (isAlphaPremultiplied) {
+                red = (int) (normComp[0] * normAlpha * maxValues[0] + 0.5f);
+                green = (int) (normComp[1] * normAlpha * maxValues[1] + 0.5f);
+                blue = (int) (normComp[2] * normAlpha * maxValues[2] + 0.5f);
+            } else {
+                red = (int) (normComp[0] * maxValues[0] + 0.5f);
+                green = (int) (normComp[1] * maxValues[1] + 0.5f);
+                blue = (int) (normComp[2] * maxValues[2] + 0.5f);
+            }
+            pxl = (alpha << offsets[3]) & componentMasks[3];
+        } else {
+            red = (int) (normComp[0] * maxValues[0] + 0.5f);
+            green = (int) (normComp[1] * maxValues[1] + 0.5f);
+            blue = (int) (normComp[2] * maxValues[2] + 0.5f);
+        }
+
+        pxl |= ((red << offsets[0]) & componentMasks[0]) |
+               ((green << offsets[1]) & componentMasks[1]) |
+               ((blue << offsets[2]) & componentMasks[2]);
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (pixel == null) {
+                ba = new byte[1];
+            } else {
+                ba = (byte[]) pixel;
+            }
+            ba[0] = (byte) pxl;
+            return ba;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[];
+            if (pixel == null) {
+                sa = new short[1];
+            } else {
+                sa = (short[]) pixel;
+            }
+            sa[0] = (short) pxl;
+            return sa;
+
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (pixel == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[]) pixel;
+            }
+            ia[0] = pxl;
+            return ia;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public final ColorModel coerceData(WritableRaster raster,
+            boolean isAlphaPremultiplied) {
+
+        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
+            return this;
+        }
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        int components[] = null;
+        int transparentComponents[] = new int[numComponents];
+
+        float alphaFactor = maxValues[numColorComponents];
+
+        if (isAlphaPremultiplied) {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        components = raster.getPixel(x, minY, components);
+                        if (components[numColorComponents] == 0) {
+                            raster.setPixel(x, minY, transparentComponents);
+                        } else {
+                            float alpha =
+                                components[numColorComponents] /
+                                    alphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                components[n] =
+                                    (int) (alpha * components[n] + 0.5f);
+                            }
+                            raster.setPixel(x, minY, components);
+                        }
+                    }
+
+                }
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+            }
+        } else {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        components = raster.getPixel(x, minY, components);
+                        if (components[numColorComponents] != 0) {
+                            float alpha =
+                                alphaFactor / components[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                components[n] =
+                                    (int) (alpha * components[n] + 0.5f);
+                            }
+                            raster.setPixel(x, minY, components);
+                        }
+                    }
+
+                }
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+            }
+
+        }
+
+        return new DirectColorModel(cs, pixel_bits, componentMasks[0],
+                componentMasks[1], componentMasks[2], componentMasks[3],
+                isAlphaPremultiplied, transferType);
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. 
+        // It could be reveled such way:
+        // BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+        // ColorModel cm = bi.getColorModel();
+        // System.out.println(cm.toString());
+        String str = "DirectColorModel:" + " rmask = " + //$NON-NLS-1$ //$NON-NLS-2$
+               Integer.toHexString(componentMasks[0]) + " gmask = " + //$NON-NLS-1$
+               Integer.toHexString(componentMasks[1]) + " bmask = " + //$NON-NLS-1$
+               Integer.toHexString(componentMasks[2]) + " amask = " + //$NON-NLS-1$
+               (!hasAlpha ? "0" : Integer.toHexString(componentMasks[3])); //$NON-NLS-1$
+
+        return str;
+    }
+
+    @Override
+    public final int[] getComponents(Object pixel, int components[],
+            int offset) {
+
+        if (components == null) {
+            components = new int[numComponents + offset];
+        }
+
+        int intPixel = 0;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            intPixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) pixel;
+            intPixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            intPixel = ia[0];
+            break;
+
+        default:
+            // awt.22D=This transferType ( {0} ) is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
+                   transferType));
+        }
+
+        return getComponents(intPixel, components, offset);
+    }
+
+    @Override
+    public int getRed(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getRed(pixel);
+    }
+
+    @Override
+    public int getRGB(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getRGB(pixel);
+    }
+
+    @Override
+    public int getGreen(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getGreen(pixel);
+    }
+
+    @Override
+    public int getBlue(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getBlue(pixel);
+    }
+
+    @Override
+    public int getAlpha(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getAlpha(pixel);
+    }
+
+    @Override
+    public final WritableRaster createCompatibleWritableRaster(int w, int h) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        int bandMasks[] = componentMasks.clone();
+
+        if (pixel_bits > 16) {
+            return Raster.createPackedRaster(DataBuffer.TYPE_INT, w, h,
+                    bandMasks, null);
+        } else if (pixel_bits > 8) {
+            return Raster.createPackedRaster(DataBuffer.TYPE_USHORT, w, h,
+                    bandMasks, null);
+        } else {
+            return Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h,
+                    bandMasks, null);
+        }
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        SampleModel sm = raster.getSampleModel();
+        if (!(sm instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+
+        SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+
+        if (sppsm.getNumBands() != numComponents) {
+            return false;
+        }
+        if (raster.getTransferType() != transferType) {
+            return false;
+        }
+
+        int maskBands[] = sppsm.getBitMasks();
+        return Arrays.equals(maskBands, componentMasks);
+    }
+
+    @Override
+    public int getDataElement(int components[], int offset) {
+        int pixel = 0;
+        for (int i = 0; i < numComponents; i++) {
+            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
+        }
+        return pixel;
+    }
+
+    @Override
+    public final int[] getComponents(int pixel, int components[], int offset) {
+        if (components == null) {
+            components = new int[numComponents + offset];
+        }
+        for (int i = 0; i < numComponents; i++) {
+            components[offset + i] = (pixel & componentMasks[i]) >> offsets[i];
+        }
+        return components;
+    }
+
+    @Override
+    public final int getRed(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 0);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 0);
+        }
+        return getComponentFrom_RGB(pixel, 0);
+    }
+
+    @Override
+    public final int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) |
+               (getGreen(pixel) << 8) | getBlue(pixel);
+    }
+
+    @Override
+    public final int getGreen(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 1);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 1);
+        }
+        return getComponentFrom_RGB(pixel, 1);
+    }
+
+    @Override
+    public final int getBlue(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 2);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 2);
+        }
+        return getComponentFrom_RGB(pixel, 2);
+    }
+
+    @Override
+    public final int getAlpha(int pixel) {
+        if (!hasAlpha) {
+            return 255;
+        }
+        int a = (pixel & componentMasks[3]) >>> offsets[3];
+        if (bits[3] == 8) {
+            return a;
+        }
+        return alphaLUT[a] & 0xff;
+    }
+
+    /**
+     * Gets the red mask.
+     * 
+     * @return the red mask
+     */
+    public final int getRedMask() {
+        return componentMasks[0];
+    }
+
+    /**
+     * Gets the green mask.
+     * 
+     * @return the green mask
+     */
+    public final int getGreenMask() {
+        return componentMasks[1];
+    }
+
+    /**
+     * Gets the blue mask.
+     * 
+     * @return the blue mask
+     */
+    public final int getBlueMask() {
+        return componentMasks[2];
+    }
+
+    /**
+     * Gets the alpha mask.
+     * 
+     * @return the alpha mask
+     */
+    public final int getAlphaMask() {
+        if (hasAlpha) {
+            return componentMasks[3];
+        }
+        return 0;
+    }
+
+    /**
+     * Initialization of Lookup tables.
+     */
+    private void initLUTs() {
+        is_sRGB = cs.isCS_sRGB();
+        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
+
+        if (is_LINEAR_RGB) {
+            if (maxBitLength > 8) {
+                LINEAR_RGB_Length = 16;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom16lRGBtosRGB_LUT();
+                to_LINEAR_16RGB_LUT =
+                    LUTColorConverter.getFromsRGBto16lRGB_LUT();
+            } else {
+                LINEAR_RGB_Length = 8;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom8lRGBtosRGB_LUT();
+                to_LINEAR_8RGB_LUT =
+                    LUTColorConverter.getFromsRGBto8lRGB_LUT();
+            }
+            fFactor = ((1 << LINEAR_RGB_Length) - 1);
+        } else {
+            fFactor = 255.0f;
+        }
+
+        if (hasAlpha && bits[3] != 8) {
+            alphaLUT = new byte[maxValues[3] + 1];
+            for (int i = 0; i <= maxValues[3]; i++) {
+                alphaLUT[i] = (byte) (scales[3] * i + 0.5f);
+            }
+
+        }
+
+        if (!isAlphaPremultiplied) {
+            colorLUTs = new byte[3][];
+
+            if (is_sRGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != 8) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[i]; j++) {
+                            colorLUTs[i][j] = (byte) (scales[i] * j + 0.5f);
+                        }
+                    }
+                }
+            }
+
+            if (is_LINEAR_RGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != LINEAR_RGB_Length) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            int idx;
+                            if (LINEAR_RGB_Length == 8) {
+                                idx = (int) (scales[i] * j + 0.5f);
+                            } else {
+                                idx = (int) (scales[i] * j * 257.0f + 0.5f);
+                            }
+                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * This method return RGB component value if Color Model has
+     * sRGB ColorSpace.
+     * 
+     * @param pixel - INT representation of pixel
+     * @param idx - index of pixel component
+     * 
+     * @return - value of the pixel component scaled fro 0 to 255
+     */
+    private int getComponentFrom_sRGB(int pixel, int idx) {
+        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
+        if (isAlphaPremultiplied) {
+            int alpha = (pixel & componentMasks[3]) >>> offsets[3];
+            comp = alpha == 0 ? 0 : (int) (scales[idx] * comp * 255.0f /
+                    (scales[3] * alpha) + 0.5f);
+        } else if (bits[idx] != 8) {
+            comp = colorLUTs[idx][comp] & 0xff;
+        }
+        return comp;
+    }
+
+    /**
+     * This method return RGB component value if Color Model has
+     * Linear RGB ColorSpace.
+     * 
+     * @param pixel - INT representation of pixel
+     * @param idx - index of pixel component
+     * 
+     * @return - value of the pixel component scaled fro 0 to 255
+     */
+    private int getComponentFrom_LINEAR_RGB(int pixel, int idx) {
+        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
+        if (isAlphaPremultiplied) {
+            float factor = ((1 << LINEAR_RGB_Length) - 1);
+            int alpha = (pixel & componentMasks[3]) >> offsets[3];
+            comp = alpha == 0 ? 0 : (int) (scales[idx] * comp * factor /
+                    (scales[3] * alpha) + 0.5f);
+        } else if (bits[idx] != LINEAR_RGB_Length) {
+            comp = colorLUTs[idx][comp] & 0xff;
+        } else {
+            comp = from_LINEAR_RGB_LUT[comp] & 0xff;
+        }
+        return comp;
+    }
+
+    /**
+     * This method return RGB component value if Color Model has
+     * arbitrary RGB ColorSapce.
+     * 
+     * @param pixel - INT representation of pixel
+     * @param idx - index of pixel component
+     * 
+     * @return - value of the pixel component scaled fro 0 to 255
+     */
+    private int getComponentFrom_RGB(int pixel, int idx) {
+        int components[] = getComponents(pixel, null, 0);
+        float[] normComponents = getNormalizedComponents(components, 0, null, 0);
+        float[] sRGBcomponents = cs.toRGB(normComponents);
+        return (int) (sRGBcomponents[idx] * 255.0f + 0.5f);
+    }
+
+}
+
diff --git a/awt/java/awt/image/FilteredImageSource.java b/awt/java/awt/image/FilteredImageSource.java
new file mode 100644
index 0000000..6a41fa7
--- /dev/null
+++ b/awt/java/awt/image/FilteredImageSource.java
@@ -0,0 +1,88 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+
+/**
+ * The FilteredImageSource class is used for producing image data for a new 
+ * filtered version of the original image using the specified filter object. 
+ */
+public class FilteredImageSource implements ImageProducer {
+
+    /** The source. */
+    private final ImageProducer source;
+    
+    /** The filter. */
+    private final ImageFilter filter;
+
+    /** The cons table. */
+    private final Hashtable<ImageConsumer, ImageConsumer> consTable = new Hashtable<ImageConsumer, ImageConsumer>();
+
+    /**
+     * Instantiates a new FilteredImageSource object with 
+     * the specified ImageProducer and the ImageFilter objects.
+     * 
+     * @param orig the specified ImageProducer.
+     * @param imgf the specified ImageFilter.
+     */
+    public FilteredImageSource(ImageProducer orig, ImageFilter imgf) {
+        source = orig;
+        filter = imgf;
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        if(ic != null) {
+            return consTable.containsKey(ic);
+        }
+        return false;
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+        ImageConsumer fic = consTable.get(ic);
+        source.startProduction(fic);
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+        if(ic != null && isConsumer(ic)){
+            ImageFilter fic = (ImageFilter) consTable.get(ic);
+            fic.resendTopDownLeftRight(source);
+        }
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        if(ic != null && isConsumer(ic)){
+            ImageConsumer fic = consTable.get(ic);
+            source.removeConsumer(fic);
+            consTable.remove(ic);
+        }
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if(ic != null && !isConsumer(ic)){
+            ImageConsumer fic = filter.getFilterInstance(ic);
+            source.addConsumer(fic);
+            consTable.put(ic, fic);
+        }
+    }
+}
diff --git a/awt/java/awt/image/ImageConsumer.java b/awt/java/awt/image/ImageConsumer.java
new file mode 100644
index 0000000..2eba290
--- /dev/null
+++ b/awt/java/awt/image/ImageConsumer.java
@@ -0,0 +1,165 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The ImageConsumer interface provides the data about the image
+ * and about how its data is delivered.  A ImageProducer provides 
+ * all of the information about the image using 
+ * the methods defined in this interface.
+ */
+public interface ImageConsumer {
+
+    /** 
+     * The Constant RANDOMPIXELORDER indicates that the pixels are 
+     * delivered in a random order.
+     */
+    public static final int RANDOMPIXELORDER = 1;
+
+    /** 
+     * The Constant TOPDOWNLEFTRIGHT indicates that the pixels are 
+     * delivered in top-down, left-to-right order. 
+     */
+    public static final int TOPDOWNLEFTRIGHT = 2;
+
+    /** 
+     * The Constant COMPLETESCANLINES indicates that the pixels are
+     * delivered in complete scanline. 
+     */
+    public static final int COMPLETESCANLINES = 4;
+
+    /** 
+     * The Constant SINGLEPASS indicates that pixels are delivered 
+     * in a single pass. 
+     */
+    public static final int SINGLEPASS = 8;
+
+    /** 
+     * The Constant SINGLEFRAME indicates that image consists of
+     * single frame.
+     */
+    public static final int SINGLEFRAME = 16;
+
+    /** 
+     * The Constant IMAGEERROR indicates an image error during image producing.
+     */
+    public static final int IMAGEERROR = 1;
+
+    /** 
+     * The Constant SINGLEFRAMEDONE indicates that only one of the 
+     * image's frames is completed. 
+     */
+    public static final int SINGLEFRAMEDONE = 2;
+
+    /** 
+     * The Constant STATICIMAGEDONE indicates that the image is completed. 
+     */
+    public static final int STATICIMAGEDONE = 3;
+
+    /** 
+     * The Constant IMAGEABORTED indicates that the image producing 
+     * process is aborted. 
+     */
+    public static final int IMAGEABORTED = 4;
+
+    /**
+     * Sets the properties for the image associated with this ImageConsumer.
+     * 
+     * @param props the properties for the image associated with 
+     * this ImageConsumer.
+     */
+    public void setProperties(Hashtable<?, ?> props);
+
+    /**
+     * Sets the ColorModel object.
+     * 
+     * @param model the new ColorModel.
+     */
+    public void setColorModel(ColorModel model);
+
+    /**
+     * Sets the pixels for the specified rectangular area of the image.
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param model the specified ColorModel to be used for pixels
+     * converting.  
+     * @param pixels the array of pixels.
+     * @param off the offset of pixels array.
+     * @param scansize the distance from the one row of pixels
+     * to the next row in the specified array.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            int[] pixels, int off, int scansize);
+
+    /**
+     * Sets the pixels for the specified rectangular area of the image.
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param model the specified ColorModel to be used for pixels
+     * converting.  
+     * @param pixels the array of pixels.
+     * @param off the offset of pixels array.
+     * @param scansize the distance from the one row of pixels
+     * to the next row in the specified array.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            byte[] pixels, int off, int scansize);
+
+    /**
+     * Sets the dimensions of a source image.
+     * 
+     * @param width the width of the image.
+     * @param height the height of the image.
+     */
+    public void setDimensions(int width, int height);
+
+    /**
+     * Sets the hint flags of pixels order, which is used by 
+     * the ImageConsumer for obtaining pixels from the ImageProducer
+     * for which this ImageConsumer is added.
+     * 
+     * @param hintflags the mask of hint flags. 
+     */
+    public void setHints(int hintflags);
+
+    /**
+     * THis method is called in the one of the following cases:
+     * <ul>
+     * <li>The ImageProducer (for which this ImageConsumer is added) 
+     * has been delivered all pixels of the source image. </li>
+     * <li>A one frame of an animation has been completed. </li> 
+     * <li> An error while loading or producing of the image has occured.
+     * </ul> 
+     * 
+     * @param status the status of image producing.
+     */
+    public void imageComplete(int status);
+
+}
+
diff --git a/awt/java/awt/image/ImageFilter.java b/awt/java/awt/image/ImageFilter.java
new file mode 100644
index 0000000..e386d65
--- /dev/null
+++ b/awt/java/awt/image/ImageFilter.java
@@ -0,0 +1,129 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The ImageFilter class provides a filter for delivering image data 
+ * from an ImageProducer to an ImageConsumer.
+ */
+public class ImageFilter implements ImageConsumer, Cloneable {
+
+    /** The consumer. */
+    protected ImageConsumer consumer;
+
+    /**
+     * Instantiates a new ImageFilter.
+     */
+    public ImageFilter() {
+        super();
+    }
+
+    /**
+     * Gets an instance of an ImageFilter object which performs
+     * the filtering for the specified ImageConsumer.
+     *  
+     * @param ic the specified ImageConsumer.
+     * 
+     * @return an ImageFilter used to perform the filtering for 
+     * the specified ImageConsumer.
+     */
+    public ImageFilter getFilterInstance(ImageConsumer ic) {
+        ImageFilter filter = (ImageFilter) clone();
+        filter.consumer = ic;
+        return filter;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if (props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>) props.clone();
+        }
+        String propName = "Filters"; //$NON-NLS-1$
+        String prop = "Null filter"; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if (o != null) {
+            if (o instanceof String) {
+                prop = (String) o + "; " + prop; //$NON-NLS-1$
+            } else {
+                prop = o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+    }
+
+    /**
+     * Returns a copy of this ImageFilter.
+     * 
+     * @return a copy of this ImageFilter.
+     */
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Responds to a request for a Top-Down-Left-Right ordered 
+     * resend of the pixel data from an ImageConsumer. 
+     * 
+     * @param ip the ImageProducer that provides this instance of 
+     * the filter.
+     */
+    public void resendTopDownLeftRight(ImageProducer ip) {
+        ip.requestTopDownLeftRightResend(this);
+    }
+
+    public void setColorModel(ColorModel model) {
+        consumer.setColorModel(model);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize) {
+        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize) {
+        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
+    }
+
+    public void setDimensions(int width, int height) {
+        consumer.setDimensions(width, height);
+    }
+
+    public void setHints(int hints) {
+        consumer.setHints(hints);
+    }
+
+    public void imageComplete(int status) {
+        consumer.imageComplete(status);
+    }
+
+}
diff --git a/awt/java/awt/image/ImageObserver.java b/awt/java/awt/image/ImageObserver.java
new file mode 100644
index 0000000..418bd07
--- /dev/null
+++ b/awt/java/awt/image/ImageObserver.java
@@ -0,0 +1,99 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Image;
+
+/**
+ * the ImageObserver interface is an asynchronous update interface 
+ * for receiving notifications about Image construction status.
+ */
+public interface ImageObserver {
+
+    /** 
+     * The Constant WIDTH indicates that the width of the image is 
+     * available. 
+     */
+    public static final int WIDTH = 1;
+
+    /** 
+     * The Constant HEIGHT indicates that the width of the image is 
+     * available.
+     */
+    public static final int HEIGHT = 2;
+
+    /** 
+     * The Constant PROPERTIES indicates that the properties of the image
+     * are available. 
+     */
+    public static final int PROPERTIES = 4;
+
+    /**
+     *  The Constant SOMEBITS indicates that more bits needed for 
+     *  drawing a scaled variation of the image pixels are available.
+     */
+    public static final int SOMEBITS = 8;
+
+    /** 
+     * The Constant FRAMEBITS indicates that complete frame of 
+     * a image which was previously drawn is now available
+     * for drawing again. 
+     */
+    public static final int FRAMEBITS = 16;
+
+    /** 
+     * The Constant ALLBITS indicates that an image which 
+     * was previously drawn is now complete and can be drawn again. 
+     */
+    public static final int ALLBITS = 32;
+
+    /** 
+     * The Constant ERROR indicates that error occured. 
+     */
+    public static final int ERROR = 64;
+
+    /** 
+     * The Constant ABORT indicates that the image producing is 
+     * aborted.
+     */
+    public static final int ABORT = 128;
+
+    /**
+     * This method is called when information about an Image
+     * interface becomes available. This method returns true 
+     * if further updates are needed, false if not.
+     * 
+     * @param img the image to be observed.
+     * @param infoflags the bitwise OR combination of information flags:
+     * ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, 
+     * WIDTH.
+     * @param x the X coordinate.
+     * @param y the Y coordinate.
+     * @param width the width.
+     * @param height the height.
+     * 
+     * @return true if further updates are needed, false if not.
+     */
+    public boolean imageUpdate(Image img, int infoflags, int x, int y,
+            int width, int height);
+
+}
+
diff --git a/awt/java/awt/image/ImageProducer.java b/awt/java/awt/image/ImageProducer.java
new file mode 100644
index 0000000..557ae08
--- /dev/null
+++ b/awt/java/awt/image/ImageProducer.java
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * The ImageProducer provides an interface for objects which produce
+ * the image data. ImageProducer is used for reconstructing the 
+ * image. Each image contains an ImageProducer. 
+ */
+public interface ImageProducer {
+
+    /**
+     * Checks if the specified ImageConsumer is registered with this 
+     * ImageProvider or not.
+     * 
+     * @param ic the ImageConsumer to be checked.
+     * 
+     * @return true, if the specified ImageConsumer is registered with this 
+     * ImageProvider, false otherwise.
+     */
+    public boolean isConsumer(ImageConsumer ic);
+
+    /**
+     * Starts a reconstruction of the image data which will 
+     * be delivered to this consumer. This method addes the
+     * specified ImageConsumer before reconstructing the image.  
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void startProduction(ImageConsumer ic);
+
+    /**
+     * Requests the ImageProducer to resend the image data 
+     * in ImageConsumer.TOPDOWNLEFTRIGHT order.
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void requestTopDownLeftRightResend(ImageConsumer ic);
+
+    /**
+     * Deregisters the specified ImageConsumer.
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void removeConsumer(ImageConsumer ic);
+
+    /**
+     * Adds the specified ImageConsumer object to this ImageProducer.
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void addConsumer(ImageConsumer ic);
+
+}
+
diff --git a/awt/java/awt/image/ImagingOpException.java b/awt/java/awt/image/ImagingOpException.java
new file mode 100644
index 0000000..ebcaba4
--- /dev/null
+++ b/awt/java/awt/image/ImagingOpException.java
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 5, 2005
+ */
+
+package java.awt.image;
+
+/**
+ * The ImagingOpException class provides error notification when 
+ * the BufferedImageOp or RasterOp filter methods can not perform
+ * the desired filter operation.
+ */
+public class ImagingOpException extends RuntimeException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8026288481846276658L;
+
+    /**
+     * Instantiates a new ImagingOpException with a detail message.
+     * 
+     * @param s the detail message.
+     */
+    public ImagingOpException(String s) {
+        super(s);
+    }
+}
diff --git a/awt/java/awt/image/IndexColorModel.java b/awt/java/awt/image/IndexColorModel.java
new file mode 100644
index 0000000..a7043f4
--- /dev/null
+++ b/awt/java/awt/image/IndexColorModel.java
@@ -0,0 +1,1020 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.math.BigInteger;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class IndexColorModel represents a color model in which the 
+ * color values of the pixels are read from a palette.
+ */
+public class IndexColorModel extends ColorModel {
+
+    /** The color map. */
+    private int colorMap[];        // Color Map  
+
+    /** The map size. */
+    private int mapSize;           // Color Map size
+
+    /** The transparent index. */
+    private int transparentIndex;  // Index of fully transparent pixel
+
+    /** The gray palette. */
+    private boolean grayPalette;   // Color Model has Color Map with Gray Pallete
+
+    /** The valid bits. */
+    private BigInteger validBits;  // Specify valid Color Map values
+
+    /** The Constant CACHESIZE. */
+    private static final int CACHESIZE = 20; // Cache size. Cache used for 
+                                             // improving performace of selection
+                                             // nearest color in Color Map
+
+    /** The cachetable. */
+    private final int cachetable[] = new int[CACHESIZE * 2]; // Cache table - used for 
+                               // storing RGB values and that appropriate indices 
+                               // in the Color Map 
+                    
+
+    /** The next insert idx. */
+    private int nextInsertIdx = 0;  // Next index for insertion into Cache table
+
+    /** The total inserted. */
+    private int totalInserted = 0;  // Number of inserted values into Cache table
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * @param validBits a list of which bits represent valid colormap 
+     * values, or null if all are valid
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, int cmap[], int start,
+            int transferType, BigInteger validBits) {
+
+        super(bits, IndexColorModel.createBits(true),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false,
+                Transparency.OPAQUE, validateTransferType(transferType));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        transparentIndex = -1;
+
+        if (validBits != null) {
+            for (int i = 0; i < mapSize; i++) {
+                if (!validBits.testBit(i)) {
+                    this.validBits = validBits;
+                }
+                break;
+            }
+        }
+
+        transparency = Transparency.OPAQUE;
+        int alphaMask = 0xff000000;
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++, start++) {
+            colorMap[i] = cmap[start];
+            alpha = cmap[start] & alphaMask;
+
+            if (alpha == alphaMask) {
+                continue;
+            }
+            if (alpha == 0) {
+                if (transparentIndex < 0) {
+                    transparentIndex = i;
+                }
+                if (transparency == Transparency.OPAQUE) {
+                    transparency = Transparency.BITMASK;
+                }
+            } else if (alpha != alphaMask &&
+                    transparency != Transparency.TRANSLUCENT) {
+                transparency = Transparency.TRANSLUCENT;
+            }
+
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param hasalpha whether this color model uses alpha
+     * @param trans the transparency supported, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, int cmap[], int start,
+            boolean hasalpha, int trans, int transferType) {
+
+        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                (hasalpha || (trans >= 0)), false, Transparency.OPAQUE,
+                validateTransferType(transferType));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        if (trans >= 0 && trans < mapSize) {
+            transparentIndex = trans;
+            transparency = Transparency.BITMASK;
+        } else {
+            transparentIndex = -1;
+            transparency = Transparency.OPAQUE;
+        }
+
+        int alphaMask = 0xff000000;
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++, start++) {
+            if (transparentIndex == i) {
+                colorMap[i] = cmap[start] & 0x00ffffff;
+                continue;
+            }
+            if (hasalpha) {
+                alpha = cmap[start] & alphaMask;
+                colorMap[i] = cmap[start];
+
+                if (alpha == alphaMask) {
+                    continue;
+                }
+                if (alpha == 0) {
+                    if (trans < 0) {
+                        trans = i;
+                    }
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                    }
+                } else if (alpha != 0
+                        && transparency != Transparency.TRANSLUCENT) {
+                    transparency = Transparency.TRANSLUCENT;
+                }
+            } else {
+                colorMap[i] = alphaMask | cmap[start];
+            }
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map 
+     * from arrays of red, green, blue, and alpha values.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param r the array giving the red components of the entries in the color map
+     * @param g the array giving the green components of the entries in the color map
+     * @param b the array giving the blue components of the entries in the color map
+     * @param a the array giving the alpha components of the entries in the color map
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     * @throws ArrayIndexOutOfBoundsException if the size of one of the 
+     * component arrays is less than the size of the color map
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[],
+            byte a[]) {
+
+        super(bits, IndexColorModel.createBits(true),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false,
+                Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, a, -1);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map 
+     * from arrays of red, green, and blue values.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param r the array giving the red components of the entries in the color map
+     * @param g the array giving the green components of the entries in the color map
+     * @param b the array giving the blue components of the entries in the color map
+     * @param trans the transparency supported, @see java.awt.Transparency
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     * @throws ArrayIndexOutOfBoundsException if the size of one of the 
+     * component arrays is less than the size of the color map
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[],
+            int trans) {
+
+        super(bits, IndexColorModel.createBits((trans >= 0)),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), (trans >= 0), false,
+                Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, null, trans);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map 
+     * from arrays of red, green, and blue values.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param r the array giving the red components of the entries in the color map
+     * @param g the array giving the green components of the entries in the color map
+     * @param b the array giving the blue components of the entries in the color map
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     * @throws ArrayIndexOutOfBoundsException if the size of one of the 
+     * component arrays is less than the size of the color map
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[]) {
+        super(bits, IndexColorModel.createBits(false),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), false, false,
+                Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, null, -1);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param hasalpha whether this color model uses alpha
+     * @param trans the transparency supported, @see java.awt.Transparency
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, byte cmap[], int start,
+            boolean hasalpha, int trans) {
+
+        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                (hasalpha || (trans >= 0)), false, Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        transparentIndex = -1;
+
+        transparency = Transparency.OPAQUE;
+        int alpha = 0xff000000;
+
+        for (int i = 0; i < mapSize; i++) {
+            colorMap[i] = (cmap[start++] & 0xff) << 16 |
+                   (cmap[start++] & 0xff) << 8 | (cmap[start++] & 0xff);
+            if (trans == i) {
+                if (transparency == Transparency.OPAQUE) {
+                    transparency = Transparency.BITMASK;
+                }
+                if(hasalpha) {
+                    start++;
+                }
+                continue;
+            }
+            if (hasalpha) {
+                alpha = cmap[start++] & 0xff;
+                if (alpha == 0) {
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                        if (trans < 0) {
+                            trans = i;
+                        }
+                    }
+                } else {
+                    if (alpha != 0xff &&
+                           transparency != Transparency.TRANSLUCENT) {
+                        transparency = Transparency.TRANSLUCENT;
+                    }
+                }
+                alpha <<= 24;
+            }
+            colorMap[i] |= alpha;
+        }
+
+        if (trans >= 0 && trans < mapSize) {
+            transparentIndex = trans;
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param hasalpha whether this color model uses alpha
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, byte cmap[], int start,
+            boolean hasalpha) {
+
+        this(bits, size, cmap, start, hasalpha, -1);
+    }
+
+    @Override
+    public Object getDataElements(int[] components, int offset, Object pixel) {
+        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8 |
+               components[offset + 2];
+        if (hasAlpha) {
+            rgb |= components[offset + 3] << 24;
+        } else {
+            rgb |= 0xff000000;
+        }
+        return getDataElements(rgb, pixel);
+    }
+
+    @Override
+    public synchronized Object getDataElements(int rgb, Object pixel) {
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+        int alpha = rgb >>> 24;
+        int pixIdx = 0;
+
+        for (int i = 0; i < totalInserted; i++) {
+            int idx = i * 2;
+            if (rgb == cachetable[idx]) {
+                return createDataObject(cachetable[idx + 1], pixel);
+            }
+        }
+
+        if (!hasAlpha && grayPalette) {
+            int grey = (red * 77 + green * 150 + blue * 29 + 128) >>> 8;
+            int minError = 255;
+            int error = 0;
+
+            for (int i = 0; i < mapSize; i++) {
+                error = Math.abs((colorMap[i] & 0xff) - grey);
+                if (error < minError) {
+                    pixIdx = i;
+                    if (error == 0) {
+                        break;
+                    }
+                    minError = error;
+                }
+            }
+        } else if (alpha == 0 && transparentIndex > -1) {
+            pixIdx = transparentIndex;
+        } else  {
+            int minAlphaError = 255;
+            int minError = 195075; // 255^2 + 255^2 + 255^2
+            int alphaError;
+            int error = 0;
+
+            for (int i = 0; i < mapSize; i++) {
+                int pix = colorMap[i];
+                if (rgb == pix) {
+                    pixIdx = i;
+                    break;
+                }
+                alphaError = Math.abs(alpha - (pix >>> 24));
+                if (alphaError <= minAlphaError) {
+                    minAlphaError = alphaError;
+
+                    int buf = ((pix >> 16) & 0xff) - red;
+                    error = buf * buf;
+
+                    if (error < minError) {
+                        buf = ((pix >> 8) & 0xff) - green;
+                        error += buf * buf;
+
+                        if (error < minError) {
+                            buf = (pix & 0xff) - blue;
+                            error += buf * buf;
+
+                            if (error < minError) {
+                                pixIdx = i;
+                                minError = error;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        cachetable[nextInsertIdx] = rgb;
+        cachetable[nextInsertIdx + 1] = pixIdx;
+
+        nextInsertIdx = (nextInsertIdx + 2) % (CACHESIZE * 2);
+        if (totalInserted < CACHESIZE) {
+            totalInserted++;
+        }
+
+        return createDataObject(pixIdx, pixel);
+    }
+
+    /**
+     * Converts an image from indexed to RGB format.
+     * 
+     * @param raster the raster containing the source image
+     * @param forceARGB whether to use the default RGB color model
+     * 
+     * @return the buffered image
+     * 
+     * @throws IllegalArgumentException if the raster is not compatible with 
+     * this color model
+     */
+    public BufferedImage convertToIntDiscrete(Raster raster,
+            boolean forceARGB) {
+
+        if (!isCompatibleRaster(raster)) {
+            // awt.265=The raster argument is not compatible with this IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.265")); //$NON-NLS-1$
+        }
+
+        ColorModel model;
+        if (forceARGB || transparency == Transparency.TRANSLUCENT) {
+            model = ColorModel.getRGBdefault();
+        } else if (transparency == Transparency.BITMASK) {
+            model = new DirectColorModel(25, 0x00ff0000, 0x0000ff00,
+                    0x000000ff, 0x01000000);
+        } else {
+            model = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
+        }
+
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        WritableRaster distRaster = model.createCompatibleWritableRaster(w, h);
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+
+        Object obj = null;
+        int pixels[] = null;
+
+        for (int i = 0; i < h; i++, minY++) {
+            obj = raster.getDataElements(minX, minY, w, 1, obj);
+            if (obj instanceof byte[]) {
+                byte ba[] = (byte[]) obj;
+                if (pixels == null) {
+                    pixels = new int[ba.length];
+                }
+                for (int j = 0; j < ba.length; j++) {
+                    pixels[j] = colorMap[ba[j] & 0xff];
+                }
+            } else if (obj instanceof short[]) {
+                short sa[] = (short[]) obj;
+                if (pixels == null) {
+                    pixels = new int[sa.length];
+                }
+                for (int j = 0; j < sa.length; j++) {
+                    pixels[j] = colorMap[sa[j] & 0xffff];
+                }
+            }
+            if (obj instanceof int[]) {
+                int ia[] = (int[]) obj;
+                if (pixels == null) {
+                    pixels = new int[ia.length];
+                }
+                for (int j = 0; j < ia.length; j++) {
+                    pixels[j] = colorMap[ia[j]];
+                }
+            }
+
+            distRaster.setDataElements(0, i, w, 1, pixels);
+        }
+
+        return new BufferedImage(model, distRaster, false, null);
+    }
+
+    /**
+     * Gets the valid pixels.
+     * 
+     * @return the valid pixels
+     */
+    public BigInteger getValidPixels() {
+        return validBits;
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. 
+        // It could be reveled such way:
+        // BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_INDEXED);
+        // ColorModel cm = bi.getColorModel();
+        // System.out.println(cm.toString());
+        String str = "IndexColorModel: #pixel_bits = " + pixel_bits + //$NON-NLS-1$
+               " numComponents = " + numComponents + " color space = " + cs + //$NON-NLS-1$ //$NON-NLS-2$
+               " transparency = "; //$NON-NLS-1$
+
+        if (transparency == Transparency.OPAQUE) {
+            str = str + "Transparency.OPAQUE"; //$NON-NLS-1$
+        } else if (transparency == Transparency.BITMASK) {
+            str = str + "Transparency.BITMASK"; //$NON-NLS-1$
+        } else {
+            str = str + "Transparency.TRANSLUCENT"; //$NON-NLS-1$
+        }
+
+        str = str + " transIndex = " + transparentIndex + " has alpha = " + //$NON-NLS-1$ //$NON-NLS-2$
+               hasAlpha + " isAlphaPre = " + isAlphaPremultiplied; //$NON-NLS-1$
+
+        return str;
+    }
+
+    @Override
+    public int[] getComponents(Object pixel, int components[], int offset) {
+        int pixIdx = -1;
+        if (pixel instanceof byte[]) {
+            byte ba[] = (byte[]) pixel;
+            pixIdx = ba[0] & 0xff;
+        } else if (pixel instanceof short[]) {
+            short sa[] = (short[]) pixel;
+            pixIdx = sa[0] & 0xffff;
+        } else if (pixel instanceof int[]) {
+            int ia[] = (int[]) pixel;
+            pixIdx = ia[0];
+        } else {
+            // awt.219=This transferType is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+        }
+
+        return getComponents(pixIdx, components, offset);
+    }
+
+    @Override
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        WritableRaster raster;
+        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h, 1,
+                    pixel_bits, null);
+        } else if (pixel_bits <= 8) {
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+                    1, null);
+        } else if (pixel_bits <= 16) {
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT, w,
+                    h, 1, null);
+        } else {
+            // awt.266=The number of bits in a pixel is greater than 16
+            throw new UnsupportedOperationException(Messages.getString("awt.266")); //$NON-NLS-1$
+        }
+
+        return raster;
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (sm == null) {
+            return false;
+        }
+
+        if (!(sm instanceof MultiPixelPackedSampleModel)
+                && !(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+
+        if (sm.getTransferType() != transferType) {
+            return false;
+        }
+        if (sm.getNumBands() != 1) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
+            return new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h,
+                    pixel_bits);
+        }
+        int bandOffsets[] = new int[1];
+        bandOffsets[0] = 0;
+        return new ComponentSampleModel(transferType, w, h, 1, w,
+                bandOffsets);
+
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        int sampleSize = raster.getSampleModel().getSampleSize(0);
+        return (raster.getTransferType() == transferType &&
+               raster.getNumBands() == 1 && (1 << sampleSize) >= mapSize);
+    }
+
+    @Override
+    public int getDataElement(int components[], int offset) {
+        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8
+                | components[offset + 2];
+        
+        if (hasAlpha) {
+            rgb |= components[offset + 3] << 24;
+        } else {
+            rgb |= 0xff000000;
+        }
+ 
+        int pixel;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) getDataElements(rgb, null);
+            pixel = ba[0] & 0xff;
+            break;
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) getDataElements(rgb, null);
+            pixel = sa[0] & 0xffff;
+            break;
+        default:
+            // awt.267=The transferType is invalid
+            throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Gets the color map.
+     * 
+     * @param rgb the destination array where the color map is written
+     */
+    public final void getRGBs(int rgb[]) {
+        System.arraycopy(colorMap, 0, rgb, 0, mapSize);
+    }
+
+    /**
+     * Gets the red component of the color map.
+     * 
+     * @param r the destination array
+     */
+    public final void getReds(byte r[]) {
+        for (int i = 0; i < mapSize; i++) {
+            r[i] = (byte) (colorMap[i] >> 16);
+        }
+    }
+
+    /**
+     * Gets the green component of the color map.
+     * 
+     * @param g the destination array
+     */
+    public final void getGreens(byte g[]) {
+        for (int i = 0; i < mapSize; i++) {
+            g[i] = (byte) (colorMap[i] >> 8);
+        }
+    }
+
+    /**
+     * Gets the blue component of the color map.
+     * 
+     * @param b the destination array
+     */
+    public final void getBlues(byte b[]) {
+        for (int i = 0; i < mapSize; i++) {
+            b[i] = (byte) colorMap[i];
+        }
+    }
+
+    /**
+     * Gets the alpha component of the color map.
+     * 
+     * @param a the destination array
+     */
+    public final void getAlphas(byte a[]) {
+        for (int i = 0; i < mapSize; i++) {
+            a[i] = (byte) (colorMap[i] >> 24);
+        }
+    }
+
+    @Override
+    public int[] getComponents(int pixel, int components[], int offset) {
+        if (components == null) {
+            components = new int[offset + numComponents];
+        }
+
+        components[offset + 0] = getRed(pixel);
+        components[offset + 1] = getGreen(pixel);
+        components[offset + 2] = getBlue(pixel);
+        if (hasAlpha && (components.length - offset) > 3) {
+            components[offset + 3] = getAlpha(pixel);
+        }
+
+        return components;
+    }
+
+    /**
+     * Checks if the specified pixel is valid for this color model.
+     * 
+     * @param pixel the pixel
+     * 
+     * @return true, if the pixel is valid
+     */
+    public boolean isValid(int pixel) {
+        if (validBits == null) {
+            return (pixel >= 0 && pixel < mapSize);
+        }
+        return (pixel < mapSize && validBits.testBit(pixel));
+    }
+
+    @Override
+    public final int getRed(int pixel) {
+        return (colorMap[pixel] >> 16) & 0xff;
+    }
+
+    @Override
+    public final int getRGB(int pixel) {
+        return colorMap[pixel];
+    }
+
+    @Override
+    public final int getGreen(int pixel) {
+        return (colorMap[pixel] >> 8) & 0xff;
+    }
+
+    @Override
+    public final int getBlue(int pixel) {
+        return colorMap[pixel] & 0xff;
+    }
+
+    @Override
+    public final int getAlpha(int pixel) {
+        return (colorMap[pixel] >> 24) & 0xff;
+    }
+
+    @Override
+    public int[] getComponentSize() {
+        return bits.clone();
+    }
+
+    /**
+     * Checks if this color model validates pixels.
+     * 
+     * @return true, if all pixels are valid, otherwise false
+     */
+    public boolean isValid() {
+        return (validBits == null);
+    }
+
+    @Override
+    public void finalize() {
+        // TODO: implement
+        return;
+    }
+
+    /**
+     * Gets the index that represents the transparent pixel.
+     * 
+     * @return the index that represents the transparent pixel
+     */
+    public final int getTransparentPixel() {
+        return transparentIndex;
+    }
+
+    @Override
+    public int getTransparency() {
+        return transparency;
+    }
+
+    /**
+     * Gets the size of the color map.
+     * 
+     * @return the map size
+     */
+    public final int getMapSize() {
+        return mapSize;
+    }
+
+    /**
+     * Creates the color map.
+     * 
+     * @param size the size
+     * @param r the r
+     * @param g the g
+     * @param b the b
+     * @param a the a
+     * @param trans the trans
+     */
+    private void createColorMap(int size, byte r[], byte g[], byte b[],
+            byte a[], int trans) {
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        if (trans >= 0 && trans < mapSize) {
+            transparency = Transparency.BITMASK;
+            transparentIndex = trans;
+        } else {
+            transparency = Transparency.OPAQUE;
+            transparentIndex = -1;
+        }
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++) {
+            colorMap[i] = ((r[i] & 0xff) << 16) | ((g[i] & 0xff) << 8) |
+                   (b[i] & 0xff);
+
+            if (trans == i) {
+                continue;
+            }
+
+            if (a == null) {
+                colorMap[i] |= 0xff000000;
+            } else {
+                alpha = a[i] & 0xff;
+                if (alpha == 0xff) {
+                    colorMap[i] |= 0xff000000;
+                } else if (alpha == 0) {
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                    }
+                    if (transparentIndex < 0) {
+                        transparentIndex = i;
+                    }
+                } else {
+                    colorMap[i] |= (a[i] & 0xff) << 24;
+                    if (transparency != Transparency.TRANSLUCENT) {
+                        transparency = Transparency.TRANSLUCENT;
+                    }
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * This method checking, if Color Map has Gray Palette.
+     */
+    private void checkPalette() {
+        grayPalette = false;
+        if (transparency > Transparency.OPAQUE) {
+            return;
+        }
+        int rgb = 0;
+
+        for (int i = 0; i < mapSize; i++) {
+            rgb = colorMap[i];
+            if (((rgb >> 16) & 0xff) != ((rgb >> 8) & 0xff) ||
+                   ((rgb >> 8) & 0xff) != (rgb & 0xff)) {
+                return;
+            }
+        }
+        grayPalette = true;
+    }
+
+    /**
+     * Construction an array pixel representation.
+     * 
+     * @param colorMapIdx - index into Color Map
+     * @param pixel - pixel
+     * 
+     * @return - an array pixel representation
+     */
+    private Object createDataObject(int colorMapIdx, Object pixel) {
+        if (pixel == null) {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte[] ba = new byte[1];
+                ba[0] = (byte) colorMapIdx;
+                pixel = ba;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                short[] sa = new short[1];
+                sa[0] = (short) colorMapIdx;
+                pixel = sa;
+                break;
+            default:
+                // awt.267=The transferType is invalid
+                throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
+            }
+        } else if (pixel instanceof byte[]
+                && transferType == DataBuffer.TYPE_BYTE) {
+            byte ba[] = (byte[]) pixel;
+            ba[0] = (byte) colorMapIdx;
+            pixel = ba;
+        } else if (pixel instanceof short[]&&
+                transferType == DataBuffer.TYPE_USHORT) {
+            short[] sa = (short[]) pixel;
+            sa[0] = (short) colorMapIdx;
+            pixel = sa;
+        } else if (pixel instanceof int[]) {
+            int ia[] = (int[]) pixel;
+            ia[0] = colorMapIdx;
+            pixel = ia;
+        } else {
+            // awt.268=The pixel is not a primitive array of type transferType
+            throw new ClassCastException(Messages.getString("awt.268")); //$NON-NLS-1$
+        }
+        return pixel;
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param hasAlpha the has alpha
+     * 
+     * @return the int[]
+     */
+    private static int[] createBits(boolean hasAlpha) {
+
+        int numChannels;
+        if (hasAlpha) {
+            numChannels = 4;
+        } else {
+            numChannels = 3;
+        }
+
+        int bits[] = new int[numChannels];
+        for (int i = 0; i < numChannels; i++) {
+            bits[i] = 8;
+        }
+
+        return bits;
+
+    }
+
+    /**
+     * Validate transfer type.
+     * 
+     * @param transferType the transfer type
+     * 
+     * @return the int
+     */
+    private static int validateTransferType(int transferType) {
+        if (transferType != DataBuffer.TYPE_BYTE &&
+               transferType != DataBuffer.TYPE_USHORT) {
+            // awt.269=The transferType is not one of DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
+            throw new IllegalArgumentException(Messages.getString("awt.269")); //$NON-NLS-1$
+        }
+        return transferType;
+    }
+
+    /**
+     * Checks if is gray pallete.
+     * 
+     * @return true, if is gray pallete
+     */
+    boolean isGrayPallete(){
+        return grayPalette;
+    }
+
+}
+
+
diff --git a/awt/java/awt/image/Kernel.java b/awt/java/awt/image/Kernel.java
new file mode 100644
index 0000000..c6f00e2
--- /dev/null
+++ b/awt/java/awt/image/Kernel.java
@@ -0,0 +1,138 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 28, 2005
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Kernel class provides a matrix. This matrix is stored as a float array
+ * which describes how a specified pixel affects the value calculated for 
+ * the pixel's position in the output image of a filtering operation. 
+ * The X, Y origins indicate the kernel matrix element which corresponds to 
+ * the pixel position for which an output value is being calculated.
+ */
+public class Kernel implements Cloneable {
+    
+    /** The x origin. */
+    private final int xOrigin;
+    
+    /** The y origin. */
+    private final int yOrigin;
+    
+    /** The width. */
+    private int width;
+    
+    /** The height. */
+    private int height;
+    
+    /** The data. */
+    float data[];
+
+    /**
+     * Instantiates a new Kernel with the specified float array.
+     * The width*height elements of the data array are copied. 
+     * 
+     * @param width the width of the Kernel.
+     * @param height the height of the Kernel.
+     * @param data the data of Kernel.
+     */
+    public Kernel(int width, int height, float[] data) {
+        int dataLength = width*height;
+        if (data.length < dataLength) {
+            // awt.22B=Length of data should not be less than width*height
+            throw new IllegalArgumentException(Messages.getString("awt.22B")); //$NON-NLS-1$
+        }
+
+        this.width = width;
+        this.height = height;
+
+        this.data = new float[dataLength];
+        System.arraycopy(data, 0, this.data, 0, dataLength);
+
+        xOrigin = (width-1)/2;
+        yOrigin = (height-1)/2;
+    }
+
+    /**
+     * Gets the width of this Kernel.
+     * 
+     * @return the width of this Kernel.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the height of this Kernel.
+     * 
+     * @return the height of this Kernel.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the float data array of this Kernel.
+     * 
+     * @param data the float array where the resulted data will be stored.
+     * 
+     * @return the float data array of this Kernel.
+     */
+    public final float[] getKernelData(float[] data) {
+        if (data == null) {
+            data = new float[this.data.length];
+        }
+        System.arraycopy(this.data, 0, data, 0, this.data.length);
+
+        return data;
+    }
+
+    /**
+     * Gets the X origin of this Kernel.
+     * 
+     * @return the X origin of this Kernel.
+     */
+    public final int getXOrigin() {
+        return xOrigin;
+    }
+
+    /**
+     * Gets the Y origin of this Kernel.
+     * 
+     * @return the Y origin of this Kernel.
+     */
+    public final int getYOrigin() {
+        return yOrigin;
+    }
+
+    /**
+     * Returns a copy of this Kernel object.
+     * 
+     * @return the copy of this Kernel object.
+     */
+    @Override
+    public Object clone() {
+        return new Kernel(width, height, data);
+    }
+}
diff --git a/awt/java/awt/image/LookupOp.java b/awt/java/awt/image/LookupOp.java
new file mode 100644
index 0000000..f9bd2c7
--- /dev/null
+++ b/awt/java/awt/image/LookupOp.java
@@ -0,0 +1,647 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The LookupOp class perfoms a lookup operation which transforms a 
+ * source image by filtering each band using a table of data. 
+ * The table may contain a single array or it may contain a 
+ * different data array for each band of the image.
+ */
+public class LookupOp implements BufferedImageOp, RasterOp {
+    
+    /** The lut. */
+    private final LookupTable lut;
+    
+    /** The hints. */
+    private RenderingHints hints;
+    
+    // TODO remove when this field is used
+    /** The can use ipp. */
+    @SuppressWarnings("unused")
+    private final boolean canUseIpp;
+
+    // We don't create levels/values when it is possible to reuse old
+    /** The cached levels. */
+    private int cachedLevels[];
+    
+    /** The cached values. */
+    private int cachedValues[];
+    // Number of channels for which cache is valid.
+    // If negative number of channels is same as positive but skipAlpha was specified
+    /** The valid for channels. */
+    private int validForChannels;
+
+    /** The level initializer. */
+    static int levelInitializer[] = new int[0x10000];
+
+    static {
+        // TODO
+        // System.loadLibrary("imageops");
+
+        for (int i=1; i<=0x10000; i++) {
+            levelInitializer[i-1] = i;
+        }
+    }
+
+    /**
+     * Instantiates a new LookupOp object from the specified 
+     * LookupTable object and a RenderingHints object.
+     * 
+     * @param lookup the specified LookupTable object. 
+     * @param hints the RenderingHints object or null.
+     */
+    public LookupOp(LookupTable lookup, RenderingHints hints) {
+        if (lookup == null){
+            throw new NullPointerException(Messages.getString("awt.01", "lookup")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        lut = lookup;
+        this.hints = hints;
+        canUseIpp = lut instanceof ByteLookupTable || lut instanceof ShortLookupTable;
+    }
+
+    /**
+     * Gets the LookupTable of the specified Object.
+     * 
+     * @return the LookupTable of the specified Object.
+     */
+    public final LookupTable getTable() {
+        return lut;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+
+            // Sync transfer type with LUT for component color model
+            if (dstCM instanceof ComponentColorModel) {
+                int transferType = dstCM.getTransferType();
+                if (lut instanceof ByteLookupTable) {
+                    transferType = DataBuffer.TYPE_BYTE;
+                } else if (lut instanceof ShortLookupTable) {
+                    transferType = DataBuffer.TYPE_SHORT;
+                }
+
+                dstCM = new ComponentColorModel(
+                        dstCM.cs,
+                        dstCM.hasAlpha(),
+                        dstCM.isAlphaPremultiplied,
+                        dstCM.transparency,
+                        transferType
+                );
+            }
+        }
+
+        WritableRaster r =
+                dstCM.isCompatibleSampleModel(src.getSampleModel()) ?
+                src.getRaster().createCompatibleWritableRaster(src.getWidth(), src.getHeight()) :
+                dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(
+                dstCM,
+                r,
+                dstCM.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else {
+            if (src.getNumBands() != dst.getNumBands()) {
+                throw new IllegalArgumentException(Messages.getString("awt.237")); //$NON-NLS-1$            }
+            }
+            if (src.getWidth() != dst.getWidth()){
+                throw new IllegalArgumentException(Messages.getString("awt.28F")); //$NON-NLS-1$            }
+            }
+            if (src.getHeight() != dst.getHeight()){
+                throw new IllegalArgumentException(Messages.getString("awt.290")); //$NON-NLS-1$            }
+            }
+        }
+
+        if (lut.getNumComponents() != 1 && lut.getNumComponents() != src.getNumBands()) {
+            // awt.238=The number of arrays in the LookupTable does not meet the restrictions
+            throw new IllegalArgumentException(Messages.getString("awt.238")); //$NON-NLS-1$
+        }
+
+        // TODO
+        // if (!canUseIpp || ippFilter(src, dst, BufferedImage.TYPE_CUSTOM, false) != 0)
+            if (slowFilter(src, dst, false) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        return dst;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        ColorModel srcCM = src.getColorModel();
+
+        if (srcCM instanceof IndexColorModel) {
+            // awt.220=Source should not have IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
+        }
+
+        // Check if the number of scaling factors matches the number of bands
+        int nComponents = srcCM.getNumComponents();
+        int nLUTComponents = lut.getNumComponents();
+        boolean skipAlpha;
+        if (srcCM.hasAlpha()) {
+            if (nLUTComponents == 1 || nLUTComponents == nComponents-1) {
+                skipAlpha = true;
+            } else if (nLUTComponents == nComponents) {
+                skipAlpha = false;
+            } else {
+                // awt.229=Number of components in the LUT does not match the number of bands
+                throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
+            }
+        } else if (nLUTComponents == 1 || nLUTComponents == nComponents) {
+            skipAlpha = false;
+        } else {
+            // awt.229=Number of components in the LUT does not match the number of bands
+            throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
+        }
+
+        BufferedImage finalDst = null;
+        if (dst == null) {
+            finalDst = dst;
+            dst = createCompatibleDestImage(src, null);
+        } else {
+            if (src.getWidth() != dst.getWidth()){
+                throw new IllegalArgumentException(Messages.getString("awt.291")); //$NON-NLS-1$
+            }
+
+            if (src.getHeight() != dst.getHeight()){
+                throw new IllegalArgumentException(Messages.getString("awt.292")); //$NON-NLS-1$
+            }
+
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and
+                // BufferedImage.TYPE_INT_ARGB as same
+                if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src
+                        .getType() == BufferedImage.TYPE_INT_ARGB) && (dst
+                        .getType() == BufferedImage.TYPE_INT_RGB || dst
+                        .getType() == BufferedImage.TYPE_INT_ARGB))) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, null);
+                }
+            }
+        }
+
+        // TODO
+        //if (!canUseIpp || ippFilter(src.getRaster(), dst.getRaster(), src.getType(), skipAlpha) != 0)
+            if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
+        int minSrcX = src.getMinX();
+        int minDstX = dst.getMinX();
+        int minSrcY = src.getMinY();
+        int minDstY = dst.getMinY();
+
+        int skippingChannels = skipAlpha ? 1 : 0;
+        int numBands2Process = src.getNumBands() - skippingChannels;
+
+        int numBands = src.getNumBands();
+        int srcHeight = src.getHeight();
+        int srcWidth = src.getWidth();
+
+        int[] pixels = null;
+        int offset = lut.getOffset();
+
+        if (lut instanceof ByteLookupTable){
+            byte[][] byteData = ((ByteLookupTable)lut).getTable();
+            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
+
+            if (lut.getNumComponents() != 1){
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = byteData[b][pixels[i+b]-offset] & 0xFF;
+                    }
+                }
+            } else {
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = byteData[0][pixels[i+b]-offset] & 0xFF;
+                    }
+                }
+            }
+
+            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
+        } else if (lut instanceof ShortLookupTable){
+            short[][] shortData  = ((ShortLookupTable)lut).getTable();
+            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
+
+            if (lut.getNumComponents() != 1){
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = shortData[b][pixels[i+b]-offset] & 0xFFFF;
+                    }
+                }
+            } else {
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = shortData[0][pixels[i+b]-offset] & 0xFFFF;
+                    }
+                }
+            }
+
+            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
+        } else {
+            int pixel[] = new int[src.getNumBands()];
+            int maxY = minSrcY + srcHeight;
+            int maxX = minSrcX + srcWidth;
+            for (int srcY=minSrcY, dstY = minDstY; srcY < maxY; srcY++, dstY++){
+                for (int srcX=minSrcX, dstX = minDstX; srcX < maxX; srcX++, dstX++){
+                    src.getPixel(srcX, srcY, pixel);
+                    lut.lookupPixel(pixel, pixel);
+                    dst.setPixel(dstX, dstY, pixel);
+                }
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Creates the byte levels.
+     * 
+     * @param channels the channels
+     * @param skipAlpha the skip alpha
+     * @param levels the levels
+     * @param values the values
+     * @param channelsOrder the channels order
+     */
+    private final void createByteLevels(
+            int channels, boolean skipAlpha,
+            int levels[], int values[], int channelsOrder[]
+    ) {
+        byte data[][] = ((ByteLookupTable)lut).getTable();
+        int nLevels = data[0].length;
+        int offset = lut.getOffset();
+
+        // Use one data array for all channels or use several data arrays
+        int dataIncrement = data.length > 1 ? 1 : 0;
+
+        for (int ch = 0, dataIdx = 0; ch<channels; dataIdx+=dataIncrement, ch++) {
+            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
+            int channelBase = nLevels * channelOffset;
+
+            // Skip last channel if needed, zero values are OK -
+            // no changes to the channel information will be done in IPP
+            if ((channelOffset == channels-1 && skipAlpha) || (dataIdx >= data.length)) {
+                continue;
+            }
+
+            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
+            for (int from=0, to=channelBase; from<nLevels; from++, to++) {
+                values[to] = data[dataIdx][from] & 0xFF;
+            }
+        }
+    }
+
+    /**
+     * Creates the short levels.
+     * 
+     * @param channels the channels
+     * @param skipAlpha the skip alpha
+     * @param levels the levels
+     * @param values the values
+     * @param channelsOrder the channels order
+     */
+    private final void createShortLevels(
+            int channels, boolean skipAlpha,
+            int levels[], int values[], int channelsOrder[]
+    ) {
+        short data[][] = ((ShortLookupTable)lut).getTable();
+        int nLevels = data[0].length;
+        int offset = lut.getOffset();
+
+        // Use one data array for all channels or use several data arrays
+        int dataIncrement = data.length > 1 ? 1 : 0;
+
+        for (int ch = 0, dataIdx = 0; ch<channels; dataIdx+=dataIncrement, ch++) {
+            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
+
+            // Skip last channel if needed, zero values are OK -
+            // no changes to the channel information will be done in IPP
+            if ((channelOffset == channels-1 && skipAlpha) || (dataIdx >= data.length)) {
+                continue;
+            }
+
+            int channelBase = nLevels * channelOffset;
+            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
+            for (int from=0, to=channelBase; from<nLevels; from++, to++) {
+                values[to] = data[dataIdx][from] & 0xFFFF;
+            }
+        }
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private final int ippFilter(
+            Raster src, WritableRaster dst,
+            int imageType, boolean skipAlpha
+    ) {
+        int res;
+
+        int srcStride, dstStride;
+        int channels;
+        int offsets[] = null;
+        int channelsOrder[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_INT_RGB: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                channelsOrder = new int[] {2, 1, 0, 3};
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                channelsOrder = new int[] {2, 1, 0};
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst, skipAlpha);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Have IPP functions for 1, 3 and 4 channels
+                    channels = srcSM.getNumBands();
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();
+
+                    channelsOrder = ((ComponentSampleModel) srcSM).getBandOffsets();
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 =
+                            (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 =
+                            (SinglePixelPackedSampleModel) dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                     // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (
+                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
+                            !(channels == 3 || channels == 4)
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst, skipAlpha);
+                        }
+                    }
+
+                    channelsOrder = new int[channels];
+                    int bitOffsets[] = sppsm1.getBitOffsets();
+                    for (int i=0; i<channels; i++) {
+                        channelsOrder[i] = bitOffsets[i] / 8;
+                    }
+
+                    if (channels == 3) { // Don't skip channel now, could be optimized
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst, skipAlpha);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        int levels[] = null, values[] = null;
+        int channelMultiplier = skipAlpha ? -1 : 1;
+        if (channelMultiplier*channels == validForChannels) { // use existing levels/values
+            levels = cachedLevels;
+            values = cachedValues;
+        } else { // create new levels/values
+            if (lut instanceof ByteLookupTable) {
+                byte data[][] = ((ByteLookupTable)lut).getTable();
+                levels = new int[channels*data[0].length];
+                values = new int[channels*data[0].length];
+                createByteLevels(channels, skipAlpha, levels, values, channelsOrder);
+            } else if (lut instanceof ShortLookupTable) {
+                short data[][] = ((ShortLookupTable)lut).getTable();
+                levels = new int[channels*data[0].length];
+                values = new int[channels*data[0].length];
+                createShortLevels(channels, skipAlpha, levels, values, channelsOrder);
+            }
+
+            // cache levels/values
+            validForChannels = channelMultiplier*channels;
+            cachedLevels = levels;
+            cachedValues = values;
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        res = ippLUT(
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            levels, values,
+            channels, offsets,
+            false
+        );
+
+        return res;
+    }
+
+    /**
+     * Ipp lut.
+     * 
+     * @param src the src
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dst the dst
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param levels the levels
+     * @param values the values
+     * @param channels the channels
+     * @param offsets the offsets
+     * @param linear the linear
+     * 
+     * @return the int
+     */
+    final static native int ippLUT(
+            Object src, int srcWidth, int srcHeight, int srcStride,
+            Object dst, int dstWidth, int dstHeight, int dstStride,
+            int levels[], int values[],
+            int channels, int offsets[],
+            boolean linear
+    );
+}
diff --git a/awt/java/awt/image/LookupTable.java b/awt/java/awt/image/LookupTable.java
new file mode 100644
index 0000000..d15f23c
--- /dev/null
+++ b/awt/java/awt/image/LookupTable.java
@@ -0,0 +1,93 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This abstract LookupTable class represents lookup table which
+ * is defined with the number of components and offset value.
+ * ByteLookupTable and ShortLookupTable classes are subclasses of
+ * LookupTable which contains byte and short data tables as
+ * an input arrays for bands or components of image.
+ */
+public abstract class LookupTable {
+    
+    /** The offset. */
+    private int offset;
+    
+    /** The num components. */
+    private int numComponents;
+
+    /**
+     * Instantiates a new LookupTable with the specified offset value
+     * and number of components.
+     * 
+     * @param offset the offset value.
+     * @param numComponents the number of components.
+     */
+    protected LookupTable(int offset, int numComponents) {
+        if (offset < 0) {
+            // awt.232=Offset should be not less than zero
+            throw new IllegalArgumentException(Messages.getString("awt.232")); //$NON-NLS-1$
+        }
+        if (numComponents < 1) {
+            // awt.233=Number of components should be positive
+            throw new IllegalArgumentException(Messages.getString("awt.233")); //$NON-NLS-1$
+        }
+
+        this.offset = offset;
+        this.numComponents = numComponents;
+    }
+
+    /**
+     * Gets the offset value of this Lookup table.
+     * 
+     * @return the offset value of this Lookup table.
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Gets the number of components of this Lookup table.
+     * 
+     * @return the number components of this Lookup table.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+    /**
+     * Returns a int array which contains samples of the specified
+     * pixel which is translated with the lookup table of this 
+     * LookupTable. The resulted array is stored to the dst array.
+     * 
+     * @param src the source array.
+     * @param dst the destination array where the result can be stored.
+     * 
+     * @return the int array of translated samples of a pixel.
+     */
+    public abstract int[] lookupPixel(int[] src, int[] dst);
+}
diff --git a/awt/java/awt/image/MemoryImageSource.java b/awt/java/awt/image/MemoryImageSource.java
new file mode 100644
index 0000000..983f19e
--- /dev/null
+++ b/awt/java/awt/image/MemoryImageSource.java
@@ -0,0 +1,512 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The MemoryImageSource class is used to produces pixels of an image from
+ * an array. This class can manage a memory image which 
+ * contains an animation or custom rendering.
+ */
+public class MemoryImageSource implements ImageProducer {
+
+    /** The width. */
+    int width;
+    
+    /** The height. */
+    int height;
+    
+    /** The cm. */
+    ColorModel cm;
+    
+    /** The b data. */
+    byte bData[];
+    
+    /** The i data. */
+    int iData[];
+    
+    /** The offset. */
+    int offset;
+    
+    /** The scanline. */
+    int scanline;
+    
+    /** The properties. */
+    Hashtable<?, ?> properties;
+    
+    /** The consumers. */
+    Vector<ImageConsumer> consumers;
+    
+    /** The animated. */
+    boolean animated;
+    
+    /** The fullbuffers. */
+    boolean fullbuffers;
+    
+    /** The data type. */
+    int dataType;
+
+    /** The Constant DATA_TYPE_BYTE. */
+    static final int DATA_TYPE_BYTE = 0;
+    
+    /** The Constant DATA_TYPE_INT. */
+    static final int DATA_TYPE_INT = 1;
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     * @param props the set of properties to be used for image
+     * processing.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, int pix[],
+            int off, int scan, Hashtable<?, ?> props) {
+        init(w, h, cm, pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     * @param props the set of properties to be used for image
+     * processing.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[],
+            int off, int scan, Hashtable<?, ?> props) {
+        init(w, h, cm, pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters and default RGB ColorModel.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     * @param props the set of properties to be used for image
+     * processing.
+     */
+    public MemoryImageSource(int w, int h, int pix[], int off, int scan,
+            Hashtable<?, ?> props) {
+        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, int pix[],
+            int off, int scan) {
+        init(w, h, cm, pix, off, scan, null);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[],
+            int off, int scan) {
+        init(w, h, cm, pix, off, scan, null);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters and default RGB ColorModel.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param pix the pixels array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     */
+    public MemoryImageSource(int w, int h, int pix[], int off, int scan) {
+        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, null);
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        return consumers.contains(ic);
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        if(!isConsumer(ic) && ic != null) {
+            consumers.addElement(ic);
+        }
+        try{
+            setHeader(ic);
+            setPixels(ic, 0, 0, width, height);
+            if(animated){
+                ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+            }else{
+                ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
+                if(isConsumer(ic)) {
+                    removeConsumer(ic);
+                }
+            }
+        }catch(Exception e){
+            if(isConsumer(ic)) {
+                ic.imageComplete(ImageConsumer.IMAGEERROR);
+            }
+            if(isConsumer(ic)) {
+                removeConsumer(ic);
+            }
+        }
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        consumers.removeElement(ic);
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if(ic == null || consumers.contains(ic)) {
+            return;
+        }
+        consumers.addElement(ic);
+    }
+
+    /**
+     * Replaces the pixel data with a new pixel array for holding 
+     * the pixels for this image. If an animation 
+     * flag is set to true value by the setAnimated() method, 
+     * the new pixels will be immediately delivered to the ImageConsumers. 
+     * 
+     * @param newpix the new pixel array.
+     * @param newmodel the new ColorModel.
+     * @param offset the offset in the array.
+     * @param scansize the distance from one row of pixels to the next row
+     * in the pixel array
+     */
+    public synchronized void newPixels(int newpix[], ColorModel newmodel,
+            int offset, int scansize) {
+        this.dataType = DATA_TYPE_INT;
+        this.iData = newpix;
+        this.cm = newmodel;
+        this.offset = offset;
+        this.scanline = scansize;
+        newPixels();
+    }
+
+    /**
+     * Replaces the pixel data with a new pixel array for holding 
+     * the pixels for this image. If an animation 
+     * flag is set to true value by the setAnimated() method, 
+     * the new pixels will be immediately delivered to the ImageConsumers. 
+     * 
+     * @param newpix the new pixel array.
+     * @param newmodel the new ColorModel.
+     * @param offset the offset in the array.
+     * @param scansize the distance from one row of pixels to the next row
+     * in the pixel array
+     */
+    public synchronized void newPixels(byte newpix[], ColorModel newmodel,
+            int offset, int scansize) {
+        this.dataType = DATA_TYPE_BYTE;
+        this.bData = newpix;
+        this.cm = newmodel;
+        this.offset = offset;
+        this.scanline = scansize;
+        newPixels();
+    }
+
+    /**
+     * Sets the full buffer updates flag to true. If this is an 
+     * animated image, the image consumers hints are updated
+     * accordingly.
+     * 
+     * @param fullbuffers the true if the pixel buffer should be sent always.
+     */
+    public synchronized void setFullBufferUpdates(boolean fullbuffers) {
+        if(this.fullbuffers == fullbuffers) {
+            return;
+        }
+        this.fullbuffers = fullbuffers;
+        if(animated){
+            Object consAr[] = consumers.toArray();
+            for (Object element : consAr) {
+                ImageConsumer con = (ImageConsumer)element;
+                try{
+                    if(fullbuffers){
+                        con.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
+                                ImageConsumer.COMPLETESCANLINES);
+                    }else{
+                        con.setHints(ImageConsumer.RANDOMPIXELORDER);
+                    }
+                }catch(Exception e){
+                    if(isConsumer(con)) {
+                        con.imageComplete(ImageConsumer.IMAGEERROR);
+                    }
+                    if(isConsumer(con)) {
+                        removeConsumer(con);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the flag that tells whether this memory image has more 
+     * than one frame (for animation): true for multiple frames,
+     * false if this class represents a single frame image.
+     *  
+     * @param animated whether this image represents an animation.
+     */
+    public synchronized void setAnimated(boolean animated) {
+        if(this.animated == animated) {
+            return;
+        }
+        Object consAr[] = consumers.toArray();
+        for (Object element : consAr) {
+            ImageConsumer con = (ImageConsumer)element;
+            try{
+                con.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            }catch(Exception e){
+                if(isConsumer(con)) {
+                    con.imageComplete(ImageConsumer.IMAGEERROR);
+                }
+            }
+            if(isConsumer(con)){
+                removeConsumer(con);
+            }
+        }
+        this.animated = animated;
+    }
+
+    /**
+     * Sends the specified rectangular area of the buffer to 
+     * ImageConsumers and notifies them that an animation frame 
+     * is completed only if framenotify parameter is true.
+     * That works only if the animated flag has been set to true 
+     * by the setAnimated() method. If the full buffer update flag 
+     * has been set to true by the setFullBufferUpdates() method, 
+     * then the entire buffer will always be sent ignoring parameters.
+     * 
+     * @param x the X coordinate of the rectangular area.
+     * @param y the Y coordinate of rthe ectangular area.
+     * @param w the width of the rectangular area.
+     * @param h the height of the rectangular area. 
+     * @param framenotify true if a SINGLEFRAMEDONE notification
+     * should be sent to the registered consumers, false otherwise. 
+     */
+    public synchronized void newPixels(int x, int y, int w, int h,
+            boolean framenotify) {
+        if(animated){
+            if(fullbuffers){
+                x = 0;
+                y = 0;
+                w = width;
+                h = height;
+            }else{
+                if(x < 0){
+                    w += x;
+                    x = 0;
+                }
+                if(w > width) {
+                    w = width - x;
+                }
+                if(y < 0){
+                    h += y;
+                    y = 0;
+                }
+            }
+            if(h > height) {
+                h = height - y;
+            }
+            Object consAr[] = consumers.toArray();
+            for (Object element : consAr) {
+                ImageConsumer con = (ImageConsumer)element;
+                try{
+                    if(w > 0 && h > 0) {
+                        setPixels(con, x, y, w, h);
+                    }
+                    if(framenotify) {
+                        con.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+                    }
+                }catch(Exception ex){
+                    if(isConsumer(con)) {
+                        con.imageComplete(ImageConsumer.IMAGEERROR);
+                    }
+                    if(isConsumer(con)) {
+                        removeConsumer(con);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sends the specified rectangular area of the buffer to 
+     * the ImageConsumers and notifies them that an animation frame 
+     * is completed if the animated flag has been set to true 
+     * by the setAnimated() method. If the full buffer update flag 
+     * has been set to true by the setFullBufferUpdates() method, 
+     * then the entire buffer will always be sent ignoring parameters.
+     * 
+     * @param x the X coordinate of the rectangular area.
+     * @param y the Y coordinate of the rectangular area.
+     * @param w the width of the rectangular area.
+     * @param h the height of the rectangular area. 
+     */
+    public synchronized void newPixels(int x, int y, int w, int h) {
+        newPixels(x, y, w, h, true);
+    }
+
+    /**
+     * Sends a new buffer of pixels to the ImageConsumers 
+     * and notifies them that an animation frame is completed if
+     * the animated flag has been set to true by the setAnimated() method. 
+     */
+    public void newPixels() {
+        newPixels(0, 0, width, height, true);
+    }
+
+    /**
+     * Inits the.
+     * 
+     * @param width the width
+     * @param height the height
+     * @param model the model
+     * @param pixels the pixels
+     * @param off the off
+     * @param scan the scan
+     * @param prop the prop
+     */
+    private void init(int width, int height, ColorModel model, byte pixels[],
+            int off, int scan, Hashtable<?, ?> prop){
+
+        this.width = width;
+        this.height = height;
+        this.cm = model;
+        this.bData = pixels;
+        this.offset = off;
+        this.scanline = scan;
+        this.properties = prop;
+        this.dataType = DATA_TYPE_BYTE;
+        this.consumers = new Vector<ImageConsumer>();
+
+    }
+
+    /**
+     * Inits the.
+     * 
+     * @param width the width
+     * @param height the height
+     * @param model the model
+     * @param pixels the pixels
+     * @param off the off
+     * @param scan the scan
+     * @param prop the prop
+     */
+    private void init(int width, int height, ColorModel model, int pixels[],
+            int off, int scan, Hashtable<?, ?> prop){
+
+        this.width = width;
+        this.height = height;
+        this.cm = model;
+        this.iData = pixels;
+        this.offset = off;
+        this.scanline = scan;
+        this.properties = prop;
+        this.dataType = DATA_TYPE_INT;
+        this.consumers = new Vector<ImageConsumer>();
+    }
+
+    /**
+     * Sets the pixels.
+     * 
+     * @param con the con
+     * @param x the x
+     * @param y the y
+     * @param w the w
+     * @param h the h
+     */
+    private void setPixels(ImageConsumer con, int x, int y, int w, int h){
+        int pixelOff = scanline * y + offset + x;
+
+        switch(dataType){
+        case DATA_TYPE_BYTE:
+            con.setPixels(x, y, w, h, cm, bData, pixelOff, scanline);
+            break;
+        case DATA_TYPE_INT:
+            con.setPixels(x, y, w, h, cm, iData, pixelOff, scanline);
+            break;
+        default:
+            // awt.22A=Wrong type of pixels array
+            throw new IllegalArgumentException(Messages.getString("awt.22A")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Sets the header.
+     * 
+     * @param con the new header
+     */
+    private synchronized void setHeader(ImageConsumer con){
+        con.setDimensions(width, height);
+        con.setProperties(properties);
+        con.setColorModel(cm);
+        con.setHints(animated ? (fullbuffers ? (ImageConsumer.TOPDOWNLEFTRIGHT |
+                ImageConsumer.COMPLETESCANLINES) : ImageConsumer.RANDOMPIXELORDER) :
+                (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
+                 ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME));
+    }
+
+}
+
diff --git a/awt/java/awt/image/MultiPixelPackedSampleModel.java b/awt/java/awt/image/MultiPixelPackedSampleModel.java
new file mode 100644
index 0000000..dd44b49
--- /dev/null
+++ b/awt/java/awt/image/MultiPixelPackedSampleModel.java
@@ -0,0 +1,454 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The MultiPixelPackedSampleModel class represents image data with one
+ * band. This class packs multiple pixels with one sample in one data 
+ * element and supports the following data types: DataBuffer.TYPE_BYTE, 
+ * DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT. 
+ */
+public class MultiPixelPackedSampleModel extends SampleModel {
+
+    /** The pixel bit stride. */
+    private int pixelBitStride;
+
+    /** The scanline stride. */
+    private int scanlineStride;
+
+    /** The data bit offset. */
+    private int dataBitOffset;
+
+    /** The bit mask. */
+    private int bitMask;
+
+    /** The data element size. */
+    private int dataElementSize;
+
+    /** The pixels per data element. */
+    private int pixelsPerDataElement;
+
+    /**
+     * Instantiates a new MultiPixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param numberOfBits the number of bits per pixel.
+     * @param scanlineStride the scanline stride of the of the image data.
+     * @param dataBitOffset the array of the band offsets.
+     */
+    public MultiPixelPackedSampleModel(int dataType, int w, int h,
+            int numberOfBits, int scanlineStride, int dataBitOffset) {
+
+        super(dataType, w, h, 1);
+        if (dataType != DataBuffer.TYPE_BYTE &&
+               dataType != DataBuffer.TYPE_USHORT &&
+               dataType != DataBuffer.TYPE_INT) {
+            // awt.61=Unsupported data type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
+                    dataType));
+        }
+
+        this.scanlineStride = scanlineStride;
+        if(numberOfBits == 0) {
+            // awt.20C=Number of Bits equals to zero
+            throw new RasterFormatException(Messages.getString("awt.20C")); //$NON-NLS-1$
+        }
+        this.pixelBitStride = numberOfBits;
+        this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
+        if(dataElementSize % pixelBitStride != 0) {
+            // awt.20D=The number of bits per pixel is not a power of 2 or pixels span data element boundaries
+            throw new RasterFormatException(Messages.getString("awt.20D")); //$NON-NLS-1$
+        }
+
+        if(dataBitOffset % numberOfBits != 0) {
+            // awt.20E=Data Bit offset is not a multiple of pixel bit stride
+            throw new RasterFormatException(Messages.getString("awt.20E")); //$NON-NLS-1$
+        }
+        this.dataBitOffset = dataBitOffset;
+
+        this.pixelsPerDataElement = dataElementSize / pixelBitStride;
+        this.bitMask = (1 << numberOfBits) - 1;
+    }
+
+    /**
+     * Instantiates a new MultiPixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param numberOfBits the number of bits per pixel.
+     */
+    public MultiPixelPackedSampleModel(int dataType, int w, int h,
+            int numberOfBits) {
+
+        this(dataType, w, h, numberOfBits, (numberOfBits * w +
+               DataBuffer.getDataTypeSize(dataType) - 1) /
+               DataBuffer.getDataTypeSize(dataType), 0);
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            if (obj == null) {
+                bdata = new byte[1];
+            } else {
+                bdata = (byte[]) obj;
+            }
+            bdata[0] = (byte) getSample(x, y, 0, data);
+            obj = bdata;
+            break;
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            if (obj == null) {
+                sdata = new short[1];
+            } else {
+                sdata = (short[]) obj;
+            }
+            sdata[0] = (short) getSample(x, y, 0, data);
+            obj = sdata;
+            break;
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            if (obj == null) {
+                idata = new int[1];
+            } else {
+                idata = (int[]) obj;
+            }
+            idata[0] = getSample(x, y, 0, data);
+            obj = idata;
+            break;
+        }
+
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        setSample(x, y, obj, data, 1, 0);
+    }
+
+    /**
+     * Compares this MultiPixelPackedSampleModel object with 
+     * the specified object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if the object is a MultiPixelPackedSampleModel 
+     * with the same data parameter values as this MultiPixelPackedSampleModel,
+     * false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
+            return false;
+        }
+
+        MultiPixelPackedSampleModel model = (MultiPixelPackedSampleModel) o;
+        return this.width == model.width &&
+               this.height == model.height &&
+               this.numBands == model.numBands &&
+               this.dataType == model.dataType &&
+               this.pixelBitStride == model.pixelBitStride &&
+               this.bitMask == model.bitMask &&
+               this.pixelsPerDataElement == model.pixelsPerDataElement &&
+               this.dataElementSize == model.dataElementSize &&
+               this.dataBitOffset == model.dataBitOffset &&
+               this.scanlineStride == model.scanlineStride;
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands != null && bands.length != 1) {
+            // awt.20F=Number of bands must be only 1
+            throw new RasterFormatException(Messages.getString("awt.20F")); //$NON-NLS-1$
+        }
+        return createCompatibleSampleModel(width, height);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        pixel[0] = getSample(x, y, 0, data);
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        setSample(x, y, iArray, data, 2, 0);
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height || b != 0) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int bitnum = dataBitOffset + x * pixelBitStride;
+        int elem = data.getElem(y * scanlineStride + bitnum / dataElementSize);
+        int shift = dataElementSize - (bitnum & (dataElementSize - 1)) -
+                pixelBitStride;
+
+        return (elem >> shift) & bitMask;
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (b != 0) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        setSample(x, y, null, data, 3, s);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer dataBuffer = null;
+        int size = scanlineStride * height;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            dataBuffer = new DataBufferByte(size + (dataBitOffset + 7) / 8);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            dataBuffer = new DataBufferUShort(size + (dataBitOffset + 15) / 16);
+            break;
+        case DataBuffer.TYPE_INT:
+            dataBuffer = new DataBufferInt(size + (dataBitOffset + 31) / 32);
+            break;
+        }
+        return dataBuffer;
+    }
+
+    /**
+     * Gets the offset of the specified pixel in the data array.
+     * 
+     * @param x the X coordinate of the specified pixel.
+     * @param y the Y coordinate of the specified pixel.
+     * 
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return y * scanlineStride + (x * pixelBitStride + dataBitOffset) /
+               dataElementSize;
+    }
+
+    @Override
+    public int getSampleSize(int band) {
+        return pixelBitStride;
+    }
+
+    /**
+     * Gets the bit offset in the data element which 
+     * is stored for the specified pixel of a scanline.
+     * 
+     * @param x the pixel.
+     * 
+     * @return the bit offset of the pixel in the data element.
+     */
+    public int getBitOffset(int x) {
+        return (x * pixelBitStride + dataBitOffset) % dataElementSize;
+    }
+
+    @Override
+    public int[] getSampleSize() {
+        int sampleSizes[] = { pixelBitStride };
+        return sampleSizes;
+    }
+
+    /**
+     * Returns a hash code of this MultiPixelPackedSampleModel class.
+     * 
+     * @return the hash code of this MultiPixelPackedSampleModel class.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= scanlineStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= pixelBitStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataBitOffset;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= bitMask;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataElementSize;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= pixelsPerDataElement;
+        return hash;
+    }
+
+    @Override
+    public int getTransferType() {
+        if (pixelBitStride > 16) {
+            return DataBuffer.TYPE_INT;
+        } else if (pixelBitStride > 8) {
+            return DataBuffer.TYPE_USHORT;
+        } else {
+            return DataBuffer.TYPE_BYTE;
+        }
+    }
+
+    /**
+     * Gets the scanline stride of this MultiPixelPackedSampleModel.
+     * 
+     * @return the scanline stride of this MultiPixelPackedSampleModel.
+     */
+    public int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /**
+     * Gets the pixel bit stride of this MultiPixelPackedSampleModel.
+     * 
+     * @return the pixel bit stride of this MultiPixelPackedSampleModel.
+     */
+    public int getPixelBitStride() {
+        return pixelBitStride;
+    }
+
+    @Override
+    public int getNumDataElements() {
+        return 1;
+    }
+
+    /**
+     * Gets the data bit offset.
+     * 
+     * @return the data bit offset.
+     */
+    public int getDataBitOffset() {
+        return dataBitOffset;
+    }
+
+    /**
+     * This method is used by other methods of this class. The behaviour of
+     * this method depends on the method which has been invoke this one. The
+     * argument methodId is used to choose valid behaviour in a particular case.
+     * If methodId is equal to 1 it means that this method has been invoked by
+     * the setDataElements() method, 2 - means setPixel(), and setSample() in
+     * any other cases.
+     * 
+     * @param x the x
+     * @param y the y
+     * @param obj the obj
+     * @param data the data
+     * @param methodId the method id
+     * @param s the s
+     */
+    private void setSample(final int x, final int y, final Object obj,
+            final DataBuffer data, final int methodId, int s) {
+        if ((x < 0) || (y < 0) || (x >= this.width) || (y >= this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages
+                    .getString("awt.63")); //$NON-NLS-1$
+        }
+
+        final int bitnum = dataBitOffset + x * pixelBitStride;
+        final int idx = y * scanlineStride + bitnum / dataElementSize;
+        final int shift = dataElementSize - (bitnum & (dataElementSize - 1))
+                - pixelBitStride;
+        final int mask = ~(bitMask << shift);
+        int elem = data.getElem(idx);
+
+        switch (methodId) {
+        case 1: {                        // Invoked from setDataElements()
+            switch (getTransferType()) {
+            case DataBuffer.TYPE_BYTE:
+                s = ((byte[]) obj)[0] & 0xff;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                s = ((short[]) obj)[0] & 0xffff;
+                break;
+            case DataBuffer.TYPE_INT:
+                s = ((int[]) obj)[0];
+                break;
+            }
+            break;
+        }
+        case 2: {                        // Invoked from setPixel()
+            s = ((int[]) obj)[0];
+            break;
+        }
+        }
+
+        elem &= mask;
+        elem |= (s & bitMask) << shift;
+        data.setElem(idx, elem);
+    }
+}
+
diff --git a/awt/java/awt/image/PackedColorModel.java b/awt/java/awt/image/PackedColorModel.java
new file mode 100644
index 0000000..7aaefbf
--- /dev/null
+++ b/awt/java/awt/image/PackedColorModel.java
@@ -0,0 +1,383 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class PackedColorModel represents a color model where the 
+ * components are just the red, green, and blue bands, plus an alpha
+ * band if alpha is supported.
+ */
+public abstract class PackedColorModel extends ColorModel {
+
+    /** The component masks. */
+    int componentMasks[];
+
+    /** The offsets. */
+    int offsets[];
+
+    /** The scales. */
+    float scales[];
+
+    /**
+     * Instantiates a new packed color model.
+     * 
+     * @param space the color space
+     * @param bits the array of component masks
+     * @param colorMaskArray the array that gives the bitmask corresponding
+     * to each color band (red, green, and blue)
+     * @param alphaMask the bitmask corresponding to the alpha band
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this color model
+     * @param trans the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the number of bits in the combined 
+     * bitmasks for the color bands is less than one or greater than 32
+     */
+    public PackedColorModel(ColorSpace space, int bits, int colorMaskArray[],
+            int alphaMask, boolean isAlphaPremultiplied, int trans,
+            int transferType) {
+
+        super(bits, createBits(colorMaskArray, alphaMask), space,
+                (alphaMask == 0 ? false : true), isAlphaPremultiplied, trans,
+                validateTransferType(transferType));
+
+        if (pixel_bits < 1 || pixel_bits > 32) {
+            // awt.236=The bits is less than 1 or greater than 32
+            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
+        }
+
+        componentMasks = new int[numComponents];
+        for (int i = 0; i < numColorComponents; i++) {
+            componentMasks[i] = colorMaskArray[i];
+        }
+
+        if (hasAlpha) {
+            componentMasks[numColorComponents] = alphaMask;
+            if (this.bits[numColorComponents] == 1) {
+                transparency = Transparency.BITMASK;
+            }
+        }
+
+        parseComponents();
+    }
+
+    /**
+     * Instantiates a new packed color model.
+     * 
+     * @param space the color space
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     * @param amask the bitmask corresponding to the alpha band
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this color model
+     * @param trans the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the number of bits in the combined 
+     * bitmasks for the color bands is less than one or greater than 32
+     */
+    public PackedColorModel(ColorSpace space, int bits, int rmask, int gmask,
+            int bmask, int amask, boolean isAlphaPremultiplied, int trans,
+            int transferType) {
+
+        super(bits, createBits(rmask, gmask, bmask, amask), space,
+                (amask == 0 ? false : true), isAlphaPremultiplied, trans,
+                validateTransferType(transferType));
+
+        if (pixel_bits < 1 || pixel_bits > 32) {
+            // awt.236=The bits is less than 1 or greater than 32
+            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
+        }
+
+        if (cs.getType() != ColorSpace.TYPE_RGB) {
+            // awt.239=The space is not a TYPE_RGB space
+            throw new IllegalArgumentException(Messages.getString("awt.239")); //$NON-NLS-1$
+        }
+
+        for (int i = 0; i < numColorComponents; i++) {
+            if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                // awt.23A=The min/max normalized component values are not 0.0/1.0
+                throw new IllegalArgumentException(Messages.getString("awt.23A")); //$NON-NLS-1$
+            }
+        }
+        componentMasks = new int[numComponents];
+        componentMasks[0] = rmask;
+        componentMasks[1] = gmask;
+        componentMasks[2] = bmask;
+
+        if (hasAlpha) {
+            componentMasks[3] = amask;
+            if (this.bits[3] == 1) {
+                transparency = Transparency.BITMASK;
+            }
+        }
+
+        parseComponents();
+    }
+
+    @Override
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        if(!hasAlpha) {
+            return null;
+        }
+
+        int x = raster.getMinX();
+        int y = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+        int band[] = new int[1];
+        band[0] = raster.getNumBands() - 1;
+        return raster.createWritableChild(x, y, w, h, x, y, band);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof PackedColorModel)) {
+            return false;
+        }
+        PackedColorModel cm = (PackedColorModel) obj;
+
+        return (pixel_bits == cm.getPixelSize() &&
+                transferType == cm.getTransferType() &&
+                cs.getType() == cm.getColorSpace().getType() &&
+                hasAlpha == cm.hasAlpha() &&
+                isAlphaPremultiplied == cm.isAlphaPremultiplied() &&
+                transparency == cm.getTransparency() &&
+                numColorComponents == cm.getNumColorComponents()&&
+                numComponents == cm.getNumComponents() &&
+                Arrays.equals(bits, cm.getComponentSize()) &&
+                Arrays.equals(componentMasks, cm.getMasks()));
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (sm == null) {
+            return false;
+        }
+        if (!(sm instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+        SinglePixelPackedSampleModel esm = (SinglePixelPackedSampleModel) sm;
+
+        return ((esm.getNumBands() == numComponents) &&
+                (esm.getTransferType() == transferType) &&
+                Arrays.equals(esm.getBitMasks(), componentMasks));
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new SinglePixelPackedSampleModel(transferType, w, h,
+                componentMasks);
+    }
+
+    /**
+     * Gets the bitmask corresponding to the specified color component.
+     * 
+     * @param index the index of the desired color
+     * 
+     * @return the mask
+     */
+    public final int getMask(int index) {
+        return componentMasks[index];
+    }
+
+    /**
+     * Gets the bitmasks of the components.
+     * 
+     * @return the masks
+     */
+    public final int[] getMasks() {
+        return (componentMasks.clone());
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param colorMaskArray the color mask array
+     * @param alphaMask the alpha mask
+     * 
+     * @return the int[]
+     */
+    private static int[] createBits(int colorMaskArray[], int alphaMask) {
+        int bits[];
+        int numComp;
+        if (alphaMask == 0) {
+            numComp = colorMaskArray.length;
+        } else {
+            numComp = colorMaskArray.length + 1;
+        }
+
+        bits = new int[numComp];
+        int i = 0;
+        for (; i < colorMaskArray.length; i++) {
+            bits[i] = countCompBits(colorMaskArray[i]);
+            if (bits[i] < 0) {
+                // awt.23B=The mask of the {0} component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23B", i)); //$NON-NLS-1$
+            }
+        }
+
+        if (i < numComp) {
+            bits[i] = countCompBits(alphaMask);
+
+            if (bits[i] < 0) {
+                // awt.23C=The mask of the alpha component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
+            }
+        }
+
+        return bits;
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param rmask the rmask
+     * @param gmask the gmask
+     * @param bmask the bmask
+     * @param amask the amask
+     * 
+     * @return the int[]
+     */
+    private static int[] createBits(int rmask, int gmask, int bmask,
+            int amask) {
+
+        int numComp;
+        if (amask == 0) {
+            numComp = 3;
+        } else {
+            numComp = 4;
+        }
+        int bits[] = new int[numComp];
+
+        bits[0] = countCompBits(rmask);
+        if (bits[0] < 0) {
+            // awt.23D=The mask of the red component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23D")); //$NON-NLS-1$
+        }
+
+        bits[1] = countCompBits(gmask);
+        if (bits[1] < 0) {
+            // awt.23E=The mask of the green component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23E")); //$NON-NLS-1$
+        }
+
+        bits[2] = countCompBits(bmask);
+        if (bits[2] < 0) {
+            // awt.23F=The mask of the blue component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23F")); //$NON-NLS-1$
+        }
+
+        if (amask != 0) {
+            bits[3] = countCompBits(amask);
+            if (bits[3] < 0) {
+                // awt.23C=The mask of the alpha component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
+            }
+        }
+
+        return bits;
+    }
+
+    /**
+     * Count comp bits.
+     * 
+     * @param compMask the comp mask
+     * 
+     * @return the int
+     */
+    private static int countCompBits(int compMask) {
+        int bits = 0;
+        if (compMask != 0) {
+            // Deleting final zeros
+            while ((compMask & 1) == 0) {
+                compMask >>>= 1;
+            }
+            // Counting component bits
+            while ((compMask & 1) == 1) {
+                compMask >>>= 1;
+                bits++;
+            }
+        }
+
+        if (compMask != 0) {
+            return -1;
+        }
+
+        return bits;
+    }
+
+    /**
+     * Validate transfer type.
+     * 
+     * @param transferType the transfer type
+     * 
+     * @return the int
+     */
+    private static int validateTransferType(int transferType) {
+        if (transferType != DataBuffer.TYPE_BYTE &&
+                transferType != DataBuffer.TYPE_USHORT &&
+                transferType != DataBuffer.TYPE_INT) {
+            // awt.240=The transferType not is one of DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT or DataBuffer.TYPE_INT
+            throw new IllegalArgumentException(Messages.getString("awt.240")); //$NON-NLS-1$
+        }
+        return transferType;
+}
+
+    /**
+     * Parses the components.
+     */
+    private void parseComponents() {
+        offsets = new int[numComponents];
+        scales = new float[numComponents];
+        for (int i = 0; i < numComponents; i++) {
+            int off = 0;
+            int mask = componentMasks[i];
+            while ((mask & 1) == 0) {
+                mask >>>= 1;
+                off++;
+            }
+            offsets[i] = off;
+            if (bits[i] == 0) {
+                scales[i] = 256.0f; // May be any value different from zero,
+                // because will dividing by zero
+            } else {
+                scales[i] = 255.0f / maxValues[i];
+            }
+        }
+
+    }
+
+}
+
diff --git a/awt/java/awt/image/PixelGrabber.java b/awt/java/awt/image/PixelGrabber.java
new file mode 100644
index 0000000..cecd5c8
--- /dev/null
+++ b/awt/java/awt/image/PixelGrabber.java
@@ -0,0 +1,408 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Image;
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class PixelGrabber implements ImageConsumer {
+
+    int width;
+    int height;
+    int X;
+    int Y;
+    int offset;
+    int scanline;
+    ImageProducer producer;
+
+    byte bData[];
+    int iData[];
+    ColorModel cm;
+
+    private int grabberStatus;
+    private int dataType;
+    private boolean isGrabbing;
+    private boolean isRGB;
+
+
+    private static final int DATA_TYPE_BYTE = 0;
+    private static final int DATA_TYPE_INT = 1;
+    private static final int DATA_TYPE_UNDEFINED = 2;
+
+    private static final int ALL_BITS = (ImageObserver.FRAMEBITS |
+            ImageObserver.ALLBITS);
+
+    private static final int GRABBING_STOP = ALL_BITS | ImageObserver.ERROR;
+
+
+
+    public PixelGrabber(ImageProducer ip, int x, int y, int w, int h, int[] pix,
+            int off, int scansize) {
+        initialize(ip, x, y, w, h, pix, off, scansize, true);
+    }
+
+    public PixelGrabber(Image img, int x, int y, int w, int h, int[] pix,
+            int off, int scansize) {
+        initialize(img.getSource(), x, y, w, h, pix, off, scansize, true);
+    }
+
+    public PixelGrabber(Image img, int x, int y, int w, int h, boolean forceRGB) {
+        initialize(img.getSource(), x, y, w, h, null, 0, 0, forceRGB);
+    }
+
+    public void setProperties(Hashtable<?, ?> props) {
+        return;
+    }
+
+    public synchronized Object getPixels() {
+        switch(dataType){
+        case DATA_TYPE_BYTE:
+            return bData;
+        case DATA_TYPE_INT:
+            return iData;
+        default:
+            return null;
+        }
+    }
+
+    public void setColorModel(ColorModel model) {
+        return;
+    }
+
+    public void setPixels(int srcX, int srcY, int srcW, int srcH,
+            ColorModel model, byte[] pixels, int srcOff, int srcScan) {
+        if(srcY < Y){
+            int delta = Y - srcY;
+            if(delta >= height) {
+                return;
+            }
+            srcY += delta;
+            srcH -= delta;
+            srcOff += srcScan * delta;
+        }
+
+        if(srcY + srcH > Y + height){
+            srcH = Y + height - srcY;
+            if(srcH <= 0) {
+                return;
+            }
+        }
+
+        if(srcX < X){
+            int delta = X - srcX;
+            if(delta >= width) {
+                return;
+            }
+            srcW -= delta;
+            srcX += delta;
+            srcOff += delta;
+        }
+
+        if(srcX + srcW > X + width){
+            srcW = X + width - srcX;
+            if(srcW <= 0) {
+                return;
+            }
+        }
+        if(scanline == 0) {
+            scanline = width;
+        }
+        int realOff = offset + (srcY - Y) * scanline + (srcX - X);
+        switch(dataType){
+        case DATA_TYPE_UNDEFINED:
+            cm = model;
+            if(model != ColorModel.getRGBdefault()){
+                bData = new byte[width * height];
+                isRGB = false;
+                dataType = DATA_TYPE_BYTE;
+            }else{
+                iData = new int[width * height];
+                isRGB = true;
+                dataType = DATA_TYPE_INT;
+            }
+        case DATA_TYPE_BYTE:
+            if(!isRGB && cm == model){
+                for(int y = 0; y < srcH; y++){
+                    System.arraycopy(pixels, srcOff, bData, realOff, srcW);
+                    srcOff += srcScan;
+                    realOff += scanline;
+                }
+                break;
+            }
+            forceToRGB();
+        case DATA_TYPE_INT:
+            for(int y = 0; y < srcH; y++){
+                for(int x = 0; x < srcW; x++){
+                    iData[realOff + x] = cm.getRGB(pixels[srcOff + x] & 0xff);                    
+                }
+                srcOff += srcScan;
+                realOff += scanline;
+            }
+        }
+
+        return;
+    }
+
+    public void setPixels(int srcX, int srcY, int srcW, int srcH,
+            ColorModel model, int[] pixels, int srcOff, int srcScan) {
+
+        if(srcY < Y){
+            int delta = Y - srcY;
+            if(delta >= height) {
+                return;
+            }
+            srcY += delta;
+            srcH -= delta;
+            srcOff += srcScan * delta;
+        }
+
+        if(srcY + srcH > Y + height){
+            srcH = Y + height - srcY;
+            if(srcH <= 0) {
+                return;
+            }
+        }
+
+        if(srcX < X){
+            int delta = X - srcX;
+            if(delta >= width) {
+                return;
+            }
+            srcW -= delta;
+            srcX += delta;
+            srcOff += delta;
+        }
+
+        if(srcX + srcW > X + width){
+            srcW = X + width - srcX;
+            if(srcW <= 0) {
+                return;
+            }
+        }
+        if(scanline == 0) {
+            scanline = width;
+        }
+        int realOff = offset + (srcY - Y) * scanline + (srcX - X);
+
+        int mask = 0xFF;
+
+        switch(dataType){
+        case DATA_TYPE_UNDEFINED:
+            cm = model;
+            iData = new int[width * height];
+            dataType = DATA_TYPE_INT;
+            isRGB = (cm == ColorModel.getRGBdefault());
+
+        case DATA_TYPE_INT:
+            if(cm == model){
+                for(int y = 0; y < srcH; y++){
+                    System.arraycopy(pixels, srcOff, iData, realOff, srcW);
+                    srcOff += srcScan;
+                    realOff += scanline;
+                }
+                break;
+            }
+            mask = 0xFFFFFFFF;
+
+        case DATA_TYPE_BYTE:
+            forceToRGB();
+            for(int y = 0; y < srcH; y++){
+                for(int x = 0; x < srcW; x++){
+                    iData[realOff+x] = cm.getRGB(pixels[srcOff+x] & mask);
+                }
+                srcOff += srcScan;
+                realOff += scanline;
+            }
+        }
+    }
+
+    public synchronized ColorModel getColorModel() {
+        return cm;
+    }
+
+    public synchronized boolean grabPixels(long ms) 
+    throws InterruptedException {
+        if((grabberStatus & GRABBING_STOP) != 0){
+            return ((grabberStatus & ALL_BITS) != 0);
+        }
+
+        long start = System.currentTimeMillis();
+
+        if(!isGrabbing){
+            isGrabbing = true;
+            grabberStatus &= ~ImageObserver.ABORT;
+            producer.startProduction(this);
+        }
+        while((grabberStatus & GRABBING_STOP) == 0){
+            if(ms != 0){
+                ms = start + ms - System.currentTimeMillis();
+                if(ms <= 0) {
+                    break;
+                }
+            }
+            wait(ms);
+        }
+
+        return ((grabberStatus & ALL_BITS) != 0);
+    }
+
+    public void setDimensions(int w, int h) {
+        if(width < 0) {
+            width = w - X;
+        }
+        if(height < 0) {
+            height = h - Y;
+        }
+
+        grabberStatus |= ImageObserver.WIDTH | ImageObserver.HEIGHT;
+
+        if(width <=0 || height <=0){
+            imageComplete(STATICIMAGEDONE);
+            return;
+        }
+
+        if(isRGB && dataType == DATA_TYPE_UNDEFINED){
+            iData = new int[width * height];
+            dataType = DATA_TYPE_INT;
+            scanline = width;
+        }
+    }
+
+    public void setHints(int hints) {
+        return;
+    }
+
+    public synchronized void imageComplete(int status) {
+        switch(status){
+        case IMAGEABORTED:
+            grabberStatus |= ImageObserver.ABORT;
+            break;
+        case IMAGEERROR:
+            grabberStatus |= ImageObserver.ERROR | ImageObserver.ABORT;
+            break;
+        case SINGLEFRAMEDONE:
+            grabberStatus |= ImageObserver.FRAMEBITS;
+            break;
+        case STATICIMAGEDONE:
+            grabberStatus |= ImageObserver.ALLBITS;
+            break;
+        default:
+            // awt.26A=Incorrect ImageConsumer completion status
+            throw new IllegalArgumentException(Messages.getString("awt.26A")); //$NON-NLS-1$
+        }
+        isGrabbing = false;
+        producer.removeConsumer(this);
+        notifyAll();
+    }
+
+    public boolean grabPixels() throws InterruptedException {
+        return grabPixels(0);
+    }
+
+    public synchronized void startGrabbing() {
+        if((grabberStatus & GRABBING_STOP) != 0){
+            return;
+        }
+        if(!isGrabbing){
+            isGrabbing = true;
+            grabberStatus &= ~ImageObserver.ABORT;
+            producer.startProduction(this);
+        }
+    }
+
+    public synchronized void abortGrabbing() {
+        imageComplete(IMAGEABORTED);
+    }
+
+    public synchronized int status() {
+        return grabberStatus;
+    }
+
+    public synchronized int getWidth() {
+        if(width < 0) {
+            return -1;
+        }
+        return width;
+    }
+
+    public synchronized int getStatus() {
+        return grabberStatus;
+    }
+
+    public synchronized int getHeight() {
+        if(height < 0) {
+            return -1;
+        }
+        return height;
+    }
+
+    private void initialize(ImageProducer ip, int x, int y, int w, int h,
+            int pixels[], int off, int scansize, boolean forceRGB){
+
+        producer = ip;
+        X = x;
+        Y = y;
+        width = w;
+        height = h;
+        iData = pixels;
+        dataType = (pixels == null) ? DATA_TYPE_UNDEFINED : DATA_TYPE_INT;
+        offset = off;
+        scanline = scansize;
+        if(forceRGB){
+            cm = ColorModel.getRGBdefault();
+            isRGB = true;
+        }
+    }
+
+    /**
+     * Force pixels to INT RGB mode
+     */
+    private void forceToRGB(){
+        if (isRGB)
+            return;
+    
+        switch(dataType){
+        case DATA_TYPE_BYTE:
+            iData = new int[width * height];
+            for(int i = 0; i < iData.length; i++){
+                iData[i] = cm.getRGB(bData[i] & 0xff);
+            }
+            dataType = DATA_TYPE_INT;
+            bData = null;
+            break;
+
+        case DATA_TYPE_INT:
+            int buff[] = new int[width * height];
+            for(int i = 0; i < iData.length; i++){
+                buff[i] = cm.getRGB(iData[i]);
+            }
+            iData = buff;
+            break;
+        }
+        offset = 0;
+        scanline = width;
+        cm = ColorModel.getRGBdefault();
+        isRGB = true;
+    }
+
+}
diff --git a/awt/java/awt/image/PixelInterleavedSampleModel.java b/awt/java/awt/image/PixelInterleavedSampleModel.java
new file mode 100644
index 0000000..e41473e
--- /dev/null
+++ b/awt/java/awt/image/PixelInterleavedSampleModel.java
@@ -0,0 +1,124 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The PixelInterleavedSampleModel class represents image data 
+ * as represented as interleaved pixels and for which each sample of 
+ * a pixel takes one data element of the DataBuffer.
+ */
+public class PixelInterleavedSampleModel extends ComponentSampleModel {
+
+    /**
+     * Instantiates a new PixelInterleavedSampleModel with the 
+     * specified parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param pixelStride the pixel stride of the image data.
+     * @param scanlineStride the scanline stride of the of the image data.
+     * @param bandOffsets the array of the band offsets.
+     */
+    public PixelInterleavedSampleModel(int dataType, int w, int h,
+            int pixelStride, int scanlineStride, int bandOffsets[]) {
+
+        super(dataType, w, h, pixelStride, scanlineStride, bandOffsets);
+
+        int maxOffset = bandOffsets[0];
+        int minOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+
+        maxOffset -= minOffset;
+
+        if (maxOffset > scanlineStride) {
+            // awt.241=Any offset between bands is greater than the Scanline stride
+            throw new IllegalArgumentException(Messages.getString("awt.241")); //$NON-NLS-1$
+        }
+
+        if (maxOffset > pixelStride) {
+            // awt.242=Pixel stride is less than any offset between bands
+            throw new IllegalArgumentException(Messages.getString("awt.242")); //$NON-NLS-1$
+        }
+
+        if (pixelStride * w > scanlineStride) {
+            // awt.243=Product of Pixel stride and w is greater than Scanline stride
+            throw new IllegalArgumentException(Messages.getString("awt.243")); //$NON-NLS-1$
+        }
+
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        int newOffsets[] = new int[bands.length];
+        for (int i = 0; i < bands.length; i++) {
+            newOffsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new PixelInterleavedSampleModel(dataType, width, height,
+                pixelStride, scanlineStride, newOffsets);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        int newOffsets[];
+        int minOffset = bandOffsets[0];
+
+        for (int i = 1; i < numBands; i++) {
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+
+        if (minOffset > 0) {
+            newOffsets = new int[numBands];
+            for (int i = 0; i < numBands; i++) {
+                newOffsets[i] = bandOffsets[i] - minOffset;
+            }
+        } else {
+            newOffsets = bandOffsets;
+        }
+
+        return new PixelInterleavedSampleModel(dataType, w, h, pixelStride,
+                pixelStride * w, newOffsets);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        int tmp = hash >>> 8;
+        hash <<= 8;
+        hash |= tmp;
+
+        return hash ^ 0x66;
+    }
+
+}
+
diff --git a/awt/java/awt/image/RGBImageFilter.java b/awt/java/awt/image/RGBImageFilter.java
new file mode 100644
index 0000000..9a76997
--- /dev/null
+++ b/awt/java/awt/image/RGBImageFilter.java
@@ -0,0 +1,190 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * The RGBImageFilter class represents a filter which modifies
+ * pixels of an image in the default RGB ColorModel. 
+ */
+public abstract class RGBImageFilter extends ImageFilter {
+
+    /** 
+     * The origmodel is the ColorModel to be replaced by newmodel 
+     * when substituteColorModel is called.
+     */
+    protected ColorModel origmodel;
+
+    /** 
+     * The newmodel is the ColorModel with which to replace origmodel 
+     * when substituteColorModel is called. 
+     */
+    protected ColorModel newmodel;
+
+    /** 
+     * The canFilterIndexColorModel indicates if it is 
+     * acceptable to apply the color filtering of the filterRGB 
+     * method to the color table entries of an IndexColorModel 
+     * object.
+     * */
+    protected boolean canFilterIndexColorModel;
+
+    /**
+     * Instantiates a new RGBImageFilter.
+     */
+    public RGBImageFilter() {}
+
+    /**
+     * Filters an IndexColorModel object by calling filterRGB function for
+     * each entry of IndexColorModel.
+     * 
+     * @param icm the IndexColorModel to be filtered.
+     * 
+     * @return the IndexColorModel.
+     */
+    public IndexColorModel filterIndexColorModel(IndexColorModel icm) {
+        int transferType = icm.getTransferType();
+        int bits = icm.getPixelSize();
+        int mapSize = icm.getMapSize();
+        int colorMap[] = new int[mapSize];
+        int filteredColorMap[] = new int[mapSize];
+        icm.getRGBs(colorMap);
+        int trans = -1;
+        boolean hasAlpha = false;
+        for(int i = 0; i < mapSize; i++){
+            filteredColorMap[i] = filterRGB(-1, -1, colorMap[i]);
+            int alpha = filteredColorMap[i] >>> 24;
+            if(alpha != 0xff){
+                if(!hasAlpha) {
+                    hasAlpha = true;
+                }
+                if(alpha == 0 && trans < 0) {
+                    trans = i;
+                }
+            }
+        }
+
+        return new IndexColorModel(bits, mapSize, filteredColorMap, 0,
+                hasAlpha, trans, transferType);
+    }
+
+    /**
+     * Replaces the original color model and the new one.
+     * 
+     * @param oldcm the old ColorModel.
+     * @param newcm the new ColorModel.
+     */
+    public void substituteColorModel(ColorModel oldcm, ColorModel newcm) {
+        origmodel = oldcm;
+        newmodel = newcm;
+    }
+
+    @Override
+    public void setColorModel(ColorModel model) {
+        if(model instanceof IndexColorModel &&
+                canFilterIndexColorModel){
+            IndexColorModel icm = (IndexColorModel) model;
+            ColorModel filteredModel = filterIndexColorModel(icm);
+            substituteColorModel(model, filteredModel);
+            consumer.setColorModel(filteredModel);
+        }else{
+            consumer.setColorModel(ColorModel.getRGBdefault());
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, 
+            int[] pixels, int off, int scansize) {
+        
+        if(model == null || model == origmodel){
+            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
+        }else{
+            int rgbPixels[] = new int[w];
+            for(int sy = y, pixelsOff = off; sy < y + h; 
+                sy++, pixelsOff += scansize){
+                
+                for(int sx = x, idx = 0; sx < x + w; sx++, idx++){
+                    rgbPixels[idx] = model.getRGB(pixels[pixelsOff + idx]);
+                }
+                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
+            }
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, 
+            byte[] pixels, int off, int scansize) {
+        
+        if(model == null || model == origmodel){
+            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
+        }else{
+            int rgbPixels[] = new int[w];
+            for(int sy = y, pixelsOff = off; sy < y + h; 
+                sy++, pixelsOff += scansize){
+                
+                for(int sx = x, idx = 0; sx < x + w; sx++, idx++){
+                    rgbPixels[idx] = 
+                        model.getRGB(pixels[pixelsOff + idx] & 0xff);
+                }
+                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
+            }
+        }
+    }
+
+    /**
+     * Filters a region of pixels in the default RGB ColorModel 
+     * by calling the filterRGB method for them.
+     * 
+     * @param x the X coordinate of region.
+     * @param y the Y coordinate of region.
+     * @param w the width ofregion.
+     * @param h the height of region.
+     * @param pixels the pixels array.
+     * @param off the offset of array.
+     * @param scansize the distance between rows of pixels in the array.
+     */
+    public void filterRGBPixels(int x, int y, int w, int h, 
+            int[] pixels, int off, int scansize) {
+        
+        for(int sy = y, lineOff = off; sy < y + h; sy++, lineOff += scansize){
+            for(int sx = x, idx = 0; sx < x + w; sx++, idx++){
+                pixels[lineOff + idx] = 
+                    filterRGB(sx, sy, pixels[lineOff + idx]);
+            }
+        }
+        consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), 
+                pixels, off, scansize);
+    }
+
+    /**
+     * Coverts a single input pixel in the default RGB ColorModel 
+     * to a single output pixel.
+     * 
+     * @param x the X pixel's coordinate.
+     * @param y the Y pixel's coordinate.
+     * @param rgb a pixel in the default RGB color model.
+     * 
+     * @return a filtered pixel in the default RGB color model.
+     */
+    public abstract int filterRGB(int x, int y, int rgb);
+
+}
+
diff --git a/awt/java/awt/image/Raster.java b/awt/java/awt/image/Raster.java
new file mode 100644
index 0000000..4b2426e
--- /dev/null
+++ b/awt/java/awt/image/Raster.java
@@ -0,0 +1,1412 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.gl.image.OrdinaryWritableRaster;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Raster class represents a rectangular area of pixels.
+ * This class is defined by DataBuffer and SampleModel objects. 
+ * The DataBuffer object stores sample values and DSampleModel defines 
+ * the location of sample in this DataBuffer. 
+ */
+public class Raster {
+
+    /** The DataBuffer of this Raster. */
+    protected DataBuffer dataBuffer;
+
+    /** The height of this Raster. */
+    protected int height;
+
+    /** The X coordinate of the upper left pixel in this Raster. */
+    protected int minX;
+
+    /** The Y coordinate of the upper left pixel in this Raster. */
+    protected int minY;
+
+    /** The number of bands in this Raster. */
+    protected int numBands;
+
+    /** The number of data elements. */
+    protected int numDataElements;
+
+    /** The parent of this Raster. */
+    protected Raster parent;
+
+    /** The SampleModel of this Raster. */
+    protected SampleModel sampleModel;
+
+    /** 
+     * The X translation from the coordinate space of the 
+     * SampleModel of this Raster.
+     */
+    protected int sampleModelTranslateX;
+
+    /** 
+     * The Y translation from the coordinate space of the 
+     * SampleModel of this Raster.
+     */
+    protected int sampleModelTranslateY;
+
+    /** The width of this Raster. */
+    protected int width;
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified 
+     * DataBuffer. The number of bands is defined by the length of bandOffsets
+     * or bankIndices arrays.
+     * 
+     * @param dataBuffer the specified DataBuffer.
+     * @param w the width of the image data.
+     * @param h the height of the image data. 
+     * @param bankIndices the bank indices of bands.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
+            int w, int h, int scanlineStride, int bankIndices[],
+            int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bankIndices == null || bandOffsets == null) {
+            // awt.277=bankIndices or bandOffsets is null
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        BandedSampleModel sampleModel = new BandedSampleModel(dataType, w, h,
+                scanlineStride, bankIndices, bandOffsets);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+    }
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified
+     * data type. The Data type can be one of the following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of the samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data. 
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bankIndices the bank indices of bands.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(int dataType, int w, int h,
+            int scanlineStride, int bankIndices[], int bandOffsets[],
+            Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bankIndices == null || bandOffsets == null) {
+            // awt.277=bankIndices or bandOffsets is null
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        int maxOffset = bandOffsets[0];
+        int maxBank = bankIndices[0];
+
+        for (int i = 0; i < bankIndices.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+        }
+
+        int numBanks = maxBank + 1;
+        int dataSize = scanlineStride * (h - 1) + w + maxOffset;
+
+        DataBuffer data = null;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(dataSize, numBanks);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(dataSize, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(dataSize, numBanks);
+            break;
+        }
+        return createBandedRaster(data, w, h, scanlineStride, bankIndices,
+                bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified
+     * data type. The Data type can be one of the following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of the samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data. 
+     * @param bands the number of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(int dataType, int w, int h,
+            int bands, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bands < 1) {
+            // awt.279=bands is less than 1
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.279")); //$NON-NLS-1$
+        }
+
+        int bandOffsets[] = new int[bands];
+        int bankIndices[] = new int[bands];
+
+        for (int i = 0; i < bands; i++) {
+            bandOffsets[i] = 0;
+            bankIndices[i] = i;
+        }
+        return createBandedRaster(dataType, w, h, w, bankIndices, bandOffsets,
+                location);
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel 
+     * and the specified DataBuffer. 
+     * 
+     * @param dataBuffer the DataBuffer.
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param pixelStride the pixel stride of image data.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
+            int w, int h, int scanlineStride, int pixelStride,
+            int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        if (bandOffsets == null) {
+            // awt.27B=bandOffsets is null
+            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
+        }
+
+        PixelInterleavedSampleModel sampleModel = 
+            new PixelInterleavedSampleModel(dataType, w, h, 
+                    pixelStride, scanlineStride, bandOffsets);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel 
+     * and the specified data type. The Data type can be one of the 
+     * following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of the samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param pixelStride the pixel stride of image data.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createInterleavedRaster(int dataType, int w,
+            int h, int scanlineStride, int pixelStride, int bandOffsets[],
+            Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (bandOffsets == null) {
+            // awt.27B=bandOffsets is null
+            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
+        }
+
+        int minOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+        int size = (h - 1) * scanlineStride + w * pixelStride + minOffset;
+        DataBuffer data = null;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size);
+            break;
+        }
+
+        return createInterleavedRaster(data, w, h, scanlineStride, pixelStride,
+                bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel 
+     * and the specified data type. The Data type can be one of the 
+     * following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param bands the number of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createInterleavedRaster(int dataType, int w,
+            int h, int bands, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        int bandOffsets[] = new int[bands];
+        for (int i = 0; i < bands; i++) {
+            bandOffsets[i] = i;
+        }
+
+        return createInterleavedRaster(dataType, w, h, w * bands, bands,
+                bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a SinglePixelPackedSampleModel  
+     * and the specified DataBuffer. 
+     * 
+     * @param dataBuffer the DataBuffer.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bandMasks the band masks.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+            int w, int h, int scanlineStride, int bandMasks[], Point location) {
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bandMasks == null) {
+            // awt.27C=bandMasks is null
+            throw new RasterFormatException(Messages.getString("awt.27C")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        SinglePixelPackedSampleModel sampleModel = 
+            new SinglePixelPackedSampleModel(dataType, w, h, 
+                    scanlineStride, bandMasks);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+    }
+
+    /**
+     * Creates a Raster object with a MultiPixelPackedSampleModel   
+     * and the specified DataBuffer.
+     * 
+     * @param dataBuffer the DataBuffer.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bitsPerPixel the number of bits per pixel.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+            int w, int h, int bitsPerPixel, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        MultiPixelPackedSampleModel sampleModel = 
+            new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+
+    }
+
+    /**
+     * Creates a Raster object with a MultiPixelPackedSampleModel   
+     * and the specified DataBuffer.
+     * 
+     * @param dataType the data type of samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bands the number of bands.
+     * @param bitsPerBand the number of bits per band.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(int dataType, int w, int h,
+            int bands, int bitsPerBand, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bands < 1 || bitsPerBand < 1) {
+            // awt.27D=bitsPerBand or bands is not greater than zero
+            throw new IllegalArgumentException(Messages.getString("awt.27D")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (bitsPerBand * bands > DataBuffer.getDataTypeSize(dataType)) {
+            // awt.27E=The product of bitsPerBand and bands is greater than the number of bits held by dataType
+            throw new IllegalArgumentException(Messages.getString("awt.27E")); //$NON-NLS-1$
+        }
+
+        if (bands > 1) {
+
+            int bandMasks[] = new int[bands];
+            int mask = (1 << bitsPerBand) - 1;
+
+            for (int i = 0; i < bands; i++) {
+                bandMasks[i] = mask << (bitsPerBand * (bands - 1 - i));
+            }
+
+            return createPackedRaster(dataType, w, h, bandMasks, location);
+        }
+        DataBuffer data = null;
+        int size = ((bitsPerBand * w + 
+                DataBuffer.getDataTypeSize(dataType) - 1) / 
+                DataBuffer.getDataTypeSize(dataType)) * h;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size);
+            break;
+        }
+        return createPackedRaster(data, w, h, bitsPerBand, location);
+    }
+
+    /**
+     * Creates a Raster object with a SinglePixelPackedSampleModel    
+     * and the specified DataBuffer.
+     * 
+     * @param dataType the data type of samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bandMasks the band masks.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(int dataType, int w, int h,
+            int bandMasks[], Point location) {
+        
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bandMasks == null) {
+            // awt.27C=bandMasks is null
+            throw new NullPointerException(Messages.getString("awt.27C")); //$NON-NLS-1$
+        }
+
+        DataBuffer data = null;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(w * h);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(w * h);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(w * h);
+            break;
+        }
+
+        return createPackedRaster(data, w, h, w, bandMasks, location);
+    }
+
+    /**
+     * Creates a Raster object with the specified DataBuffer and SampleModel.
+     * 
+     * @param sm the specified SampleModel.
+     * @param db the specified DataBuffer.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the Raster.
+     */
+    public static Raster createRaster(SampleModel sm, DataBuffer db,
+            Point location) {
+
+        if (sm == null || db == null) {
+            // awt.27F=SampleModel or DataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return new Raster(sm, db, location);
+    }
+
+    /**
+     * Creates a WritableRaster with the specified SampleModel and DataBuffer.
+     * 
+     * @param sm the specified SampleModel.
+     * @param db the specified DataBuffer.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm,
+            DataBuffer db, Point location) {
+
+        if (sm == null || db == null) {
+            // awt.27F=SampleModel or DataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return new OrdinaryWritableRaster(sm, db, location);
+    }
+
+    /**
+     * Creates a WritableRaster with the specified SampleModel.
+     * 
+     * @param sm the specified SampleModel.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm,
+            Point location) {
+
+        if (sm == null) {
+            // awt.280=SampleModel is null
+            throw new NullPointerException(Messages.getString("awt.280")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return createWritableRaster(sm, sm.createDataBuffer(), location);
+    }
+
+    /**
+     * Instantiates a new Raster object with the specified SampleModel and
+     * DataBuffer.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified  DataBuffer.
+     * @param origin the specified origin.
+     */
+    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Point origin) {
+
+        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
+                sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
+    }
+
+    /**
+     * Instantiates a new Raster object with the specified SampleModel,
+     * DataBuffer, rectangular region and parent Raster. 
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified DataBuffer.
+     * @param aRegion the a rectangular region which defines the new image bounds. 
+     * @param sampleModelTranslate this point defines the translation point
+     * from the SampleModel coordinates to the new Raster coordinates.
+     * @param parent the parent of this Raster.
+     */
+    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Rectangle aRegion, Point sampleModelTranslate, Raster parent) {
+
+        if (sampleModel == null || dataBuffer == null || aRegion == null
+                || sampleModelTranslate == null) {
+            // awt.281=sampleModel, dataBuffer, aRegion or sampleModelTranslate is null
+            throw new NullPointerException(Messages.getString("awt.281")); //$NON-NLS-1$
+        }
+
+        if (aRegion.width <= 0 || aRegion.height <= 0) {
+            // awt.282=aRegion has width or height less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.282")); //$NON-NLS-1$
+        }
+
+        if ((long) aRegion.x + (long) aRegion.width > Integer.MAX_VALUE) {
+            // awt.283=Overflow X coordinate of Raster
+            throw new RasterFormatException(Messages.getString("awt.283")); //$NON-NLS-1$
+        }
+
+        if ((long) aRegion.y + (long) aRegion.height > Integer.MAX_VALUE) {
+            // awt.284=Overflow Y coordinate of Raster
+            throw new RasterFormatException(Messages.getString("awt.284")); //$NON-NLS-1$
+        }
+        
+        if (sampleModel instanceof ComponentSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((ComponentSampleModel) sampleModel).getScanlineStride());
+        } else if (sampleModel instanceof MultiPixelPackedSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((MultiPixelPackedSampleModel) sampleModel)
+                            .getScanlineStride());
+        } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((SinglePixelPackedSampleModel) sampleModel)
+                            .getScanlineStride());
+        }
+
+        this.sampleModel = sampleModel;
+        this.dataBuffer = dataBuffer;
+        this.minX = aRegion.x;
+        this.minY = aRegion.y;
+        this.width = aRegion.width;
+        this.height = aRegion.height;
+        this.sampleModelTranslateX = sampleModelTranslate.x;
+        this.sampleModelTranslateY = sampleModelTranslate.y;
+        this.parent = parent;
+        this.numBands = sampleModel.getNumBands();
+        this.numDataElements = sampleModel.getNumDataElements();
+
+    }
+
+    /**
+     * Instantiates a new Raster with the specified SampleModel.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param origin the origin.
+     */
+    protected Raster(SampleModel sampleModel, Point origin) {
+        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(
+                origin.x, origin.y, sampleModel.getWidth(), sampleModel
+                        .getHeight()), origin, null);
+    }
+
+    /**
+     * Creates the child of this Raster by sharing the specified rectangular
+     * area in this Raste. The parentX, parentY, width 
+     * and height parameters specify the rectangular area to be shared.
+     * 
+     * @param parentX the X coordinate of the upper left corner of this Raster. 
+     * @param parentY the Y coordinate of the upper left corner of this Raster.
+     * @param width the width of the child area.
+     * @param height the height of the child area.
+     * @param childMinX the X coordinate of child area mapped to the parentX
+     * coordinate.
+     * @param childMinY the Y coordinate of child area mapped to the parentY
+     * coordinate.
+     * @param bandList the array of band indicies.
+     * 
+     * @return the Raster.
+     */
+    public Raster createChild(int parentX, int parentY, int width, int height,
+            int childMinX, int childMinY, int bandList[]) {
+        if (width <= 0 || height <= 0) {
+            // awt.285=Width or Height of child Raster is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.285")); //$NON-NLS-1$
+        }
+
+        if (parentX < this.minX || parentX + width > this.minX + this.width) {
+            // awt.286=parentX disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.286")); //$NON-NLS-1$
+        }
+
+        if (parentY < this.minY || parentY + height > this.minY + this.height) {
+            // awt.287=parentY disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.287")); //$NON-NLS-1$
+        }
+
+        if ((long) parentX + width > Integer.MAX_VALUE) {
+            // awt.288=parentX + width results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.288")); //$NON-NLS-1$
+        }
+
+        if ((long) parentY + height > Integer.MAX_VALUE) {
+            // awt.289=parentY + height results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.289")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinX + width > Integer.MAX_VALUE) {
+            // awt.28A=childMinX + width results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.28A")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinY + height > Integer.MAX_VALUE) {
+            // awt.28B=childMinY + height results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.28B")); //$NON-NLS-1$
+        }
+
+        SampleModel childModel;
+
+        if (bandList == null) {
+            childModel = sampleModel;
+        } else {
+            childModel = sampleModel.createSubsetSampleModel(bandList);
+        }
+
+        int childTranslateX = childMinX - parentX;
+        int childTranslateY = childMinY - parentY;
+
+        return new Raster(childModel, dataBuffer, new Rectangle(childMinX,
+                childMinY, width, height), new Point(childTranslateX
+                + sampleModelTranslateX, childTranslateY
+                + sampleModelTranslateY), this);
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster() {
+        return new OrdinaryWritableRaster(sampleModel, new Point(0, 0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster and the specified size.
+     * 
+     * @param w the width of the new WritableRaster.
+     * @param h the height of the new WritableRaster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
+
+        return new OrdinaryWritableRaster(sm, new Point(0, 0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster and the specified size and location.
+     * 
+     * @param x the X coordinate of the new WritableRaster.
+     * @param y the Y coordinate of the new WritableRaster.
+     * @param w the width of the new WritableRaster.
+     * @param h the height of the new WritableRaster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(int x, int y, int w,
+            int h) {
+
+        WritableRaster raster = createCompatibleWritableRaster(w, h);
+
+        return raster.createWritableChild(0, 0, w, h, x, y, null);
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster and the specified rectangle which determines
+     * new WritableRaster's location and size.
+     * 
+     * @param rect the specified Rectangle.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
+        if (rect == null) {
+            // awt.28C=Rect is null
+            throw new NullPointerException(Messages.getString("awt.28C")); //$NON-NLS-1$
+        }
+
+        return createCompatibleWritableRaster(rect.x, rect.y, rect.width,
+                rect.height);
+    }
+
+    /**
+     * Creates the translated child of this Raster. The New Raster
+     * object is a reference to the this Raster with a 
+     * different location. 
+     *  
+     * @param childMinX the X coordinate of the new Raster.
+     * @param childMinY the Y coordinate of the new Raster.
+     * 
+     * @return the Raster.
+     */
+    public Raster createTranslatedChild(int childMinX, int childMinY) {
+        return createChild(minX, minY, width, height, childMinX, childMinY,
+                null);
+    }
+
+    /**
+     * Gets the bounds of this Raster as a rectangle.
+     * 
+     * @return the bounds of this Raster.
+     */
+    public Rectangle getBounds() {
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the DataBuffer associated with this Raster.
+     * 
+     * @return the DataBuffer associated with this Raster.
+     */
+    public DataBuffer getDataBuffer() {
+        return dataBuffer;
+    }
+
+    /**
+     * Gets the data elements which represent the pixel data of the specified 
+     * rectangle area as a primitive array. The following image data types
+     * are supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 
+     * or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param outData the resulting array.
+     * 
+     * @return the data elements of the specified area of this Raster.
+     */
+    public Object getDataElements(int x, int y, int w, int h, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, outData, dataBuffer);
+    }
+
+    /**
+     * Gets the data elements which represent the specified pixel of 
+     * this Raster as a primitive array. The following image data types
+     * are supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 
+     * or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param outData the resulting data.
+     * 
+     * @return the data elements of the specified pixel of this Raster.
+     */
+    public Object getDataElements(int x, int y, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, outData, dataBuffer);
+    }
+
+    /**
+     * Gets the height of this Raster.
+     * 
+     * @return the height of this Raster.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the minimum X coordinate of this Raster.
+     * 
+     * @return the minimum X coordinate of this Raster.
+     */
+    public final int getMinX() {
+        return minX;
+    }
+
+    /**
+     * Gets the minimum Y coordinate of this Raster.
+     * 
+     * @return the minimum Y coordinate of this Raster.
+     */
+    public final int getMinY() {
+        return minY;
+    }
+
+    /**
+     * Gets the number of bands in this Raster.
+     * 
+     * @return the number of bands in this Raster.
+     */
+    public final int getNumBands() {
+        return numBands;
+    }
+
+    /**
+     * Gets the number of data elements for one pixel.
+     * 
+     * @return the number of data elements for one pixel.
+     */
+    public final int getNumDataElements() {
+        return numDataElements;
+    }
+
+    /**
+     * Gets the parent Raster for this Raster object. 
+     * 
+     * @return the parent Raster for this Raster object.
+     */
+    public Raster getParent() {
+        return parent;
+    }
+
+    /**
+     * Gets a double array of samples for the specified pixel in this Raster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param dArray the double array where result array will be stored.
+     * 
+     * @return the double array of samples for the specified pixel in 
+     * this Raster.
+     */
+    public double[] getPixel(int x, int y, double dArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets a float array of samples for the specified pixel in this Raster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param fArray the float array where the result array will be stored.
+     * 
+     * @return the float array of samples for the specified pixel in 
+     * this Raster.
+     */
+    public float[] getPixel(int x, int y, float fArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets an int array of samples for the specified pixel in this Raster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param iArray the int array where the result array will be stored.
+     * 
+     * @return the int array of samples for the specified pixel in 
+     * this Raster.
+     */
+    public int[] getPixel(int x, int y, int iArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets an double array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param dArray the resulting array.
+     * 
+     * @return the double array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     */
+    public double[] getPixels(int x, int y, int w, int h, double dArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets an float array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param fArray the resulting array.
+     * 
+     * @return the float array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     */
+    public float[] getPixels(int x, int y, int w, int h, float fArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets an int array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of pixel's the area of pixels.
+     * @param h the height of pixel's the area of pixels.
+     * @param iArray the resulting array.
+     * 
+     * @return the int array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     */
+    public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified
+     * pixel as an int.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the sample for the specified band of the specified
+     * pixel as an int.
+     */
+    public int getSample(int x, int y, int b) {
+        return sampleModel.getSample(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, b, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified
+     * pixel as a double.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the sample for the specified band of the specified
+     * pixel as a double.
+     */
+    public double getSampleDouble(int x, int y, int b) {
+        return sampleModel.getSampleDouble(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, b, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified
+     * pixel as a float.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the sample for the specified band of the specified
+     * pixel as a float.
+     */
+    public float getSampleFloat(int x, int y, int b) {
+        return sampleModel.getSampleFloat(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, b, dataBuffer);
+    }
+
+    /**
+     * Gets the SampleModel associated with this Raster.
+     * 
+     * @return the SampleModel associated with this Raster.
+     */
+    public SampleModel getSampleModel() {
+        return sampleModel;
+    }
+
+    /**
+     * Gets the translation of the X coordinate from the SampleModel
+     * coordinate system to the Rasters's coordinate system.
+     * 
+     * @return the value of the translation of the X coordinate from 
+     * the SampleModel coordinate system to the Rasters's 
+     * coordinate system.
+     */
+    public final int getSampleModelTranslateX() {
+        return sampleModelTranslateX;
+    }
+
+    /**
+     * Gets the translation of the Y coordinate from the SampleModel
+     * coordinate system to the Rasters's coordinate system.
+     * 
+     * @return the value of the translation of the Y coordinate from 
+     * the SampleModel coordinate system to the Rasters's 
+     * coordinate system.
+
+     */
+    public final int getSampleModelTranslateY() {
+        return sampleModelTranslateY;
+    }
+
+    /**
+     * Gets the double array of samples for the specified band 
+     * of the specified rectangular area of pixels in this Raster
+     * as a double array.
+     * 
+     * @param x the X coordinate of the rectangular area of pixels. 
+     * @param y the Y coordinate of the rectangular area of pixels.
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param b the band.
+     * @param dArray the resulting double array.
+     * 
+     * @return the double array of samples for the specified band 
+     * of the specified rectangular area of pixels.
+     */
+    public double[] getSamples(int x, int y, int w, int h, int b,
+            double dArray[]) {
+
+        return sampleModel.getSamples(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets the float array of samples for the specified band 
+     * of the specified rectangular area of pixels in this Raster
+     * as a float array.
+     * 
+     * @param x the X coordinate of the rectangular area of pixels. 
+     * @param y the Y coordinate of the rectangular area of pixels.
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param b the band.
+     * @param fArray the resulting float array.
+     * 
+     * @return the float array of samples for the specified band 
+     * of the specified rectangular area of pixels.
+     */
+    public float[] getSamples(int x, int y, int w, int h, int b, float fArray[]) {
+
+        return sampleModel.getSamples(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets the int array of samples for the specified band 
+     * of the specified rectangular area of pixels in this Raster
+     * as a int array.
+     * 
+     * @param x the X coordinate of the rectangular area of pixels. 
+     * @param y the Y coordinate of the rectangular area of pixels.
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param b the band.
+     * @param iArray the resulting int array.
+     * 
+     * @return the int array of samples for the specified band 
+     * of the specified rectangular area of pixels.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[]) {
+        return sampleModel.getSamples(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets the transfer type for pixels of this Raster.
+     * @see SampleModel#getTransferType()
+     * 
+     * @return the transfer type for pixels of this Raster.
+     */
+    public final int getTransferType() {
+        return sampleModel.getTransferType();
+    }
+
+    /**
+     * Gets the width of this Raster.
+     * 
+     * @return the width of this Raster.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Validate data buffer.
+     * 
+     * @param dataBuffer the data buffer
+     * @param w the w
+     * @param h the h
+     * @param scanlineStride the scanline stride
+     */
+    private static void validateDataBuffer(final DataBuffer dataBuffer, final int w,
+            final int h, final int scanlineStride) {
+        if (dataBuffer.getSize() < (scanlineStride * (h - 1) + w - 1)) {
+            // awt.298=dataBuffer is too small
+            throw new RasterFormatException(Messages.getString("awt.298")); //$NON-NLS-1$
+        }
+    }
+}
+
+
diff --git a/awt/java/awt/image/RasterFormatException.java b/awt/java/awt/image/RasterFormatException.java
new file mode 100644
index 0000000..8577dad
--- /dev/null
+++ b/awt/java/awt/image/RasterFormatException.java
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * The RasterFormatException class represents the exception 
+ * that is thrown when there's an invalid layout
+ * in the Raster.
+ */
+public class RasterFormatException extends RuntimeException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 96598996116164315L;
+
+    /**
+     * Instantiates a new RasterFormatException with the 
+     * specified detail message.
+     * 
+     * @param s the detail message.
+     */
+    public RasterFormatException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/image/RasterOp.java b/awt/java/awt/image/RasterOp.java
new file mode 100644
index 0000000..e8933ee
--- /dev/null
+++ b/awt/java/awt/image/RasterOp.java
@@ -0,0 +1,83 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The RasterOp interface provides methods for performing transformations
+ * from source data to destination data for Raster objects. The source and 
+ * destination objects should contain the appropriate number of bands for 
+ * the particular classes which implement this interface.
+ */
+public interface RasterOp {
+    
+    /**
+     * Creates a destination WritableRaster with the specified Raster;
+     * this destination image data is empty and has the correct size 
+     * and number of bands.   
+     * 
+     * @param src the source Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleDestRaster(Raster src);
+
+    /**
+     * Performs a filter operation on the source Raster and stores the resulting
+     * image data to the destination WritableRaster.
+     * 
+     * @param src the source Raster.
+     * @param dst the destination WritableRaster, where the result is stored.
+     * 
+     * @return the filtered WritableRaster.
+     */
+    public WritableRaster filter(Raster src, WritableRaster dst);
+
+    /**
+     * Gets the bounds of the filtered Raster.
+     * 
+     * @param src the source Raster to be filtered.
+     * 
+     * @return the rectangle bounds of the filtered Raster.
+     */
+    public Rectangle2D getBounds2D(Raster src);
+
+    /**
+     * Gets the point of the destination image which corresponds
+     * to the specified point in the source raster.
+     * 
+     * @param srcPoint the point of the source raster.
+     * @param dstPoint the point where the result will be stored.
+     * 
+     * @return the destination point.
+     */
+    public Point2D getPoint2D(Point2D srcPoint, Point2D dstPoint);
+
+    /**
+     * Gets the RenderingHints of the RasterOp.
+     * 
+     * @return the RenderingHints of the RasterOp.
+     */
+    public RenderingHints getRenderingHints();
+}
diff --git a/awt/java/awt/image/RenderedImage.java b/awt/java/awt/image/RenderedImage.java
new file mode 100644
index 0000000..db3a4c8
--- /dev/null
+++ b/awt/java/awt/image/RenderedImage.java
@@ -0,0 +1,198 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Rectangle;
+import java.util.Vector;
+
+/**
+ * The RenderedImage interface should be implemented by all objects which 
+ * contains image data. The image data is represented as a single tile or 
+ * an array of tiles.
+ */
+public interface RenderedImage {
+
+    /**
+     * Gets the property with the specified name from the property set 
+     * of this RenderedImage.
+     * 
+     * @param name the property's name.
+     * 
+     * @return the property value corresponded to this property's name.
+     */
+    public Object getProperty(String name);
+
+    /**
+     * Copies the region of this RenderedImage to the specified 
+     * WritableRaster. The bounds of the region are the bounds of the 
+     * WritableRaster.
+     * 
+     * @param raster the WritableRaster.
+     * 
+     * @return the created WritableRaster.
+     */
+    public WritableRaster copyData(WritableRaster raster);
+
+    /**
+     * Gets the image data of the image's region as one tile.
+     * 
+     * @param rect the rectangular region of RenderedImage.
+     * 
+     * @return the image data of the image's region as one tile.
+     */
+    public Raster getData(Rectangle rect);
+
+    /**
+     * Gets all RenderedImage objects which are the source of this
+     * RenderedImage object.
+     * 
+     * @return a Vector of RenderedImage objects which are the source 
+     * of this RenderedImage object or null, if there is no information
+     * about them.
+     */
+    public Vector<RenderedImage> getSources();
+
+    /**
+     * Gets the set of all property names for this RenderedImage.
+     * 
+     * @return the array of all property names for this RenderedImage.
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Gets the SampleModel of this RenderedImage.
+     * 
+     * @return the SampleModel of this RenderedImage.
+     */
+    public SampleModel getSampleModel();
+
+    /**
+     * Gets the tile corresponded to the specified indices in the tile
+     * array.
+     * 
+     * @param tileX the X index of the tile.  
+     * @param tileY the Y index of the tile. 
+     * 
+     * @return the tile corresponded to the specified indices in the tile
+     * array.
+     */
+    public Raster getTile(int tileX, int tileY);
+
+    /**
+     * Gets the image data of this image as one tile.
+     * 
+     * @return the image data of this image as one tile.
+     */
+    public Raster getData();
+
+    /**
+     * Gets the ColorModel of this RenderedImage.
+     * 
+     * @return the ColorModel of this RenderedImage.
+     */
+    public ColorModel getColorModel();
+
+    /**
+     * Gets the width of the RenderedImage.
+     * 
+     * @return the width of the RenderedImage.
+     */
+    public int getWidth();
+
+    /**
+     * Gets the tile width.
+     * 
+     * @return the tile width in pixels.
+     */
+    public int getTileWidth();
+
+    /**
+     * Gets the tile height.
+     * 
+     * @return the tile height in pixels.
+     */
+    public int getTileHeight();
+
+    /**
+     * Gets the Y offset of the tile grid.
+     * 
+     * @return the Y offset of the tile grid.
+     */
+    public int getTileGridYOffset();
+
+    /**
+     * Gets the X offset of the tile grid.
+     * 
+     * @return the X offset of the tile grid.
+     */
+    public int getTileGridXOffset();
+
+    /**
+     * Gets the number of tiles along Y direction.
+     * 
+     * @return the number of tiles along Y direction.
+     */
+    public int getNumYTiles();
+
+    /**
+     * Gets the number of tiles along X direction.
+     * 
+     * @return the number of tiles along X direction.
+     */
+    public int getNumXTiles();
+
+    /**
+     * Gets the minimum Y coordinate of this RenderedImage.
+     * 
+     * @return the minimum Y coordinate of this RenderedImage.
+     */
+    public int getMinY();
+
+    /**
+     * Gets the minimum X coordinate of this RenderedImage.
+     * 
+     * @return the minimum X coordinate of this RenderedImage.
+     */
+    public int getMinX();
+
+    /**
+     * Gets the minimum tile's index along the Y direction.
+     * 
+     * @return the minimum tile's index along the Y direction.
+     */
+    public int getMinTileY();
+
+    /**
+     * Gets the minimum tile's index along the X direction.
+     * 
+     * @return the minimum tile's index along the X direction.
+     */
+    public int getMinTileX();
+
+    /**
+     * Gets the height of the RenderedImage.
+     * 
+     * @return the height of the RenderedImage.
+     */
+    public int getHeight();
+
+}
+
diff --git a/awt/java/awt/image/ReplicateScaleFilter.java b/awt/java/awt/image/ReplicateScaleFilter.java
new file mode 100644
index 0000000..9298125
--- /dev/null
+++ b/awt/java/awt/image/ReplicateScaleFilter.java
@@ -0,0 +1,213 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * The ReplicateScaleFilter class scales an source image 
+ * by replicating rows and columns of pixels to scale up or 
+ * omitting rows and columns of pixels to scale down.
+ */
+public class ReplicateScaleFilter extends ImageFilter {
+
+    /** The width of a source image. */
+    protected int srcWidth;
+
+    /** The height of a source image. */
+    protected int srcHeight;
+
+    /** The width of a destination image. */
+    protected int destWidth;
+
+    /** The height of a destination image. */
+    protected int destHeight;
+
+    /** The int array of source rows. */
+    protected int[] srcrows;
+
+    /** The int array of source columns. */
+    protected int[] srccols;
+
+    /** 
+     * An Object (byte array with a destination width) provides 
+     * a row of pixel data to the ImageConsumer. 
+     */
+    protected Object outpixbuf;
+
+    /**
+     * Instantiates a new ReplicateScaleFilter that filters 
+     * the image with the specified width and height.
+     * 
+     * @param width the width of scaled image.
+     * @param height the height of scaled image.
+     */
+    public ReplicateScaleFilter(int width, int height) {
+        if(width == 0 || height == 0) {
+            // awt.234=Width or Height equals zero
+            throw new IllegalArgumentException(Messages.getString("awt.234")); //$NON-NLS-1$
+        }
+
+        this.destWidth = width;
+        this.destHeight = height;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if(props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>) props.clone();
+        }
+        String propName = "Rescale Filters"; //$NON-NLS-1$
+        String prop = "destWidth=" + destWidth + "; " +  //$NON-NLS-1$ //$NON-NLS-2$
+        "destHeight=" + destHeight; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if(o != null){
+            if(o instanceof String){
+                prop = (String)o + "; " + prop; //$NON-NLS-1$
+            }else{
+                prop =  o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+     }
+
+    // setPixels methods produce pixels according to Java API Spacification
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, 
+            ColorModel model, int[] pixels, int off, int scansize) {
+        
+        if(srccols == null) {
+            initArrays();
+        }
+        int buff[];
+        if(outpixbuf == null || !(outpixbuf instanceof int[])){
+            buff = new int[destWidth];
+            outpixbuf = buff;
+        }else{
+            buff = (int[])outpixbuf;
+        }
+
+        int wa = (srcWidth - 1) >>> 1;
+        int ha = (srcHeight - 1) >>> 1;
+        int dstX = (x * destWidth + wa) / srcWidth;
+        int dstY = (y * destHeight + ha) / srcHeight;
+
+        int sx, sy, dx, dy;
+        dy = dstY;
+        while((dy < destHeight) && ((sy = srcrows[dy]) < y + h)){
+            dx = dstX;
+            int srcOff = off + (sy - y) * scansize;
+            while((dx < destWidth) && ((sx = srccols[dx]) < x + w)){
+                buff[dx] = pixels[srcOff + (sx - x)];
+                dx++;
+            }
+
+            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, 
+                    dstX, destWidth);
+            dy++;
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, 
+            ColorModel model, byte[] pixels, int off, int scansize) {
+        
+        if(srccols == null) {
+            initArrays();
+        }
+        byte buff[];
+        if(outpixbuf == null || !(outpixbuf instanceof byte[])){
+            buff = new byte[destWidth];
+            outpixbuf = buff;
+        }else{
+            buff = (byte[])outpixbuf;
+        }
+
+        int wa = (srcWidth - 1) >>> 1;
+        int ha = (srcHeight - 1) >>> 1;
+        int dstX = (x * destWidth + wa) / srcWidth;
+        int dstY = (y * destHeight + ha) / srcHeight;
+
+        int sx, sy, dx, dy;
+        dy = dstY;
+        while((dy < destHeight) && ((sy = srcrows[dy]) < y + h)){
+            dx = dstX;
+            int srcOff = off + (sy - y) * scansize;
+            while((dx < destWidth) && ((sx = srccols[dx]) < x + w)){
+                buff[dx] = pixels[srcOff + (sx - x)];
+                dx++;
+            }
+
+            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, 
+                    dstX, destWidth);
+            dy++;
+        }
+    }
+
+    @Override
+    public void setDimensions(int w, int h) {
+        srcWidth = w;
+        srcHeight = h;
+
+        if(destWidth < 0 && destHeight < 0){
+            destWidth = srcWidth;
+            destHeight = srcHeight;
+        }else if(destWidth < 0){
+            destWidth = destHeight * srcWidth / srcHeight;
+        }else if(destHeight < 0){
+            destHeight = destWidth * srcHeight / srcWidth;
+        }
+        consumer.setDimensions(destWidth, destHeight);
+    }
+
+    /**
+     * Initialization of srccols and srcrows arrays.
+     */
+    private void initArrays(){
+        if ((destWidth < 0) || (destHeight < 0)) {
+            throw new IndexOutOfBoundsException();
+        }
+        
+        srccols = new int[destWidth];
+        int ca = srcWidth >>> 1;
+        for(int i = 0; i < destWidth; i++){
+            srccols[i] = (i * srcWidth + ca) / destWidth;
+        }
+
+        srcrows = new int[destHeight];
+        int ra = srcHeight >>> 1;
+        for(int i = 0; i < destHeight; i++){
+            srcrows[i] = (i * srcHeight + ra) / destHeight;
+        }
+    }
+
+}
+
+
diff --git a/awt/java/awt/image/RescaleOp.java b/awt/java/awt/image/RescaleOp.java
new file mode 100644
index 0000000..0e96031
--- /dev/null
+++ b/awt/java/awt/image/RescaleOp.java
@@ -0,0 +1,659 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 6, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.*;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RescaleOp performs rescaling of the source image data
+ * by multiplying the pixel values with a scale factor 
+ * and then adding an offset.
+ */
+public class RescaleOp implements BufferedImageOp, RasterOp {
+    
+    /** The scale factors. */
+    private float scaleFactors[];
+    
+    /** The offsets. */
+    private float offsets[];
+    
+    /** The hints. */
+    private RenderingHints hints;
+
+    static {
+        // TODO
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new RescaleOp object with the specified 
+     * scale factors and offsets.
+     * 
+     * @param scaleFactors the array of scale factor values.
+     * @param offsets the array of offset values.
+     * @param hints the RenderingHints or null.
+     */
+    public RescaleOp(float[] scaleFactors, float[] offsets, RenderingHints hints) {
+        int numFactors = Math.min(scaleFactors.length, offsets.length);
+
+        this.scaleFactors = new float[numFactors];
+        this.offsets = new float[numFactors];
+
+        System.arraycopy(scaleFactors, 0, this.scaleFactors, 0, numFactors);
+        System.arraycopy(offsets, 0, this.offsets, 0, numFactors);
+
+        this.hints = hints;
+    }
+
+    /**
+     * Instantiates a new RescaleOp object with the specified 
+     * scale factor and offset.
+     * 
+     * @param scaleFactor the scale factor.
+     * @param offset the offset.
+     * @param hints the RenderingHints or null.
+     */
+    public RescaleOp(float scaleFactor, float offset, RenderingHints hints) {
+        scaleFactors = new float[1];
+        offsets = new float[1];
+
+        scaleFactors[0] = scaleFactor;
+        offsets[0] = offset;
+
+        this.hints = hints;
+    }
+
+    /**
+     * Gets the number of scaling factors.
+     * 
+     * @return the number of scaling factors.
+     */
+    public final int getNumFactors() {
+        return scaleFactors.length;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    /**
+     * Gets the scale factors of this RescaleOp.
+     * 
+     * @param scaleFactors the desired scale factors array will be copied 
+     * to this array.
+     * 
+     * @return the scale factors array.
+     */
+    public final float[] getScaleFactors(float[] scaleFactors) {
+        if (scaleFactors == null) {
+            scaleFactors = new float[this.scaleFactors.length];
+        }
+
+        int minLength = Math.min(scaleFactors.length, this.scaleFactors.length);
+        System.arraycopy(this.scaleFactors, 0, scaleFactors, 0, minLength);
+        return scaleFactors;
+    }
+
+    /**
+     * Gets the offsets array of this RescaleOp.
+     * 
+     * @param offsets the desired offsets array will be copied to this array.
+     * 
+     * @return the offsets array of this RescaleOp.
+     */
+    public final float[] getOffsets(float[] offsets) {
+        if (offsets == null) {
+            offsets = new float[this.offsets.length];
+        }
+
+        int minLength = Math.min(offsets.length, this.offsets.length);
+        System.arraycopy(this.offsets, 0, offsets, 0, minLength);
+        return offsets;
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+        }
+
+        if (dstCM instanceof IndexColorModel) {
+            dstCM = ColorModel.getRGBdefault();
+        }
+
+        WritableRaster r =
+                dstCM.isCompatibleSampleModel(src.getSampleModel()) ?
+                src.getRaster().createCompatibleWritableRaster(src.getWidth(), src.getHeight()) :
+                dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(
+                dstCM,
+                r,
+                dstCM.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else {
+            if (src.getNumBands() != dst.getNumBands()) {
+                // awt.21D=Number of src bands ({0}) does not match number of dst bands ({1})
+                throw new IllegalArgumentException(Messages.getString("awt.21D", //$NON-NLS-1$
+                        src.getNumBands(), dst.getNumBands()));
+            }
+        }
+
+        if (
+                this.scaleFactors.length != 1 &&
+                this.scaleFactors.length != src.getNumBands()
+        ) {
+            // awt.21E=Number of scaling constants is not equal to the number of bands
+            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+        }
+
+        // TODO
+        //if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM, false) != 0)
+            if (slowFilter(src, dst, false) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
+        SampleModel sm = src.getSampleModel();
+
+        int numBands = src.getNumBands();
+        int srcHeight = src.getHeight();
+        int srcWidth = src.getWidth();
+
+        int srcMinX = src.getMinX();
+        int srcMinY = src.getMinY();
+        int dstMinX = dst.getMinX();
+        int dstMinY = dst.getMinY();
+
+        int[] maxValues = new int[numBands];
+        int[] masks = new int[numBands];
+        int[] sampleSizes = sm.getSampleSize();
+
+        for (int i=0; i < numBands; i++){
+            maxValues[i] = (1 << sampleSizes[i]) - 1;
+            masks[i] = ~(maxValues[i]);
+        }
+
+        // Processing bounds
+        float[] pixels = null;
+        pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
+
+        // Cycle over pixels to be calculated
+        if (skipAlpha) { // Always suppose that alpha channel is the last band
+            if (scaleFactors.length > 1) {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands-1; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+
+                    i++;
+                }
+            } else {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands-1; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+
+                    i++;
+                }
+            }
+        } else {
+            if (scaleFactors.length > 1) {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+                }
+            } else {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, pixels);
+
+        return 0;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        ColorModel srcCM = src.getColorModel();
+
+        if (srcCM instanceof IndexColorModel) {
+            // awt.220=Source should not have IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
+        }
+
+        // Check if the number of scaling factors matches the number of bands
+        int nComponents = srcCM.getNumComponents();
+        boolean skipAlpha;
+        if (srcCM.hasAlpha()) {
+            if (scaleFactors.length == 1 || scaleFactors.length == nComponents-1) {
+                skipAlpha = true;
+            } else if (scaleFactors.length == nComponents) {
+                skipAlpha = false;
+            } else {
+                // awt.21E=Number of scaling constants is not equal to the number of bands
+                throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+            }
+        } else if (scaleFactors.length == 1 || scaleFactors.length == nComponents) {
+            skipAlpha = false;
+        } else {
+            // awt.21E=Number of scaling constants is not equal to the number of bands
+            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+        }
+
+        BufferedImage finalDst = null;
+        if (dst == null) {
+            finalDst = dst;
+            dst = createCompatibleDestImage(src, srcCM);
+        } else if (!srcCM.equals(dst.getColorModel())) {
+            // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB as same
+            if (
+                    !((src.getType() == BufferedImage.TYPE_INT_RGB ||
+                       src.getType() == BufferedImage.TYPE_INT_ARGB) &&
+                      (dst.getType() == BufferedImage.TYPE_INT_RGB ||
+                       dst.getType() == BufferedImage.TYPE_INT_ARGB))
+            ) {
+                finalDst = dst;
+                dst = createCompatibleDestImage(src, srcCM);
+            }
+        }
+
+        // TODO
+        //if (ippFilter(src.getRaster(), dst.getRaster(), src.getType(), skipAlpha) != 0)
+            if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    // Don't forget to pass allocated arrays for levels and values, size should be numBands*4
+    /**
+     * Creates the levels.
+     * 
+     * @param sm the sm
+     * @param numBands the num bands
+     * @param skipAlpha the skip alpha
+     * @param levels the levels
+     * @param values the values
+     * @param channelsOrder the channels order
+     */
+    private final void createLevels(
+            SampleModel sm, int numBands, boolean skipAlpha,
+            int levels[], int values[], int channelsOrder[]
+    ) {
+        // Suppose same sample size for all channels, otherwise use slow filter
+        int maxValue = (1 << sm.getSampleSize(0)) - 1;
+
+        // For simplicity introduce these arrays
+        float extScaleFactors[] = new float[numBands];
+        float extOffsets[] = new float[numBands];
+
+        if (scaleFactors.length != 1) {
+            System.arraycopy(scaleFactors, 0, extScaleFactors, 0, scaleFactors.length);
+            System.arraycopy(offsets, 0, extOffsets, 0, scaleFactors.length);
+        } else {
+            for (int i = 0; i < numBands; i++) {
+                extScaleFactors[i] = scaleFactors[0];
+                extOffsets[i] = offsets[0];
+            }
+        }
+
+        if (skipAlpha) {
+            extScaleFactors[numBands-1] = 1;
+            extOffsets[numBands-1] = 0;
+        }
+
+        // Create a levels
+        for (int i=0; i<numBands; i++) {
+            if (extScaleFactors[i] == 0) {
+                levels[i*4] = 0;
+                levels[i*4+1] = 0;
+                levels[i*4+2] = maxValue+1;
+                levels[i*4+3] = maxValue+1;
+            }
+
+            float minLevel = -extOffsets[i] / extScaleFactors[i];
+            float maxLevel = (maxValue - extOffsets[i]) / extScaleFactors[i];
+
+            if (minLevel < 0) {
+                minLevel = 0;
+            } else if (minLevel > maxValue){
+                minLevel = maxValue;
+            }
+
+            if (maxLevel < 0) {
+                maxLevel = 0;
+            } else if (maxLevel > maxValue){
+                maxLevel = maxValue;
+            }
+
+            levels[i*4] = 0;
+            if (minLevel > maxLevel) {
+                levels[i*4+1] = (int) maxLevel;
+                levels[i*4+2] = (int) minLevel;
+            } else {
+                levels[i*4+1] = (int) minLevel;
+                levels[i*4+2] = (int) maxLevel;
+            }
+            levels[i*4+3] = maxValue+1;
+
+            // Fill values
+            for (int k=0; k<4; k++) {
+                int idx = i*4+k;
+                values[idx] = (int) (extScaleFactors[i] * levels[idx] + extOffsets[i]);
+                if (values[idx] < 0) {
+                    values[idx] = 0;
+                } else if (values[idx] > maxValue){
+                    values[idx] = maxValue;
+                }
+            }
+        }
+
+        // Reorder data if channels are stored in different order
+        if (channelsOrder != null) {
+            int len = numBands*4;
+            int savedLevels[] = new int[len];
+            int savedValues[] = new int[len];
+            System.arraycopy(levels, 0, savedLevels, 0, len);
+            System.arraycopy(values, 0, savedValues, 0, len);
+            for (int i = 0; i < channelsOrder.length; i++) {
+                System.arraycopy(savedLevels, i*4, levels, channelsOrder[i]*4, 4);
+                System.arraycopy(savedValues, i*4, values, channelsOrder[i]*4, 4);
+            }
+        }
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private final int ippFilter(
+            Raster src, WritableRaster dst,
+            int imageType, boolean skipAlpha
+    ) {
+        int res;
+
+        int srcStride, dstStride;
+        int channels;
+        int offsets[] = null;
+        int channelsOrder[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_INT_RGB: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                channelsOrder = new int[] {2, 1, 0, 3};
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                channelsOrder = new int[] {2, 1, 0};
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst, skipAlpha);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1, 3 and 4 channels
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();
+
+                    channelsOrder = ((ComponentSampleModel) srcSM).getBandOffsets();
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                     // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (
+                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
+                            !(channels == 3 || channels == 4)
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst, skipAlpha);
+                        }
+                    }
+
+                    channelsOrder = new int[channels];
+                    int bitOffsets[] = sppsm1.getBitOffsets();
+                    for (int i=0; i<channels; i++) {
+                        channelsOrder[i] = bitOffsets[i] / 8;
+                    }
+
+                    if (channels == 3) { // Don't skip channel now, could be optimized
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst, skipAlpha);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        int levels[] = new int[4*channels];
+        int values[] = new int[4*channels];
+
+        createLevels(src.getSampleModel(), channels, skipAlpha, levels, values, channelsOrder);
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        res = LookupOp.ippLUT(
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            levels, values,
+            channels, offsets,
+            true
+        );
+
+        return res;
+    }
+}
diff --git a/awt/java/awt/image/SampleModel.java b/awt/java/awt/image/SampleModel.java
new file mode 100644
index 0000000..44059a0
--- /dev/null
+++ b/awt/java/awt/image/SampleModel.java
@@ -0,0 +1,1053 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The SampleModel class is abstract class for retrieving pixel's samples
+ * in the data of an image. Each pixel contains several samples. A 
+ * sample is the set of values of the bands for single pixel. 
+ * For example, each pixel in the RGB model contains three samples 
+ * and there are three corresponding bands in the image 
+ * data of such pixels representing red, green and blue components.
+ * <p> 
+ * The image data is represented as a Raster with a DataBuffer 
+ * and a SampleModel. The SampleModel allows access to the samples in the 
+ * DataBuffer. 
+ */
+public abstract class SampleModel {
+
+    /** The width of the image data which this SampleModel describes. */
+    protected int width;
+
+    /** The height of the image data which this SampleModel describes. */
+    protected int height;
+
+    /** The number of bands of image data which this SampleModel describes. */
+    protected int numBands;
+
+    /** The data type of the image data which this SampleModel describes. */
+    protected int dataType;
+
+    /**
+     * Instantiates a new SampleModel with the specified data type,
+     * width, height and number of bands.
+     * 
+     * @param dataType the data type of the image data.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param numBands the number of bands of the image data.
+     */
+    public SampleModel(int dataType, int w, int h, int numBands) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        double squre = ((double) w) * ((double) h);
+        if (squre >= Integer.MAX_VALUE) {
+            // awt.22F=The product of w and h is greater than Integer.MAX_VALUE
+            throw new IllegalArgumentException(Messages.getString("awt.22F")); //$NON-NLS-1$
+        }
+
+        if (dataType < DataBuffer.TYPE_BYTE ||
+                dataType > DataBuffer.TYPE_DOUBLE &&
+                dataType != DataBuffer.TYPE_UNDEFINED) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (numBands < 1) {
+            // awt.231=Number of bands must be more then 0
+            throw new IllegalArgumentException(Messages.getString("awt.231")); //$NON-NLS-1$
+        }
+
+        this.dataType = dataType;
+        this.width = w;
+        this.height = h;
+        this.numBands = numBands;
+
+    }
+
+    /**
+     * Gets the data array for the specified pixel of the specified 
+     * DataBuffer with one of the following types: 
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param obj the Object is a data where the result will be stored.
+     * @param data the image data.
+     * 
+     * @return the data array for the specified pixel of the specified 
+     * DataBuffer.
+     */
+    public abstract Object getDataElements(int x, int y, Object obj,
+            DataBuffer data);
+
+    /**
+     * Gets the array of pixel data for the specified rectangular 
+     * area of pixels of the specified DataBuffer with one of 
+     * the following types: 
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * 
+     * @param x the X coordinate of the rectangular pixel area.
+     * @param y the Y coordinate of the rectangular pixel area.
+     * @param w the width of the rectangular pixel area.
+     * @param h the height of the rectangular pixel area.
+     * @param obj the Object is an array with the primitive type,
+     * where the result array will be stored.
+     * @param data the image data.
+     * 
+     * @return the array of pixel data for the specified rectangular 
+     * area of pixels of the specified DataBuffer object.
+     */
+    public Object getDataElements(int x, int y, int w, int h, Object obj,
+            DataBuffer data) {
+        int numDataElements = getNumDataElements();
+        int idx = 0;
+
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            byte bbuf[] = null;
+
+            if (obj == null) {
+                bdata = new byte[numDataElements * w * h];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    bbuf = (byte[]) getDataElements(j, i, bbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        bdata[idx++] = bbuf[n];
+                    }
+                }
+            }
+            obj = bdata;
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            short sbuf[] = null;
+
+            if (obj == null) {
+                sdata = new short[numDataElements * w * h];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    sbuf = (short[]) getDataElements(j, i, sbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        sdata[idx++] = sbuf[n];
+                    }
+                }
+            }
+            obj = sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            int ibuf[] = null;
+
+            if (obj == null) {
+                idata = new int[numDataElements * w * h];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    ibuf = (int[]) getDataElements(j, i, ibuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        idata[idx++] = ibuf[n];
+                    }
+                }
+            }
+            obj = idata;
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fdata[];
+            float fbuf[] = null;
+
+            if (obj == null) {
+                fdata = new float[numDataElements * w * h];
+            } else {
+                fdata = (float[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    fbuf = (float[]) getDataElements(j, i, fbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        fdata[idx++] = fbuf[n];
+                    }
+                }
+            }
+            obj = fdata;
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double ddata[];
+            double dbuf[] = null;
+
+            if (obj == null) {
+                ddata = new double[numDataElements * w * h];
+            } else {
+                ddata = (double[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    dbuf = (double[]) getDataElements(j, i, dbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        ddata[idx++] = dbuf[n];
+                    }
+                }
+            }
+            obj = ddata;
+            break;
+
+        }
+
+        return obj;
+    }
+
+    /**
+     * Sets the data for a single pixel in the specified DataBuffer
+     * from a primitive array with one of the following types: 
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param obj the Object - the array of primitive pixel data
+     * to be set. 
+     * @param data the image data.
+     */
+    public abstract void setDataElements(int x, int y, Object obj,
+            DataBuffer data);
+
+    /**
+     * Sets the data elements for a rectangular area of pixels in 
+     * the specified DataBuffer from a primitive array with one of 
+     * the following types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. 
+     * 
+     * @param x the X coordinate of the specified rectangular area.
+     * @param y the Y coordinate of the specified rectangular area.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle.
+     * @param obj the Object - the array of primitive pixel data
+     * to be set. 
+     * @param data the image data.
+     */
+    public void setDataElements(int x, int y, int w, int h, Object obj,
+            DataBuffer data) {
+        int numDataElements = getNumDataElements();
+        int idx = 0;
+
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bbuf[] = new byte[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        bbuf[n] = ((byte[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, bbuf, data);
+                }
+            }
+
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sbuf[] = new short[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        sbuf[n] = ((short[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, sbuf, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ibuf[] = new int[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        ibuf[n] = ((int[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, ibuf, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fbuf[] = new float[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        fbuf[n] = ((float[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, fbuf, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double dbuf[] = new double[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        dbuf[n] = ((double[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, dbuf, data);
+                }
+            }
+            break;
+
+        }
+    }
+
+    /**
+     * Creates a new SampleModel with the specified bands of 
+     * this SampleModel.
+     * 
+     * @param bands the array of bands from this SampleModel.
+     * 
+     * @return the SampleModel with the specified bands of 
+     * this SampleModel.
+     */
+    public abstract SampleModel createSubsetSampleModel(int bands[]);
+
+    /**
+     * Creates the SampleModel which has the same data as in 
+     * this SampleModel with a different width and height.
+     * 
+     * @param a0 the width of the image data.
+     * @param a1 the height of the image data.
+     * 
+     * @return the SampleModel which has the same data as in 
+     * this SampleModel with a different width and height.
+     */
+    public abstract SampleModel createCompatibleSampleModel(int a0, int a1);
+
+    /**
+     * Gets the samples of the specified pixel as a int array.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param iArray the int array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the int array with the samples of the specified pixel.
+
+     */
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a int array of samples. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param iArray the int array.
+     * @param data the image data.
+     */
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the samples of the specified pixel as a float array.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param fArray the float array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the float array with the samples of the specified pixel.
+     */
+    public float[] getPixel(int x, int y, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        float pixel[];
+
+        if (fArray == null) {
+            pixel = new float[numBands];
+        } else {
+            pixel = fArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSampleFloat(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a float array of samples. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param fArray the float array.
+     * @param data the image data.
+     */
+    public void setPixel(int x, int y, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, fArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the samples of the specified pixel as a double array.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param dArray the double array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the double array with the samples of the specified pixel.
+     */
+    public double[] getPixel(int x, int y, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        double pixel[];
+
+        if (dArray == null) {
+            pixel = new double[numBands];
+        } else {
+            pixel = dArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSampleDouble(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a double array of samples. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param dArray the double array.
+     * @param data the image data.
+     */
+    public void setPixel(int x, int y, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, dArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the sample of a specified band for the specified pixel
+     * as an int.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param b the specified band.
+     * @param data the image data.
+     * 
+     * @return the sample of a specified band for the specified pixel.
+     */
+    public abstract int getSample(int x, int y, int b, DataBuffer data);
+
+    /**
+     * Gets the sample of a specified band for the specified pixel
+     * as a float.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param b the specified band.
+     * @param data the image data.
+     * 
+     * @return the sample of a specified band for the specified pixel.
+
+     */
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        return getSample(x, y, b, data);
+    }
+
+    /**
+     * Gets the sample of a specified band for the specified pixel
+     * as a double.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param b the specified band.
+     * @param data the image data.
+     * 
+     * @return the sample of a specified band for the specified pixel.
+     */
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        return getSample(x, y, b, data);
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels
+     * as a int array.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param iArray the int array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the int array with the samples of the specified 
+     * rectangular area of pixels.
+     */
+    public int[] getPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixels[];
+        int idx = 0;
+
+        if (iArray == null) {
+            pixels = new int[w * h * numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the DataBuffer
+     * from an int array. 
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param iArray the int array.
+     * @param data the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels 
+     * as a float array.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param fArray the float array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the float array with the samples of the specified 
+     * rectangular area of pixels.
+     */
+    public float[] getPixels(int x, int y, int w, int h, float fArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        float pixels[];
+        int idx = 0;
+
+        if (fArray == null) {
+            pixels = new float[w * h * numBands];
+        } else {
+            pixels = fArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSampleFloat(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the DataBuffer
+     * from a float array. 
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param fArray the float array.
+     * @param data the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, float fArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, fArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels 
+     * as a double array.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param dArray the double array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the double array with the samples of the specified 
+     * rectangular area of pixels.
+     */
+    public double[] getPixels(int x, int y, int w, int h, double dArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        double pixels[];
+        int idx = 0;
+
+        if (dArray == null) {
+            pixels = new double[w * h * numBands];
+        } else {
+            pixels = dArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSampleDouble(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the DataBuffer
+     * from a double array. 
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param dArray the double array.
+     * @param data the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, double dArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, dArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel
+     * in the DataBuffer as int value.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample as an int value.
+     * @param data the image data.
+     */
+    public abstract void setSample(int x, int y, int b, int s, DataBuffer data);
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular
+     * area of pixels as a int array.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param iArray the int array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the samples of a specified band for a specified rectangular
+     * area of pixels.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an int array in the specified band for 
+     * the specified rectangle of pixels.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param iArray the int array.
+     * @param data the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular
+     * area of pixels as a float array.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param fArray the float array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the samples of a specified band for a specified rectangular
+     * area of pixels.
+     */
+    public float[] getSamples(int x, int y, int w, int h, int b,
+            float fArray[], DataBuffer data) {
+        float samples[];
+        int idx = 0;
+
+        if (fArray == null) {
+            samples = new float[w * h];
+        } else {
+            samples = fArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSampleFloat(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an float array in the specified band for 
+     * the specified rectangle of pixels.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param fArray the float array
+     * @param data the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, float fArray[],
+            DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, fArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular
+     * area of pixels as a double array.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param dArray the double array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the samples of a specified band for a specified rectangular
+     * area of pixels.
+     */
+    public double[] getSamples(int x, int y, int w, int h, int b,
+            double dArray[], DataBuffer data) {
+        double samples[];
+        int idx = 0;
+
+        if (dArray == null) {
+            samples = new double[w * h];
+        } else {
+            samples = dArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSampleDouble(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an double array in the specified band for 
+     * the specified rectangle of pixels.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param dArray the double array
+     * @param data the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, double dArray[],
+            DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, dArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel
+     * in the DataBuffer as float value.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample as float value.
+     * @param data the image data.
+     */
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        setSample(x, y, b, (int) s, data);
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel
+     * in the DataBuffer as double value.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample as double value.
+     * @param data the image data.
+     */
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        setSample(x, y, b, (int) s, data);
+    }
+
+    /**
+     * Creates a DataBuffer object which corresponds to the SampleModel. 
+     *  
+     * @return the DataBuffer object which corresponds to 
+     * the SampleModel.
+     */
+    public abstract DataBuffer createDataBuffer();
+
+    /**
+     * Gets the sample size in bits for the specified band.
+     * 
+     * @param band the specified band.
+     * 
+     * @return the sample size in bits for the specified band.
+     */
+    public abstract int getSampleSize(int band);
+
+    /**
+     * Gets an array of the sample size in bits for all bands.
+     *  
+     * @return an array of the sample size in bits for all bands.
+     */
+    public abstract int[] getSampleSize();
+
+    /**
+     * Gets the width of the image data of this SampleModel object.
+     * 
+     * @return the width of the image data of this SampleModel object.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the transfer type used to transfer pixels via 
+     * the getDataElements and setDataElements methods.
+     * Transfer type value can be one of the predefined type 
+     * from DataBuffer class or not.
+     * 
+     * @return the transfer type.
+     */
+    public int getTransferType() {
+        return dataType;
+    }
+
+    /**
+     * Returns the number of data elements for pixel transfering
+     * via the getDataElements and setDataElements methods. 
+     * 
+     * @return the number of data elements for pixel transfering
+     * via the getDataElements and setDataElements methods.
+     */
+    public abstract int getNumDataElements();
+
+    /**
+     * Gets the number of bands in the image data of this 
+     * SampleModel object.
+     * 
+     * @return the number of bands in the image data of this 
+     * SampleModel object.
+     */
+    public final int getNumBands() {
+        return numBands;
+    }
+
+    /**
+     * Gets the height of the image data of this SampleModel object.
+     * 
+     * @return the height of the image data of this SampleModel object.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the data type of image data of this SampleModel object.
+     * 
+     * @return the data type of image data of this SampleModel object.
+     */
+    public final int getDataType() {
+        return dataType;
+    }
+
+}
+
diff --git a/awt/java/awt/image/ShortLookupTable.java b/awt/java/awt/image/ShortLookupTable.java
new file mode 100644
index 0000000..77c9c45
--- /dev/null
+++ b/awt/java/awt/image/ShortLookupTable.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+
+/**
+ * The ShortLookupTable class provides provides functionality for 
+ * lookup operations, and is defined by an input short array for 
+ * bands or components of image and an offset value.
+ * The offset value will be subtracted from the input values before 
+ * indexing the input arrays. The output of a lookup operation is 
+ * represented as an unsigned short array.
+ */
+public class ShortLookupTable extends LookupTable {
+    
+    /** The data. */
+    private short data[][];
+
+    /**
+     * Instantiates a new ShortLookupTable with the specified offset value
+     * and the specified short array which represents lookup table for
+     * all bands.
+     * 
+     * @param offset the offset value.
+     * @param data the data array.
+     */
+    public ShortLookupTable(int offset, short[] data) {
+        super(offset, 1);
+        this.data = new short[1][data.length];
+        // The data array stored as a reference
+        this.data[0] = data;
+    }
+
+    /**
+     * Instantiates a new ShortLookupTable with the specified offset value
+     * and the specified short array of arrays which represents lookup table
+     * for each band.
+     * 
+     * @param offset the offset value.
+     * @param data the data array of arrays for each band.
+     */
+    public ShortLookupTable(int offset, short[][] data) {
+        super(offset, data.length);
+        this.data = new short[data.length][data[0].length];
+        for (int i = 0; i < data.length; i++) {
+            // The data array for each band stored as a reference
+            this.data[i] = data[i];
+        }
+    }
+
+    /**
+     * Gets the lookup table of this ShortLookupTable object. If 
+     * this ShortLookupTable object has one short array for all bands, 
+     * the returned array length is one.
+     * 
+     * @return the lookup table of this ShortLookupTable object.
+     */
+    public final short[][] getTable() {
+        return data;
+    }
+
+    /**
+     * Returns a short array which contains samples of the specified
+     * pixel which is translated with the lookup table of this 
+     * ShortLookupTable object. The resulted array is stored to
+     * the dst array.
+     * 
+     * @param src the source array.
+     * @param dst the destination array where the result can be stored.
+     * 
+     * @return the short array of translated samples of a pixel.
+     */
+    public short[] lookupPixel(short[] src, short[] dst) {
+        if (dst == null) {
+            dst = new short[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+
+    @Override
+    public int[] lookupPixel(int[] src, int[] dst) {
+        if (dst == null) {
+            dst = new int[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+}
diff --git a/awt/java/awt/image/SinglePixelPackedSampleModel.java b/awt/java/awt/image/SinglePixelPackedSampleModel.java
new file mode 100644
index 0000000..311395a
--- /dev/null
+++ b/awt/java/awt/image/SinglePixelPackedSampleModel.java
@@ -0,0 +1,508 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The SinglePixelPackedSampleModel class represents pixel data 
+ * where several samples combine to create a single pixel and 
+ * are stored in a single data array element. This class 
+ * supports TYPE_BYTE, TYPE_USHORT, TYPE_INT data types. 
+ */
+public class SinglePixelPackedSampleModel extends SampleModel {
+
+    /** The bit masks. */
+    private int bitMasks[];
+
+    /** The bit offsets. */
+    private int bitOffsets[];
+
+    /** The bit sizes. */
+    private int bitSizes[];
+
+    /** The scanline stride. */
+    private int scanlineStride;
+
+    /** The max bit size. */
+    private int maxBitSize;
+
+    /**
+     * Instantiates a new SinglePixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bitMasks the bit masks for all the bands.
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h,
+            int bitMasks[]) {
+        this(dataType, w, h, w, bitMasks);
+    }
+
+    /**
+     * Instantiates a new SinglePixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param scanlineStride The scanline stride of the image data.
+     * @param bitMasks the bit masks for all the bands.
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h,
+            int scanlineStride, int bitMasks[]) {
+
+        super(dataType, w, h, bitMasks.length);
+
+        if (dataType != DataBuffer.TYPE_BYTE &&
+                dataType != DataBuffer.TYPE_USHORT &&
+                dataType != DataBuffer.TYPE_INT) {
+            // awt.61=Unsupported data type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
+                    dataType));
+        }
+
+        this.scanlineStride = scanlineStride;
+        this.bitMasks = bitMasks.clone();
+        this.bitOffsets = new int[this.numBands];
+        this.bitSizes = new int[this.numBands];
+
+        this.maxBitSize = 0;
+
+        for (int i = 0; i < this.numBands; i++) {
+            int offset = 0;
+            int size = 0;
+            int mask = bitMasks[i];
+
+            if (mask != 0) {
+                while ((mask & 1) == 0) {
+                    mask >>>= 1;
+                    offset++;
+                }
+
+                while ((mask & 1) == 1) {
+                    mask >>>= 1;
+                    size++;
+                }
+
+                if (mask != 0) {
+                    // awt.62=Wrong mask : {0}
+                    throw new IllegalArgumentException(Messages.getString(
+                            "awt.62", bitMasks[i])); //$NON-NLS-1$
+                }
+            }
+
+            this.bitOffsets[i] = offset;
+            this.bitSizes[i] = size;
+
+            if (this.maxBitSize < size) {
+                this.maxBitSize = size;
+            }
+
+        }
+
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            if (obj == null) {
+                bdata = new byte[1];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            bdata[0] = (byte) data.getElem(y * scanlineStride + x);
+            obj = bdata;
+            break;
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            if (obj == null) {
+                sdata = new short[1];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            sdata[0] = (short) data.getElem(y * scanlineStride + x);
+            obj = sdata;
+            break;
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            if (obj == null) {
+                idata = new int[1];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            idata[0] = data.getElem(y * scanlineStride + x);
+            obj = idata;
+            break;
+        }
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            data.setElem(y * scanlineStride + x, ((byte[]) obj)[0] & 0xff);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data.setElem(y * scanlineStride + x, ((short[]) obj)[0] & 0xffff);
+            break;
+        case DataBuffer.TYPE_INT:
+            data.setElem(y * scanlineStride + x, ((int[]) obj)[0]);
+            break;
+        }
+    }
+
+    /**
+     * Compares this SinglePixelPackedSampleModel object with 
+     * the specified object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if this SinglePixelPackedSampleModel object is 
+     * equal to the specified object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+
+        SinglePixelPackedSampleModel model = (SinglePixelPackedSampleModel) o;
+        return this.width == model.width &&
+                this.height == model.height &&
+                this.numBands == model.numBands &&
+                this.dataType == model.dataType &&
+                Arrays.equals(this.bitMasks, model.bitMasks) &&
+                Arrays.equals(this.bitOffsets, model.bitOffsets) &&
+                Arrays.equals(this.bitSizes, model.bitSizes) &&
+                this.scanlineStride == model.scanlineStride;
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > this.numBands) {
+            // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int masks[] = new int[bands.length];
+        for (int i = 0; i < bands.length; i++) {
+            masks[i] = this.bitMasks[bands[i]];
+        }
+        return new SinglePixelPackedSampleModel(this.dataType, this.width,
+                this.height, this.scanlineStride, masks);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new SinglePixelPackedSampleModel(this.dataType, w, h,
+                this.bitMasks);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[this.numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < this.numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < this.numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int sample = data.getElem(y * scanlineStride + x);
+        return ((sample & this.bitMasks[b]) >>> this.bitOffsets[b]);
+    }
+
+    @Override
+    public int[] getPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int pixels[];
+
+        if (iArray == null) {
+            pixels = new int[w * h * this.numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < this.numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages
+                    .getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < this.numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int tmp = data.getElem(y * scanlineStride + x);
+        tmp &= ~this.bitMasks[b];
+        tmp |= (s << this.bitOffsets[b]) & this.bitMasks[b];
+        data.setElem(y * scanlineStride + x, tmp);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages
+                    .getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(x + j, y + i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+        int size = (this.height - 1) * scanlineStride + width;
+
+        switch (this.dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size);
+            break;
+        }
+        return data;
+    }
+
+    /**
+     * Gets the offset of the specified pixel in the data array.
+     * 
+     * @param x the X coordinate of the specified pixel.
+     * @param y the Y coordinate of the specified pixel.
+     * 
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return (y * scanlineStride + x);
+    }
+
+    @Override
+    public int getSampleSize(int band) {
+        return bitSizes[band];
+    }
+
+    @Override
+    public int[] getSampleSize() {
+        return bitSizes.clone();
+    }
+
+    /**
+     * Gets an array of the bit offsets of the data array elements. 
+     * 
+     * @return an array of the bit offsets.
+     */
+    public int[] getBitOffsets() {
+        return bitOffsets.clone();
+    }
+
+    /**
+     * Gets an array of the bit masks for all bands.
+     * 
+     * @return an array of the bit masks for all bands.
+     */
+    public int[] getBitMasks() {
+        return bitMasks.clone();
+    }
+
+    /**
+     * Returns a hash code of this MultiPixelPackedSampleModel class.
+     * 
+     * @return the hash code of this MultiPixelPackedSampleModel class.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        for (int element : bitMasks) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bitOffsets) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bitSizes) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        hash ^= scanlineStride;
+        return hash;
+    }
+
+    /**
+     * Gets the scanline stride.
+     * 
+     * @return the scanline stride
+     */
+    public int getScanlineStride() {
+        return this.scanlineStride;
+    }
+
+    @Override
+    public int getNumDataElements() {
+        return 1;
+    }
+
+}
+
diff --git a/awt/java/awt/image/TileObserver.java b/awt/java/awt/image/TileObserver.java
new file mode 100644
index 0000000..39ded02
--- /dev/null
+++ b/awt/java/awt/image/TileObserver.java
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * An asynchronous update interface for receiving notifications
+ * about tile information when tiles of a WritableRenderedImage 
+ * become modifiable or unmodifiable.
+ */
+public interface TileObserver {
+
+    /**
+     * This method is called when information about a tile
+     * update is available.
+     * 
+     * @param source the source image.
+     * @param tileX the X index of the tile.
+     * @param tileY the Y index of the tile.
+     * @param willBeWritable parameter which indicates whether
+     * the tile will be grabbed for writing or be released.
+     */
+    public void tileUpdate(WritableRenderedImage source, int tileX, int tileY, boolean willBeWritable);
+
+}
+
diff --git a/awt/java/awt/image/VolatileImage.java b/awt/java/awt/image/VolatileImage.java
new file mode 100644
index 0000000..3b0cfb2
--- /dev/null
+++ b/awt/java/awt/image/VolatileImage.java
@@ -0,0 +1,144 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.ImageCapabilities;
+import java.awt.Transparency;
+
+/**
+ * The VolatileImage abstract class represents an image which can lose 
+ * its contents at any point. VolatileImage objects are device specific.
+ * This class provies methods for checking if operation of this image
+ * are compatible for the GraphicsConfiguration. 
+ */
+public abstract class VolatileImage extends Image
+    // Volatile image implements Transparency since 1.5
+    implements Transparency {
+    
+    /** 
+     * The Constant IMAGE_INCOMPATIBLE indicates that this VolatileImage 
+     * is not applicable for the GraphicsConfiguration object. 
+     */
+    public static final int IMAGE_INCOMPATIBLE = 2;
+
+    /** 
+     * The Constant IMAGE_OK indicates that VolatileImage is ready 
+     * for using.
+     */
+    public static final int IMAGE_OK = 0;
+
+    /** 
+     * The Constant IMAGE_RESTORED indicates that VolatileImage
+     * will be ready to use after restoring. 
+     */
+    public static final int IMAGE_RESTORED = 1;
+
+    /** 
+     * The transparency value of this image. 
+     */
+    protected int transparency = OPAQUE;
+
+    /**
+     * Instantiates a new VolatileImage object.
+     */
+    public VolatileImage() {
+        super();
+    }
+
+    /**
+     * Returns true if rendering data is lost during validating.
+     * This method should be called after rendering operation of image.
+     * 
+     * @return true, if contents lost during validating, false otherwise.
+     */
+
+    public abstract boolean contentsLost();
+
+    /**
+     * Creates a Graphics2D used to draw in this VolatileImage.
+     * 
+     * @return the Graphics2D object.
+     */
+    public abstract Graphics2D createGraphics();
+
+    /**
+     * Gets the ImageCapabilities of this VolatileImage.
+     * 
+     * @return the ImageCapabilities of this VolatileImage.
+     */
+    public abstract ImageCapabilities getCapabilities();
+
+    /**
+     * Gets the height of this VolatileImage.
+     * 
+     * @return the height of this VolatileImage.
+     */
+    public abstract int getHeight();
+
+    /**
+     * Gets a BufferedImage representation of current VolatileImage that
+     * won't be affected by any changes to this VolatileImage.
+     * 
+     * @return a BufferedImage representation of current VolatileImage.
+     */
+    public abstract BufferedImage getSnapshot();
+
+    /**
+     * Gets the width of this VolatileImage.
+     * 
+     * @return the width of this VolatileImage.
+     */
+    public abstract int getWidth();
+
+    /**
+     * Validates the drawing surface of the image if the surface had been 
+     * lost and if the spacified GraphicsConfiguration object is  
+     * applicable to this image. 
+     * 
+     * @param gc GraphicsConfiguration object.
+     * 
+     * @return one of the image status constants: IMAGE_OK, IMAGE_RESTORED or
+     * IMAGE_INCOMPATIBLE.
+     */
+    public abstract int validate(GraphicsConfiguration gc);
+
+    @Override
+    public void flush() {
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        return createGraphics();
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return getSnapshot().getSource();
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+}
diff --git a/awt/java/awt/image/WritableRaster.java b/awt/java/awt/image/WritableRaster.java
new file mode 100644
index 0000000..0893915
--- /dev/null
+++ b/awt/java/awt/image/WritableRaster.java
@@ -0,0 +1,516 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The WritableRaster class provides functionality for 
+ * writing samples and pixel capabilities to the Raster.
+ */
+public class WritableRaster extends Raster {
+
+    /**
+     * Instantiates a new WritableRaster object with the specified 
+     * SampleModel, DataBuffer, rectangular region and parent 
+     * WritableRaster. 
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified DataBuffer.
+     * @param aRegion the rectangular region which defines the new image bounds. 
+     * @param sampleModelTranslate this point defines the translation point
+     * from the SampleModel to the new WritableRaster coordinates.
+     * @param parent the parent of this WritableRaster.
+     */
+    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Rectangle aRegion, Point sampleModelTranslate,
+            WritableRaster parent) {
+        super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
+    }
+
+    /**
+     * Instantiates a new WritableRaster object with the specified
+     * SampleModel which defines a layout of this WritableRaster and 
+     * DataBuffer objects which defines the image data.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified DataBuffer.
+     * @param origin the point of origin.
+     */
+    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Point origin) {
+        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
+                sampleModel.width, sampleModel.height), origin, null);
+    }
+
+    /**
+     * Instantiates a new WritableRaster with the specified SampleModel.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param origin the origin.
+     */
+    protected WritableRaster(SampleModel sampleModel, Point origin) {
+        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(
+                origin.x, origin.y, sampleModel.width, sampleModel.height),
+                origin, null);
+    }
+
+    /**
+     * Sets the data for a single pixel from an input Object which 
+     * represents an array of primitive types: DataBuffer.TYPE_BYTE, 
+     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param inData the input data.
+     */
+    public void setDataElements(int x, int y, Object inData) {
+        sampleModel.setDataElements(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, inData, dataBuffer);
+    }
+
+    /**
+     * Sets the data elements which represent pixel data to the specified 
+     * rectangle area as a primitive array. The following image data types
+     * are supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 
+     * or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param inData the array of primitive type data to be set to the
+     * specified area.
+     */
+    public void setDataElements(int x, int y, int w, int h, Object inData) {
+        sampleModel.setDataElements(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, inData, dataBuffer);
+    }
+
+    /**
+     * Creates the child of this WritableRaster by sharing the specified 
+     * rectangular area in this WritableRaster. 
+     * The parentX, parentY, width and height parameters specify rectangular
+     * area to be shared.
+     * 
+     * @param parentX the X coordinate of the upper left corner of 
+     * the shared rectangle with respect to this WritableRaster' coordinates. 
+     * @param parentY the Y coordinate of the upper left corner of 
+     * the shared rectangle with respect to this WritableRaster' coordinates. 
+     * @param w the width of the child area.
+     * @param h the height of the child area.
+     * @param childMinX the X coordinate of child area mapped to the parentX
+     * coordinate.
+     * @param childMinY the Y coordinate of child area mapped to the parentY
+     * coordinate.
+     * @param bandList the array of band indicies.
+     * 
+     * @return the child WritableRaster.
+     */
+    public WritableRaster createWritableChild(int parentX, int parentY, int w,
+            int h, int childMinX, int childMinY, int bandList[]) {
+        if (w <= 0 || h <= 0) {
+            // awt.244=Width or Height of child Raster is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.244")); //$NON-NLS-1$
+        }
+
+        if (parentX < this.minX || parentX + w > this.minX + this.width) {
+            // awt.245=parentX disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.245")); //$NON-NLS-1$
+        }
+
+        if (parentY < this.minY || parentY + h > this.minY + this.height) {
+            // awt.246=parentY disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.246")); //$NON-NLS-1$
+        }
+
+        if ((long) parentX + w > Integer.MAX_VALUE) {
+            // awt.247=parentX + w results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.247")); //$NON-NLS-1$
+        }
+
+        if ((long) parentY + h > Integer.MAX_VALUE) {
+            // awt.248=parentY + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.248")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinX + w > Integer.MAX_VALUE) {
+            // awt.249=childMinX + w results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.249")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinY + h > Integer.MAX_VALUE) {
+            // awt.24A=childMinY + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.24A")); //$NON-NLS-1$
+        }
+
+        SampleModel childModel;
+
+        if (bandList == null) {
+            childModel = sampleModel;
+        } else {
+            childModel = sampleModel.createSubsetSampleModel(bandList);
+        }
+
+        int childTranslateX = childMinX - parentX;
+        int childTranslateY = childMinY - parentY;
+
+        return new WritableRaster(childModel, dataBuffer,
+                new Rectangle(childMinX, childMinY, w, h),
+                new Point(childTranslateX + sampleModelTranslateX,
+                        childTranslateY + sampleModelTranslateY),
+                this);
+    }
+
+    /**
+     * Creates the translated child of this WritableRaster. 
+     * New WritableRaster object is a reference to the this 
+     * WritableRaster and with different location. 
+     *  
+     * @param childMinX the X coordinate of the new WritableRaster.
+     * @param childMinY the Y coordinate of the new WritableRaster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createWritableTranslatedChild(int childMinX,
+            int childMinY) {
+        return createWritableChild(minX, minY, width, height, childMinX,
+                childMinY, null);
+    }
+
+    /**
+     * Gets the parent WritableRaster for this WritableRaster object. 
+     * 
+     * @return the parent WritableRaster for this WritableRaster object.
+     */
+    public WritableRaster getWritableParent() {
+        return (WritableRaster) parent;
+    }
+
+    /**
+     * Sets pixels from the specified source Raster srcRaster to this 
+     * WritableRaster.
+     * 
+     * @param srcRaster the source Raster.
+     */
+    public void setRect(Raster srcRaster) {
+        setRect(0, 0, srcRaster);
+    }
+
+    /**
+     * Sets pixels from the specified source Raster srcRaster to this 
+     * WritableRaster. Each pixel with (x, y) coordinates from the source 
+     * Raster is copied to pixel with (x+dx, y+dy) coordinates in this
+     * WritableRaster. The pixels with (x+dx, y+dy) coordinates which
+     * are out the bounds of this raster are ignored. 
+     *  
+     * @param dx the distance the pixel's X coordinate in the source
+     * Raster is translated when writtien to this WritableRaster. 
+     * @param dy the distance the pixel's Y coordinate in the source
+     * Raster is translated when writtien to this WritableRaster.
+     * @param srcRaster the source Raster.
+     */
+    public void setRect(int dx, int dy, Raster srcRaster) {
+        int w = srcRaster.getWidth();
+        int h = srcRaster.getHeight();
+
+        int srcX = srcRaster.getMinX();
+        int srcY = srcRaster.getMinY();
+
+        int dstX = srcX + dx;
+        int dstY = srcY + dy;
+
+        if (dstX < this.minX) {
+            int minOffX = this.minX - dstX;
+            w -= minOffX;
+            dstX = this.minX;
+            srcX += minOffX;
+        }
+
+        if (dstY < this.minY) {
+            int minOffY = this.minY - dstY;
+            h -= minOffY;
+            dstY = this.minY;
+            srcY += minOffY;
+        }
+
+        if (dstX + w > this.minX + this.width) {
+            int maxOffX = (dstX + w) - (this.minX + this.width);
+            w -= maxOffX;
+        }
+
+        if (dstY + h > this.minY + this.height) {
+            int maxOffY = (dstY + h) - (this.minY + this.height);
+            h -= maxOffY;
+        }
+
+        if (w <= 0 || h <= 0) {
+            return;
+        }
+
+        switch (sampleModel.getDataType()) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_INT:
+            int iPixelsLine[] = null;
+            for (int i = 0; i < h; i++) {
+                iPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1,
+                        iPixelsLine);
+                setPixels(dstX, dstY + i, w, 1, iPixelsLine);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fPixelsLine[] = null;
+            for (int i = 0; i < h; i++) {
+                fPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1,
+                        fPixelsLine);
+                setPixels(dstX, dstY + i, w, 1, fPixelsLine);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double dPixelsLine[] = null;
+            for (int i = 0; i < h; i++) {
+                dPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1,
+                        dPixelsLine);
+                setPixels(dstX, dstY + i, w, 1, dPixelsLine);
+            }
+            break;
+        }
+    }
+
+    /**
+     * Sets the data for a rectangle of pixels from an input Raster to
+     * this WritableRaster.
+     * 
+     * @param x the X coordinate of the point where the data of 
+     * the input Raster is to be written.
+     * @param y the Y coordinate of the point where the data of 
+     * the input Raster is to be written.
+     * @param inRaster the input Raster.
+     */
+    public void setDataElements(int x, int y, Raster inRaster) {
+        int dstX = x + inRaster.getMinX();
+        int dstY = y + inRaster.getMinY();
+
+        int w = inRaster.getWidth();
+        int h = inRaster.getHeight();
+
+        if (dstX < this.minX || dstX + w > this.minX + this.width ||
+                dstY < this.minY || dstY + h > this.minY + this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int srcX = inRaster.getMinX();
+        int srcY = inRaster.getMinY();
+        Object line = null;
+
+        for (int i = 0; i < h; i++) {
+            line = inRaster.getDataElements(srcX, srcY + i, w, 1, line);
+            setDataElements(dstX, dstY + i, w, 1, line);
+        }
+    }
+
+    /**
+     * Sets a int array of samples for the specified pixel 
+     * in this WritableRaster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param iArray the int array of samples.
+     */
+    public void setPixel(int x, int y, int iArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, iArray, dataBuffer);
+    }
+
+    /**
+     * Sets a float array of samples for the specified pixel 
+     * in this WritableRaster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param fArray the float array of samples.
+     */
+    public void setPixel(int x, int y, float fArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, fArray, dataBuffer);
+    }
+
+    /**
+     * Sets a double array of samples for the specified pixel 
+     * in this WritableRaster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param dArray the double array of samples.
+     */
+    public void setPixel(int x, int y, double dArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, dArray, dataBuffer);
+    }
+
+    /**
+     * Sets a int array of samples for the specified rectangular area
+     * of pixels in this WritableRaster. 
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param iArray the int array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, int iArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, iArray, dataBuffer);
+    }
+
+    /**
+     * Sets a float array of samples for the specified rectangular area
+     * of pixels in this WritableRaster. 
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param fArray the float array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, float fArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, fArray, dataBuffer);
+    }
+
+    /**
+     * Sets a double array of samples for the specified rectangular area
+     * of pixels in this WritableRaster. 
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param dArray the double array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, double dArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, dArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified
+     * rectangular area of pixels with an int array of samples.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param b the specified band.
+     * @param iArray the int array of samples.
+
+     */
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified
+     * rectangular area of pixels with a float array of samples.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param b the specified band.
+     * @param fArray the float array of samples.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, float fArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified
+     * rectangular area of pixels with a double array of samples.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param b the specified band.
+     * @param dArray the double array of samples.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, double dArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified
+     * pixel with an int sample.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample to be set.
+     */
+    public void setSample(int x, int y, int b, int s) {
+        sampleModel.setSample(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, b, s, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified
+     * pixel with a float sample.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample to be set.
+     */
+    public void setSample(int x, int y, int b, float s) {
+        sampleModel.setSample(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, b, s, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified
+     * pixel with a int sample.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample to be set.
+     */
+    public void setSample(int x, int y, int b, double s) {
+        sampleModel.setSample(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, b, s, dataBuffer);
+    }
+
+}
+
diff --git a/awt/java/awt/image/WritableRenderedImage.java b/awt/java/awt/image/WritableRenderedImage.java
new file mode 100644
index 0000000..ee1cb9e
--- /dev/null
+++ b/awt/java/awt/image/WritableRenderedImage.java
@@ -0,0 +1,101 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Point;
+
+/**
+ * The WriteableRenderedImage interface is interface for objects which
+ * contains Raster data of one or several tiles. This interface provides
+ * notification mehanism for obtaining tile's writing status.    
+ */
+public interface WritableRenderedImage extends RenderedImage {
+
+    /**
+     * Gets and checks out the writable tile for writing. 
+     * 
+     * @param tileX the X index of the tile. 
+     * @param tileY the Y index of the tile.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster getWritableTile(int tileX, int tileY);
+
+    /**
+     * Removes the registered TileObserver.
+     * 
+     * @param to the TileObserver which is registered for this
+     * WritableRenderedImage.
+     */
+    public void removeTileObserver(TileObserver to);
+
+    /**
+     * Adds the specified TileObserver to this WritableRenderedImage.
+     * 
+     * @param to the TileObserver object to be added.
+     */
+    public void addTileObserver(TileObserver to);
+
+    /**
+     * Sets this image to the contents of the specified Raster.  
+     * 
+     * @param r the specified Raster.
+     */
+    public void setData(Raster r);
+
+    /**
+     * Gets the array of points wich represent indices of tiles which
+     * are check out for writing.
+     * 
+     * @return the array of Points.
+     */
+    public Point[] getWritableTileIndices();
+
+    /**
+     * Checks if the specified tile is writable or not.
+     * 
+     * @param tileX the X index of tile. 
+     * @param tileY the Y index of tile.
+     * 
+     * @return true, if the specified tile is writable,
+     * false otherwise.
+     */
+    public boolean isTileWritable(int tileX, int tileY);
+
+    /**
+     * Release the specified writable tile. This method removes the writer 
+     * from the tile.
+     * 
+     * @param tileX the X index of the tile. 
+     * @param tileY the Y index of the tile.
+     */
+    public void releaseWritableTile(int tileX, int tileY);
+
+    /**
+     * Checks if there is a tile which is checked out for writing.
+     * 
+     * @return true, if any tile is checked out for writing, false if there
+     * is no such tile.
+     */
+    public boolean hasTileWriters();
+
+}
+
diff --git a/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
new file mode 100644
index 0000000..3e96637
--- /dev/null
+++ b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+
+/**
+ * A factory for creating ContextualRenderedImage objects with utilities 
+ * for manipulating the properties in the parameter block.
+ */
+public interface ContextualRenderedImageFactory extends RenderedImageFactory {
+
+    /**
+     * Maps a render context to a parameter block and a renderable image.
+     * 
+     * @param a0 the index
+     * @param a1 the RenderContext
+     * @param a2 the ParameterBlock
+     * @param a3 the RenderableImage
+     * 
+     * @return the render context
+     */
+    public RenderContext mapRenderContext(int a0, RenderContext a1, ParameterBlock a2, RenderableImage a3);
+
+    /**
+     * Gets the value of the property from the parameter block.
+     * 
+     * @param a0 the parameter block to examine to find the property
+     * @param a1 the name of the property
+     * 
+     * @return the value of the property
+     */
+    public Object getProperty(ParameterBlock a0, String a1);
+
+    /**
+     * Creates the rendered image determined by the render context and
+     * parameter block.
+     * 
+     * @param a0 the RenderContext
+     * @param a1 the ParameterBlock
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage create(RenderContext a0, ParameterBlock a1);
+
+    /**
+     * Gets the bounding rectangle from the parameter block.
+     * 
+     * @param a0 the parameter block to read the bounds from
+     * 
+     * @return the bounding rectangle
+     */
+    public Rectangle2D getBounds2D(ParameterBlock a0);
+
+    /**
+     * Gets the names of all of the supported properties.
+     * 
+     * @return the property names
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Checks if this image factory is dynamic.
+     * 
+     * @return true, if this image factory is dynamic
+     */
+    public boolean isDynamic();
+
+}
+
diff --git a/awt/java/awt/image/renderable/ParameterBlock.java b/awt/java/awt/image/renderable/ParameterBlock.java
new file mode 100644
index 0000000..1555f45
--- /dev/null
+++ b/awt/java/awt/image/renderable/ParameterBlock.java
@@ -0,0 +1,548 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.image.RenderedImage;
+import java.io.Serializable;
+import java.util.Vector;
+
+/**
+ * The Class ParameterBlock groups an indexed set of parameter data 
+ * with a set of renderable (source) images.  The mapping between
+ * the indexed parameters and their property names is provided 
+ * by a {@link ContextualRenderedImageFactory}
+ */
+public class ParameterBlock implements Cloneable, Serializable {
+
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -7577115551785240750L;
+
+    /** The sources (renderable images). */
+    protected Vector<Object> sources = new Vector<Object>();
+
+    /** The parameters. */
+    protected Vector<Object> parameters = new Vector<Object>();
+
+    /**
+     * Instantiates a new parameter block.
+     * 
+     * @param sources the vector of source images
+     * @param parameters the vector of parameters
+     */
+    public ParameterBlock(Vector<Object> sources, Vector<Object> parameters) {
+        setSources(sources);
+        setParameters(parameters);
+    }
+
+    /**
+     * Instantiates a new parameter block with no parameters.
+     * 
+     * @param sources the vector of source images
+     */
+    public ParameterBlock(Vector<Object> sources) {
+        setSources(sources);
+    }
+
+    /**
+     * Instantiates a new parameter block with no image or parameter vectors.
+     */
+    public ParameterBlock() {}
+
+    /**
+     * Sets the source image at the specified index.
+     * 
+     * @param source the source image
+     * @param index the index where the source will be placed
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock setSource(Object source, int index) {
+        if(sources.size() < index + 1){
+            sources.setSize(index + 1);
+        }
+        sources.setElementAt(source, index);
+        return this;
+    }
+
+    /**
+     * Sets the parameter value object at the specified index.
+     * 
+     * @param obj the parameter value to place at the desired index
+     * @param index the index where the object is to be placed in the 
+     * vector of parameters
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(Object obj, int index) {
+        if(parameters.size() < index + 1){
+            parameters.setSize(index + 1);
+        }
+        parameters.setElementAt(obj, index);
+        return this;
+    }
+
+    /**
+     * Adds a source to the vector of sources.
+     * 
+     * @param source the source to add
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock addSource(Object source) {
+        sources.addElement(source);
+        return this;
+    }
+
+    /**
+     * Adds the object to the vector of parameter values
+     * 
+     * @param obj the obj to add
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(Object obj) {
+        parameters.addElement(obj);
+        return this;
+    }
+
+    /**
+     * Sets the vector of sources, replacing the existing
+     * vector of sources, if any.
+     * 
+     * @param sources the new sources
+     */
+    public void setSources(Vector<Object> sources) {
+        this.sources = sources;
+    }
+
+    /**
+     * Sets the vector of parameters, replacing the existing
+     * vector of parameters, if any.
+     * 
+     * @param parameters the new parameters
+     */
+    public void setParameters(Vector<Object> parameters) {
+        this.parameters = parameters;
+    }
+
+    /**
+     * Gets the vector of sources.
+     * 
+     * @return the sources
+     */
+    public Vector<Object> getSources() {
+        return sources;
+    }
+
+    /**
+     * Gets the vector of parameters.
+     * 
+     * @return the parameters
+     */
+    public Vector<Object> getParameters() {
+        return parameters;
+    }
+
+    /**
+     * Gets the source at the specified index.
+     * 
+     * @param index the index
+     * 
+     * @return the source object found at the specified index
+     */
+    public Object getSource(int index) {
+        return sources.elementAt(index);
+    }
+
+    /**
+     * Gets the object parameter found at the specified index.
+     * 
+     * @param index the index
+     * 
+     * @return the parameter object found at the specified index
+     */
+    public Object getObjectParameter(int index) {
+        return parameters.elementAt(index);
+    }
+
+    /**
+     * Shallow clone (clones using the superclass clone method).
+     * 
+     * @return the clone of this object
+     */
+    public Object shallowClone() {
+        try{
+            return super.clone();
+        }catch(Exception e){
+            return null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object clone() {
+        ParameterBlock replica;
+        try{
+            replica = (ParameterBlock)super.clone();
+        }catch(Exception e){
+            return null;
+        }
+        if(sources != null){
+            replica.setSources((Vector<Object>)(sources.clone()));
+        }
+        if(parameters != null){
+            replica.setParameters((Vector<Object>)(parameters.clone()));
+        }
+        return replica;
+    }
+
+    /**
+     * Gets an array of classes corresponding to all of the parameter
+     * values found in the array of parameters, in order.
+     * 
+     * @return the parameter classes
+     */
+    public Class[] getParamClasses() {
+        int count = parameters.size();
+        Class paramClasses[] = new Class[count];
+
+        for(int i = 0; i < count; i++){
+            paramClasses[i] = parameters.elementAt(i).getClass();
+        }
+        return paramClasses;
+    }
+
+    /**
+     * Gets the renderable source image found at the specified index
+     * in the source array.
+     * 
+     * @param index the index
+     * 
+     * @return the renderable source image
+     */
+    public RenderableImage getRenderableSource(int index) {
+        return (RenderableImage)sources.elementAt(index);
+    }
+
+    /**
+     * Wraps the short value in a Short and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param s the short value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(short s, int index) {
+        return set(new Short(s), index);
+    }
+
+    /**
+     * Wraps the short value in a Short and adds it to the 
+     * parameter block.
+     * 
+     * @param s the short value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(short s) {
+        return add(new Short(s));
+    }
+
+    /**
+     * Wraps the long value in a Long and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param l the long value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(long l, int index) {
+        return set(new Long(l), index);
+    }
+
+    /**
+     * Wraps the long value in a Long and adds it to the 
+     * parameter block.
+     * 
+     * @param l the long value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(long l) {
+        return add(new Long(l));
+    }
+
+    /**
+     * Wraps the int value in an Integer and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param i the int value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(int i, int index) {
+        return set(new Integer(i), index);
+    }
+
+    /**
+     * Wraps the int value in an Integer and adds it to the 
+     * parameter block.
+     * 
+     * @param i the int value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(int i) {
+        return add(new Integer(i));
+    }
+
+    /**
+     * Wraps the float value in a Float and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param f the float value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(float f, int index) {
+        return set(new Float(f), index);
+    }
+
+    /**
+     * Wraps the float value in a Float and adds it to the 
+     * parameter block.
+     * 
+     * @param f the float value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(float f) {
+        return add(new Float(f));
+    }
+
+    /**
+     * Wraps the double value in a Double and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param d the double value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(double d, int index) {
+        return set(new Double(d), index);
+    }
+
+    /**
+     * Wraps the double value in a Double and adds it to the 
+     * parameter block.
+     * 
+     * @param d the double value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(double d) {
+        return add(new Double(d));
+    }
+
+    /**
+     * Wraps the char value in a Character and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param c the char value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(char c, int index) {
+        return set(new Character(c), index);
+    }
+
+    /**
+     * Wraps the char value in a Character and adds it to the 
+     * parameter block.
+     * 
+     * @param c the char value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(char c) {
+        return add(new Character(c));
+    }
+
+    /**
+     * Wraps the byte value in a Byte and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param b the byte value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(byte b, int index) {
+        return set(new Byte(b), index);
+    }
+
+    /**
+     * Wraps the byte value in a Byte and adds it to the 
+     * parameter block.
+     * 
+     * @param b the byte value of the parameter
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock add(byte b) {
+        return add(new Byte(b));
+    }
+
+    /**
+     * Gets the RenderedImage at the specified index from the 
+     * vector of source images.
+     * 
+     * @param index the index
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage getRenderedSource(int index) {
+        return (RenderedImage)sources.elementAt(index);
+    }
+
+    /**
+     * Gets the short-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the short parameter
+     */
+    public short getShortParameter(int index) {
+        return ((Short)parameters.elementAt(index)).shortValue();
+    }
+
+    /**
+     * Gets the long-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the long parameter
+     */
+    public long getLongParameter(int index) {
+        return ((Long)parameters.elementAt(index)).longValue();
+    }
+
+    /**
+     * Gets the int-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the int parameter
+     */
+    public int getIntParameter(int index) {
+        return ((Integer)parameters.elementAt(index)).intValue();
+    }
+
+    /**
+     * Gets the float-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the float parameter
+     */
+    public float getFloatParameter(int index) {
+        return ((Float)parameters.elementAt(index)).floatValue();
+    }
+
+    /**
+     * Gets the double-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the double parameter
+     */
+    public double getDoubleParameter(int index) {
+        return ((Double)parameters.elementAt(index)).doubleValue();
+    }
+
+    /**
+     * Gets the char-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the char parameter
+     */
+    public char getCharParameter(int index) {
+        return ((Character)parameters.elementAt(index)).charValue();
+    }
+
+    /**
+     * Gets the byte-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the byte parameter
+     */
+    public byte getByteParameter(int index) {
+        return ((Byte)parameters.elementAt(index)).byteValue();
+    }
+
+    /**
+     * Clears the vector of sources.
+     */
+    public void removeSources() {
+        sources.removeAllElements();
+    }
+
+    /**
+     * Clears the vector of parameters.
+     */
+    public void removeParameters() {
+        parameters.removeAllElements();
+    }
+
+    /**
+     * Gets the number of elements in the vector of sources.
+     * 
+     * @return the number of elements in the vector of sources
+     */
+    public int getNumSources() {
+        return sources.size();
+    }
+
+    /**
+     * Gets the number of elements in the vector of parameters.
+     * 
+     * @return the number of elements in the vector of parameters
+     */
+    public int getNumParameters() {
+        return parameters.size();
+    }
+}
diff --git a/awt/java/awt/image/renderable/RenderContext.java b/awt/java/awt/image/renderable/RenderContext.java
new file mode 100644
index 0000000..3a3b93c
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderContext.java
@@ -0,0 +1,196 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+
+/**
+ * The Class RenderContext stores data on how an image is to be 
+ * rendered: the affine transform, the area of interest, and 
+ * the rendering hints.
+ */
+public class RenderContext implements Cloneable {
+
+    /** The affine transform. */
+    AffineTransform transform;
+    
+    /** The area of interest. */
+    Shape aoi;
+    
+    /** The rendering hints. */
+    RenderingHints hints;
+
+    /**
+     * Instantiates a new render context.
+     * 
+     * @param usr2dev the affine transform
+     * @param aoi the area of interest
+     * @param hints the rendering hints
+     */
+    public RenderContext(AffineTransform usr2dev, Shape aoi, RenderingHints hints) {
+        this.transform = (AffineTransform)usr2dev.clone();
+        this.aoi = aoi;
+        this.hints = hints;
+    }
+
+    /**
+     * Instantiates a new render context with no specified hints.
+     * 
+     * @param usr2dev the affine transform
+     * @param aoi the area of interest
+     */
+    public RenderContext(AffineTransform usr2dev, Shape aoi) {
+        this(usr2dev, aoi, null);
+    }
+
+    /**
+     * Instantiates a new render context with no specified area of interest.
+     * 
+     * @param usr2dev the affine transform
+     * @param hints the rendering hints
+     */
+    public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
+        this(usr2dev, null, hints);
+    }
+
+    /**
+     * Instantiates a new render context with no rendering hints or 
+     * area of interest.
+     * 
+     * @param usr2dev the affine transform
+     */
+    public RenderContext(AffineTransform usr2dev) {
+        this(usr2dev, null, null);
+    }
+
+    @Override
+    public Object clone() {
+        return new RenderContext(transform, aoi, hints);
+    }
+
+    /**
+     * Sets the affine transform for this render context.
+     * 
+     * @param newTransform the new affine transform
+     */
+    public void setTransform(AffineTransform newTransform) {
+        transform = (AffineTransform)newTransform.clone();
+    }
+
+    /**
+     * Concatenates the current transform with the specified transform
+     * (so they are applied with the specified transform acting first)
+     * and sets the resulting transform as the affine transform of 
+     * this rendering context.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     * 
+     * @deprecated use {@link RenderContext#preConcatenateTransform(AffineTransform)}
+     */
+    @Deprecated    
+    public void preConcetenateTransform(AffineTransform modTransform) {
+        preConcatenateTransform(modTransform);
+    }
+
+    /**
+     * Concatenates the current transform with the specified transform
+     * (so they are applied with the specified transform acting first)
+     * and sets the resulting transform as the affine transform of 
+     * this rendering context.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     */
+    public void preConcatenateTransform(AffineTransform modTransform) {
+        transform.preConcatenate(modTransform);
+    }
+
+    /**
+     * Concatenate the specified transform with the current transform.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     * 
+     * @deprecated use {@link RenderContext#concatenateTransform(AffineTransform)}
+     */
+    @Deprecated
+    public void concetenateTransform(AffineTransform modTransform) {
+        concatenateTransform(modTransform);
+    }
+
+    /**
+     * Concatenate the specified transform with the current transform.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     */
+    public void concatenateTransform(AffineTransform modTransform) {
+        transform.concatenate(modTransform);
+    }
+
+    /**
+     * Gets the transform.
+     * 
+     * @return the transform
+     */
+    public AffineTransform getTransform() {
+        return (AffineTransform)transform.clone();
+    }
+
+    /**
+     * Sets the area of interest.
+     * 
+     * @param newAoi the new area of interest
+     */
+    public void setAreaOfInterest(Shape newAoi) {
+        aoi = newAoi;
+    }
+
+    /**
+     * Gets the area of interest.
+     * 
+     * @return the area of interest
+     */
+    public Shape getAreaOfInterest() {
+        return aoi;
+    }
+
+    /**
+     * Sets the rendering hints.
+     * 
+     * @param hints the new rendering hints
+     */
+    public void setRenderingHints(RenderingHints hints) {
+        this.hints = hints;
+    }
+
+    /**
+     * Gets the rendering hints.
+     * 
+     * @return the rendering hints
+     */
+    public RenderingHints getRenderingHints() {
+        return hints;
+    }
+}
diff --git a/awt/java/awt/image/renderable/RenderableImage.java b/awt/java/awt/image/renderable/RenderableImage.java
new file mode 100644
index 0000000..885dc06
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImage.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+/**
+ * The Interface RenderableImage is implemented by an object that
+ * collects all of the image-specific data that defines a single image 
+ * that could be rendered to different rendering targets.
+ */
+public interface RenderableImage {
+
+    /** The Constant HINTS_OBSERVED indicates that the rendering
+     * hints are applied rather than ignored. */
+    public static final String HINTS_OBSERVED = "HINTS_OBSERVED"; //$NON-NLS-1$
+
+    /**
+     * Gets the property from the RenderableImage's parameter block.
+     * 
+     * @param name the name of the property to get.
+     * 
+     * @return the value of the property
+     */
+    public Object getProperty(String name);
+
+    /**
+     * Creates the rendered image based on the information contained 
+     * in the parameters and the render context.
+     * 
+     * @param renderContext the render context giving rendering specifications
+     * such as transformations
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage createRendering(RenderContext renderContext);
+
+    /**
+     * Creates the scaled rendered image based on the information contained 
+     * in the parameters and the render context.
+     * 
+     * @param w the desired width after scaling or zero if the scaling 
+     * should be proportional, based on the height
+     * @param h the desired height after scaling or zero if the scaling 
+     * should be proportional, based on the width
+     * @param hints the rendering hints to use
+     * 
+     * @return the rendered image
+     * 
+     * @throws IllegalArgumentException if both the height and width are zero
+     */
+    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
+
+    /**
+     * Gets the vector of sources from the parameter block.
+     * 
+     * @return the sources
+     */
+    public Vector<RenderableImage> getSources();
+
+    /**
+     * Gets the names of all of the supported properties in the current context.
+     * 
+     * @return the property names
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Creates the default rendering (using the identity transform
+     * and default render context).
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage createDefaultRendering();
+
+    /**
+     * Checks if this context supports dynamic rendering.
+     * 
+     * @return true, if this context supports dynamic rendering
+     */
+    public boolean isDynamic();
+
+    /**
+     * Gets the width of the image.
+     * 
+     * @return the width of the image
+     */
+    public float getWidth();
+
+    /**
+     * Gets the y coordinate of the upper left corner.
+     * 
+     * @return the y coordinate of the upper left corner
+     */
+    public float getMinY();
+
+    /**
+     * Gets the x coordinate of the upper left corner.
+     * 
+     * @return the x coordinate of the upper left corner
+     */
+    public float getMinX();
+
+    /**
+     * Gets the height of the image.
+     * 
+     * @return the height of the image
+     */
+    public float getHeight();
+
+}
+
diff --git a/awt/java/awt/image/renderable/RenderableImageOp.java b/awt/java/awt/image/renderable/RenderableImageOp.java
new file mode 100644
index 0000000..993ba5f
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImageOp.java
@@ -0,0 +1,182 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RenderableImageOp is a basic implementation of RenderableImage, 
+ * with methods to access the parameter data and perform rendering
+ * operations.
+ */
+public class RenderableImageOp implements RenderableImage {
+
+    /** The CRIF. */
+    ContextualRenderedImageFactory CRIF;
+    
+    /** The param block. */
+    ParameterBlock paramBlock;
+    
+    /** The height. */
+    float minX, minY, width, height;
+
+    /**
+     * Instantiates a new renderable image op.
+     * 
+     * @param CRIF the cRIF
+     * @param paramBlock the param block
+     */
+    public RenderableImageOp(ContextualRenderedImageFactory CRIF, ParameterBlock paramBlock) {
+        this.CRIF = CRIF;
+        this.paramBlock = (ParameterBlock) paramBlock.clone();
+        Rectangle2D r = CRIF.getBounds2D(paramBlock);
+        minX = (float) r.getMinX();
+        minY = (float) r.getMinY();
+        width = (float) r.getWidth();
+        height = (float) r.getHeight();
+    }
+
+    public Object getProperty(String name) {
+        return CRIF.getProperty(paramBlock, name);
+    }
+
+    /**
+     * Sets the parameter block.
+     * 
+     * @param paramBlock the param block
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
+        ParameterBlock oldParam = this.paramBlock;
+        this.paramBlock = (ParameterBlock) paramBlock.clone();
+        return oldParam;
+    }
+
+    public RenderedImage createRendering(RenderContext renderContext) {
+
+        Vector<RenderableImage> sources = getSources();
+        ParameterBlock rdParam = (ParameterBlock) paramBlock.clone();
+
+        if (sources != null) {
+            Vector<Object> rdSources = new Vector<Object>();
+            int i = 0;
+            while (i < sources.size()) {
+                RenderContext newContext = CRIF.mapRenderContext(i, renderContext, paramBlock,
+                        this);
+                RenderedImage rdim = sources.elementAt(i).createRendering(newContext);
+
+                if (rdim != null) {
+                    rdSources.addElement(rdim);
+                }
+                i++;
+            }
+            if (rdSources.size() > 0) {
+                rdParam.setSources(rdSources);
+            }
+        }
+        return CRIF.create(renderContext, rdParam);
+    }
+
+    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints) {
+        if(w == 0 && h == 0) {
+            // awt.60=Width and Height mustn't be equal zero both
+            throw new IllegalArgumentException(Messages.getString("awt.60")); //$NON-NLS-1$
+        }
+        if(w == 0){
+            w = Math.round(h*(getWidth()/getHeight()));
+        }
+
+        if(h == 0){
+            h = Math.round(w*(getHeight()/getWidth()));
+        }
+
+        double sx = (double)w/getWidth();
+        double sy = (double)h/getHeight();
+
+        AffineTransform at = AffineTransform.getScaleInstance(sx, sy);
+        RenderContext context = new RenderContext(at, hints);
+        return createRendering(context);
+    }
+
+    public Vector<RenderableImage> getSources() {
+        if(paramBlock.getNumSources() == 0) {
+            return null;
+        }
+        Vector<RenderableImage> v = new Vector<RenderableImage>();
+        int  i = 0;
+        while(i < paramBlock.getNumSources()){
+            Object o = paramBlock.getSource(i);
+            if(o instanceof RenderableImage){
+                v.addElement((RenderableImage) o);
+            }
+            i++;
+        }
+        return v;
+    }
+
+    public String[] getPropertyNames() {
+        return CRIF.getPropertyNames();
+    }
+
+    /**
+     * Gets the parameter block.
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock getParameterBlock() {
+        return paramBlock;
+    }
+
+    public RenderedImage createDefaultRendering() {
+        AffineTransform at = new AffineTransform();
+        RenderContext context = new RenderContext(at);
+        return createRendering(context);
+    }
+
+    public boolean isDynamic() {
+        return CRIF.isDynamic();
+    }
+
+    public float getWidth() {
+        return width;
+    }
+
+    public float getMinY() {
+        return minY;
+    }
+
+    public float getMinX() {
+        return minX;
+    }
+
+    public float getHeight() {
+        return height;
+    }
+
+}
+
diff --git a/awt/java/awt/image/renderable/RenderableImageProducer.java b/awt/java/awt/image/renderable/RenderableImageProducer.java
new file mode 100644
index 0000000..7fda98c
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImageProducer.java
@@ -0,0 +1,141 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+/**
+ * The Class RenderableImageProducer provides the implementation for 
+ * the image rendering.
+ */
+public class RenderableImageProducer implements ImageProducer, Runnable {
+
+    /** The rbl. */
+    RenderableImage rbl;
+    
+    /** The rc. */
+    RenderContext rc;
+    
+    /** The consumers. */
+    Vector<ImageConsumer> consumers = new Vector<ImageConsumer>();
+
+    /**
+     * Instantiates a new renderable image producer.
+     * 
+     * @param rdblImage the rdbl image
+     * @param rc the rc
+     */
+    public RenderableImageProducer(RenderableImage rdblImage, RenderContext rc) {
+        this.rbl = rdblImage;
+        this.rc = rc;
+    }
+
+    /**
+     * Sets the render context.
+     * 
+     * @param rc the new render context
+     */
+    public synchronized void setRenderContext(RenderContext rc) {
+        this.rc = rc;
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        return consumers.contains(ic);
+    }
+
+    public synchronized void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+        Thread t = new Thread(this, "RenderableImageProducer thread"); //$NON-NLS-1$
+        t.start();
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {}
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        if(ic != null) {
+            consumers.removeElement(ic);
+        }
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if(ic != null && !consumers.contains(ic)){
+            consumers.addElement(ic);
+        }
+    }
+
+    /**
+     * Creates the rendered image in a new thread.
+     */
+    public void run() {
+        if(rbl == null) {
+            return;
+        }
+
+        RenderedImage rd;
+        if(rc != null) {
+            rd = rbl.createRendering(rc);
+        } else {
+            rd = rbl.createDefaultRendering();
+        }
+
+        ColorModel cm = rd.getColorModel();
+        if(cm == null) {
+            cm = ColorModel.getRGBdefault();
+        }
+
+        Raster r = rd.getData();
+        int w = r.getWidth();
+        int h = r.getHeight();
+
+        for (ImageConsumer c : consumers) {
+            c.setDimensions(w, h);
+            c.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
+                    ImageConsumer.COMPLETESCANLINES |
+                    ImageConsumer.SINGLEFRAME |
+                    ImageConsumer.SINGLEPASS);
+        }
+
+        int scanLine[] = new int[w];
+        int pixel[] = null;
+
+        for(int y = 0; y < h; y++){
+            for(int x = 0; x < w; x++){
+                pixel = r.getPixel(x, y, pixel);
+                scanLine[x] = cm.getDataElement(pixel, 0);
+            }
+
+            for (ImageConsumer c : consumers) {
+                c.setPixels(0, y, w, 1, cm, scanLine, 0, w);
+            }
+        }
+
+        for (ImageConsumer c : consumers) {
+            c.imageComplete(ImageConsumer.STATICIMAGEDONE);
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/image/renderable/RenderedImageFactory.java b/awt/java/awt/image/renderable/RenderedImageFactory.java
new file mode 100644
index 0000000..345d82c
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderedImageFactory.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+
+/**
+ * A factory for creating RenderedImage objects based on parameters
+ * and rendering hints.
+ */
+public interface RenderedImageFactory {
+
+    /**
+     * Creates the rendered image.
+     * 
+     * @param a0 the ParameterBlock
+     * @param a1 the RenderingHints
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage create(ParameterBlock a0, RenderingHints a1);
+
+}
+
diff --git a/awt/java/awt/peer/ButtonPeer.java b/awt/java/awt/peer/ButtonPeer.java
new file mode 100644
index 0000000..cc45b49
--- /dev/null
+++ b/awt/java/awt/peer/ButtonPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ButtonPeer {
+
+}
diff --git a/awt/java/awt/peer/CanvasPeer.java b/awt/java/awt/peer/CanvasPeer.java
new file mode 100644
index 0000000..e276366
--- /dev/null
+++ b/awt/java/awt/peer/CanvasPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface CanvasPeer {
+
+}
diff --git a/awt/java/awt/peer/CheckboxMenuItemPeer.java b/awt/java/awt/peer/CheckboxMenuItemPeer.java
new file mode 100644
index 0000000..296f422
--- /dev/null
+++ b/awt/java/awt/peer/CheckboxMenuItemPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface CheckboxMenuItemPeer {
+
+}
diff --git a/awt/java/awt/peer/CheckboxPeer.java b/awt/java/awt/peer/CheckboxPeer.java
new file mode 100644
index 0000000..e9f8dd1
--- /dev/null
+++ b/awt/java/awt/peer/CheckboxPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface CheckboxPeer {
+
+}
diff --git a/awt/java/awt/peer/ChoicePeer.java b/awt/java/awt/peer/ChoicePeer.java
new file mode 100644
index 0000000..57b7629
--- /dev/null
+++ b/awt/java/awt/peer/ChoicePeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ChoicePeer {
+
+}
diff --git a/awt/java/awt/peer/ComponentPeer.java b/awt/java/awt/peer/ComponentPeer.java
new file mode 100644
index 0000000..bc26791
--- /dev/null
+++ b/awt/java/awt/peer/ComponentPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ComponentPeer {
+
+}
diff --git a/awt/java/awt/peer/DialogPeer.java b/awt/java/awt/peer/DialogPeer.java
new file mode 100644
index 0000000..8ae3049
--- /dev/null
+++ b/awt/java/awt/peer/DialogPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface DialogPeer {
+
+}
diff --git a/awt/java/awt/peer/FileDialogPeer.java b/awt/java/awt/peer/FileDialogPeer.java
new file mode 100644
index 0000000..0d15e48
--- /dev/null
+++ b/awt/java/awt/peer/FileDialogPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface FileDialogPeer {
+
+}
diff --git a/awt/java/awt/peer/FontPeer.java b/awt/java/awt/peer/FontPeer.java
new file mode 100644
index 0000000..fd9815f
--- /dev/null
+++ b/awt/java/awt/peer/FontPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface FontPeer {
+
+}
diff --git a/awt/java/awt/peer/FramePeer.java b/awt/java/awt/peer/FramePeer.java
new file mode 100644
index 0000000..9cfc40b
--- /dev/null
+++ b/awt/java/awt/peer/FramePeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface FramePeer {
+
+}
diff --git a/awt/java/awt/peer/LabelPeer.java b/awt/java/awt/peer/LabelPeer.java
new file mode 100644
index 0000000..052ca9d
--- /dev/null
+++ b/awt/java/awt/peer/LabelPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface LabelPeer {
+
+}
diff --git a/awt/java/awt/peer/LightweightPeer.java b/awt/java/awt/peer/LightweightPeer.java
new file mode 100644
index 0000000..1dee905
--- /dev/null
+++ b/awt/java/awt/peer/LightweightPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface LightweightPeer {
+
+}
diff --git a/awt/java/awt/peer/ListPeer.java b/awt/java/awt/peer/ListPeer.java
new file mode 100644
index 0000000..0a27885
--- /dev/null
+++ b/awt/java/awt/peer/ListPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ListPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuBarPeer.java b/awt/java/awt/peer/MenuBarPeer.java
new file mode 100644
index 0000000..3ad2c16
--- /dev/null
+++ b/awt/java/awt/peer/MenuBarPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuBarPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuComponentPeer.java b/awt/java/awt/peer/MenuComponentPeer.java
new file mode 100644
index 0000000..3ac3b34
--- /dev/null
+++ b/awt/java/awt/peer/MenuComponentPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuComponentPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuItemPeer.java b/awt/java/awt/peer/MenuItemPeer.java
new file mode 100644
index 0000000..b133897
--- /dev/null
+++ b/awt/java/awt/peer/MenuItemPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuItemPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuPeer.java b/awt/java/awt/peer/MenuPeer.java
new file mode 100644
index 0000000..d643ce7
--- /dev/null
+++ b/awt/java/awt/peer/MenuPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuPeer {
+
+}
diff --git a/awt/java/awt/peer/MouseInfoPeer.java b/awt/java/awt/peer/MouseInfoPeer.java
new file mode 100644
index 0000000..9173a62
--- /dev/null
+++ b/awt/java/awt/peer/MouseInfoPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MouseInfoPeer {
+
+}
diff --git a/awt/java/awt/peer/PanelPeer.java b/awt/java/awt/peer/PanelPeer.java
new file mode 100644
index 0000000..1faa1fe
--- /dev/null
+++ b/awt/java/awt/peer/PanelPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface PanelPeer {
+
+}
diff --git a/awt/java/awt/peer/PopupMenuPeer.java b/awt/java/awt/peer/PopupMenuPeer.java
new file mode 100644
index 0000000..cf1ef61
--- /dev/null
+++ b/awt/java/awt/peer/PopupMenuPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface PopupMenuPeer {
+
+}
diff --git a/awt/java/awt/peer/ScrollPanePeer.java b/awt/java/awt/peer/ScrollPanePeer.java
new file mode 100644
index 0000000..df3de83
--- /dev/null
+++ b/awt/java/awt/peer/ScrollPanePeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ScrollPanePeer {
+
+}
diff --git a/awt/java/awt/peer/ScrollbarPeer.java b/awt/java/awt/peer/ScrollbarPeer.java
new file mode 100644
index 0000000..eec8961
--- /dev/null
+++ b/awt/java/awt/peer/ScrollbarPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ScrollbarPeer {
+
+}
diff --git a/awt/java/awt/peer/TextAreaPeer.java b/awt/java/awt/peer/TextAreaPeer.java
new file mode 100644
index 0000000..636707f
--- /dev/null
+++ b/awt/java/awt/peer/TextAreaPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface TextAreaPeer {
+
+}
diff --git a/awt/java/awt/peer/TextFieldPeer.java b/awt/java/awt/peer/TextFieldPeer.java
new file mode 100644
index 0000000..2b8232a
--- /dev/null
+++ b/awt/java/awt/peer/TextFieldPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface TextFieldPeer {
+
+}
diff --git a/awt/java/awt/peer/WindowPeer.java b/awt/java/awt/peer/WindowPeer.java
new file mode 100644
index 0000000..384646f
--- /dev/null
+++ b/awt/java/awt/peer/WindowPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface WindowPeer {
+
+}
diff --git a/awt/java/beans/FeatureDescriptor.java b/awt/java/beans/FeatureDescriptor.java
new file mode 100644
index 0000000..2945c65
--- /dev/null
+++ b/awt/java/beans/FeatureDescriptor.java
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package java.beans;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+/**
+ * Common base class for Descriptors.
+ */
+public class FeatureDescriptor {
+
+    private Map<String, Object> values;
+
+    boolean preferred, hidden, expert;
+
+    String shortDescription;
+
+    String name;
+
+    String displayName;
+
+    /**
+     * <p>
+     * Constructs an instance.
+     * </p>
+     */
+    public FeatureDescriptor() {
+        this.values = new HashMap<String, Object>();
+    }
+
+    /**
+     * <p>
+     * Sets the value for the named attribute.
+     * </p>
+     * 
+     * @param attributeName
+     *            The name of the attribute to set a value with.
+     * @param value
+     *            The value to set.
+     */
+    public void setValue(String attributeName, Object value) {
+        if (attributeName == null || value == null) {
+            throw new NullPointerException();
+        }
+        values.put(attributeName, value);
+    }
+
+    /**
+     * <p>
+     * Gets the value associated with the named attribute.
+     * </p>
+     * 
+     * @param attributeName
+     *            The name of the attribute to get a value for.
+     * @return The attribute's value.
+     */
+    public Object getValue(String attributeName) {
+        Object result = null;
+        if (attributeName != null) {
+            result = values.get(attributeName);
+        }
+        return result;
+    }
+
+    /**
+     * <p>
+     * Enumerates the attribute names.
+     * </p>
+     * 
+     * @return An instance of {@link Enumeration}.
+     */
+    public Enumeration<String> attributeNames() {
+        // Create a new list, so that the references are copied
+        return Collections.enumeration(new LinkedList<String>(values.keySet()));
+    }
+
+    /**
+     * <p>
+     * Sets the short description.
+     * </p>
+     * 
+     * @param text
+     *            The description to set.
+     */
+    public void setShortDescription(String text) {
+        this.shortDescription = text;
+    }
+
+    /**
+     * <p>
+     * Sets the name.
+     * </p>
+     * 
+     * @param name
+     *            The name to set.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * <p>
+     * Sets the display name.
+     * </p>
+     * 
+     * @param displayName
+     *            The display name to set.
+     */
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    /**
+     * <p>
+     * Gets the short description or {@link #getDisplayName()} if not set.
+     * </p>
+     * 
+     * @return The description.
+     */
+    public String getShortDescription() {
+        return shortDescription == null ? getDisplayName() : shortDescription;
+    }
+
+    /**
+     * <p>
+     * Gets the name.
+     * </p>
+     * 
+     * @return The name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * <p>
+     * Gets the display name or {@link #getName()} if not set.
+     * </p>
+     * 
+     * @return The display name.
+     */
+    public String getDisplayName() {
+        return displayName == null ? getName() : displayName;
+    }
+
+    /**
+     * <p>
+     * Sets the preferred indicator.
+     * </p>
+     * 
+     * @param preferred
+     *            <code>true</code> if preferred, <code>false</code>
+     *            otherwise.
+     */
+    public void setPreferred(boolean preferred) {
+        this.preferred = preferred;
+    }
+
+    /**
+     * <p>
+     * Sets the hidden indicator.
+     * </p>
+     * 
+     * @param hidden
+     *            <code>true</code> if hidden, <code>false</code> otherwise.
+     */
+    public void setHidden(boolean hidden) {
+        this.hidden = hidden;
+    }
+
+    /**
+     * <p>
+     * Sets the expert indicator.
+     * </p>
+     * 
+     * @param expert
+     *            <code>true</code> if expert, <code>false</code> otherwise.
+     */
+    public void setExpert(boolean expert) {
+        this.expert = expert;
+    }
+
+    /**
+     * <p>
+     * Indicates if this feature is preferred.
+     * </p>
+     * 
+     * @return <code>true</code> if preferred, <code>false</code> otherwise.
+     */
+    public boolean isPreferred() {
+        return preferred;
+    }
+
+    /**
+     * <p>
+     * Indicates if this feature is hidden.
+     * </p>
+     * 
+     * @return <code>true</code> if hidden, <code>false</code> otherwise.
+     */
+    public boolean isHidden() {
+        return hidden;
+    }
+
+    /**
+     * <p>
+     * Indicates if this feature is an expert feature.
+     * </p>
+     * 
+     * @return <code>true</code> if hidden, <code>false</code> otherwise.
+     */
+    public boolean isExpert() {
+        return expert;
+    }
+}
diff --git a/awt/java/beans/IndexedPropertyChangeEvent.java b/awt/java/beans/IndexedPropertyChangeEvent.java
new file mode 100644
index 0000000..c9084c6
--- /dev/null
+++ b/awt/java/beans/IndexedPropertyChangeEvent.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package java.beans;
+
+/**
+ * A type of {@link PropertyChangeEvent} that indicates that an indexed property
+ * has changed.
+ * 
+ * @since 1.5
+ */
+public class IndexedPropertyChangeEvent extends PropertyChangeEvent {
+
+    private static final long serialVersionUID = -320227448495806870L;
+
+    private final int index;
+
+    /**
+     * Creates a new property changed event with an indication of the property
+     * index.
+     * 
+     * @param source
+     *            the changed bean.
+     * @param propertyName
+     *            the changed property, or <code>null</code> to indicate an
+     *            unspecified set of the properties have changed.
+     * @param oldValue
+     *            the previous value of the property, or <code>null</code> if
+     *            the <code>propertyName</code> is <code>null</code> or the
+     *            previous value is unknown.
+     * @param newValue
+     *            the new value of the property, or <code>null</code> if the
+     *            <code>propertyName</code> is <code>null</code> or the new
+     *            value is unknown..
+     * @param index
+     *            the index of the property.
+     */
+    public IndexedPropertyChangeEvent(Object source, String propertyName,
+            Object oldValue, Object newValue, int index) {
+        super(source, propertyName, oldValue, newValue);
+        this.index = index;
+    }
+
+    /**
+     * Answer the index of the property that was changed in this event.
+     * 
+     * @return The property element index.
+     */
+    public int getIndex() {
+        return index;
+    }
+}
diff --git a/awt/java/beans/IndexedPropertyDescriptor.java b/awt/java/beans/IndexedPropertyDescriptor.java
new file mode 100644
index 0000000..25667d9
--- /dev/null
+++ b/awt/java/beans/IndexedPropertyDescriptor.java
@@ -0,0 +1,227 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import org.apache.harmony.beans.internal.nls.Messages;
+
+public class IndexedPropertyDescriptor extends PropertyDescriptor {
+    private Method indexedGetter;
+
+    private Method indexedSetter;
+
+    public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass,
+            String getterName, String setterName, String indexedGetterName,
+            String indexedSetterName) throws IntrospectionException {
+        super(propertyName, beanClass, getterName, setterName);
+
+        // RI behaves like this
+        if (indexedGetterName == null && indexedSetterName == null &&
+                (getterName != null || setterName != null)) {
+            throw new IntrospectionException(Messages.getString("beans.50"));
+        }
+        setIndexedReadMethod(beanClass, indexedGetterName);
+        setIndexedWriteMethod(beanClass, indexedSetterName);
+    }
+
+    public IndexedPropertyDescriptor(String propertyName, Method getter, Method setter,
+            Method indexedGetter, Method indexedSetter) throws IntrospectionException {
+        super(propertyName, getter, setter);
+        
+        // we need this in order to be compatible with RI
+        if (indexedGetter == null && indexedSetter == null &&
+                (getter != null || setter != null)) {
+            throw new IntrospectionException(Messages.getString("beans.50"));
+        }
+        setIndexedReadMethod(indexedGetter);
+        setIndexedWriteMethod(indexedSetter);
+    }
+
+    public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass)
+            throws IntrospectionException {
+        super(propertyName, beanClass, null, null);
+        String getterName;
+        String setterName;
+        String indexedGetterName;
+        String indexedSetterName;
+
+        // array getter
+        getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
+        if (hasMethod(beanClass, getterName)) {
+            setReadMethod(beanClass, getterName);
+        }
+        // array setter
+        setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
+        if (hasMethod(beanClass, setterName)) {
+            setWriteMethod(beanClass, setterName);
+        }
+        // indexed getter
+        indexedGetterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
+        if (hasMethod(beanClass, indexedGetterName)) {
+            setIndexedReadMethod(beanClass, indexedGetterName);
+        }
+        // indexed setter
+        indexedSetterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
+        if (hasMethod(beanClass, indexedSetterName)) {
+            setIndexedWriteMethod(beanClass, indexedSetterName);
+        }
+        // RI seems to behave a bit differently
+        if (indexedGetter == null && indexedSetter == null &&
+                getReadMethod() == null && getWriteMethod() == null) {
+            throw new IntrospectionException(
+                    Messages.getString("beans.01", propertyName)); //$NON-NLS-1$
+        }
+        if (indexedGetter == null && indexedSetter == null) {
+            // not an indexed property indeed
+            throw new IntrospectionException(Messages.getString("beans.50"));
+        }
+    }
+
+    public void setIndexedReadMethod(Method indexedGetter) throws IntrospectionException {
+        if (indexedGetter != null) {
+            int modifiers = indexedGetter.getModifiers();
+            Class<?>[] parameterTypes;
+            Class<?> returnType;
+            Class<?> indexedPropertyType;
+
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.21")); //$NON-NLS-1$
+            }
+            parameterTypes = indexedGetter.getParameterTypes();
+            if (parameterTypes.length != 1) {
+                throw new IntrospectionException(Messages.getString("beans.22")); //$NON-NLS-1$
+            }
+            if (!parameterTypes[0].equals(int.class)) {
+                throw new IntrospectionException(Messages.getString("beans.23")); //$NON-NLS-1$
+            }
+            returnType = indexedGetter.getReturnType();
+            indexedPropertyType = getIndexedPropertyType();
+            if ((indexedPropertyType != null) && !returnType.equals(indexedPropertyType)) {
+                throw new IntrospectionException(Messages.getString("beans.24")); //$NON-NLS-1$
+            }
+        }
+        this.indexedGetter = indexedGetter;
+    }
+
+    public void setIndexedWriteMethod(Method indexedSetter) throws IntrospectionException {
+        if (indexedSetter != null) {
+            int modifiers = indexedSetter.getModifiers();
+            Class<?>[] parameterTypes;
+            Class<?> firstParameterType;
+            Class<?> secondParameterType;
+            Class<?> propType;
+
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.25")); //$NON-NLS-1$
+            }
+            parameterTypes = indexedSetter.getParameterTypes();
+            if (parameterTypes.length != 2) {
+                throw new IntrospectionException(Messages.getString("beans.26")); //$NON-NLS-1$
+            }
+            firstParameterType = parameterTypes[0];
+            if (!firstParameterType.equals(int.class)) {
+                throw new IntrospectionException(Messages.getString("beans.27")); //$NON-NLS-1$
+            }
+            secondParameterType = parameterTypes[1];
+            propType = getIndexedPropertyType();
+            if (propType != null && !secondParameterType.equals(propType)) {
+                throw new IntrospectionException(Messages.getString("beans.28")); //$NON-NLS-1$
+            }
+        }
+        this.indexedSetter = indexedSetter;
+    }
+
+    public Method getIndexedWriteMethod() {
+        return indexedSetter;
+    }
+
+    public Method getIndexedReadMethod() {
+        return indexedGetter;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        boolean result = super.equals(obj);
+        
+        if (result) {
+            IndexedPropertyDescriptor pd = (IndexedPropertyDescriptor) obj;
+    
+            if (indexedGetter != null) {
+                result = indexedGetter.equals(pd.getIndexedReadMethod());
+            } else if (result && indexedGetter == null) {
+                result = pd.getIndexedReadMethod() == null;
+            }
+                
+            if (result) {
+                if (indexedSetter != null) {
+                    result = indexedSetter.equals(pd.getIndexedWriteMethod());
+                } else if (indexedSetter == null) {
+                    result = pd.getIndexedWriteMethod() == null;
+                }
+            }
+        }
+            
+        return result;
+    }
+
+    public Class<?> getIndexedPropertyType() {
+        Class<?> result = null;
+
+        if (indexedGetter != null) {
+            result = indexedGetter.getReturnType();
+        } else if (indexedSetter != null) {
+            Class<?>[] parameterTypes = indexedSetter.getParameterTypes();
+
+            result = parameterTypes[1];
+        }
+        return result;
+    }
+
+    private void setIndexedReadMethod(Class<?> beanClass, String indexedGetterName) {
+        Method[] getters = findMethods(beanClass, indexedGetterName);
+        boolean result = false;
+
+        for (Method element : getters) {
+            try {
+                setIndexedReadMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {}
+
+            if (result) {
+                break;
+            }
+        }
+    }
+
+    private void setIndexedWriteMethod(Class<?> beanClass, String indexedSetterName) {
+        Method[] setters = findMethods(beanClass, indexedSetterName);
+        boolean result = false;
+
+        for (Method element : setters) {
+            try {
+                setIndexedWriteMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {}
+
+            if (result) {
+                break;
+            }
+        }
+    }
+}
diff --git a/awt/java/beans/IntrospectionException.java b/awt/java/beans/IntrospectionException.java
new file mode 100644
index 0000000..c895afe
--- /dev/null
+++ b/awt/java/beans/IntrospectionException.java
@@ -0,0 +1,27 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+public class IntrospectionException extends Exception {
+
+    static final long serialVersionUID = -3728150539969542619L;
+
+    public IntrospectionException(String message) {
+        super(message);
+    }
+}
diff --git a/awt/java/beans/PropertyChangeEvent.java b/awt/java/beans/PropertyChangeEvent.java
new file mode 100644
index 0000000..97c703a
--- /dev/null
+++ b/awt/java/beans/PropertyChangeEvent.java
@@ -0,0 +1,62 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.util.EventObject;
+
+public class PropertyChangeEvent extends EventObject {
+
+    private static final long serialVersionUID = 7042693688939648123L;
+
+    String propertyName;
+
+    Object oldValue;
+
+    Object newValue;
+
+    Object propagationId;
+
+    public PropertyChangeEvent(Object source, String propertyName,
+            Object oldValue, Object newValue) {
+        super(source);
+
+        this.propertyName = propertyName;
+        this.oldValue = oldValue;
+        this.newValue = newValue;
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void setPropagationId(Object propagationId) {
+        this.propagationId = propagationId;
+    }
+
+    public Object getPropagationId() {
+        return propagationId;
+    }
+
+    public Object getOldValue() {
+        return oldValue;
+    }
+
+    public Object getNewValue() {
+        return newValue;
+    }
+}
diff --git a/awt/java/beans/PropertyChangeListener.java b/awt/java/beans/PropertyChangeListener.java
new file mode 100644
index 0000000..94422c0
--- /dev/null
+++ b/awt/java/beans/PropertyChangeListener.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.util.EventListener;
+
+public interface PropertyChangeListener extends EventListener {
+
+    public void propertyChange(PropertyChangeEvent event);
+}
diff --git a/awt/java/beans/PropertyChangeListenerProxy.java b/awt/java/beans/PropertyChangeListenerProxy.java
new file mode 100644
index 0000000..f4f3aec
--- /dev/null
+++ b/awt/java/beans/PropertyChangeListenerProxy.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.util.EventListenerProxy;
+
+public class PropertyChangeListenerProxy extends EventListenerProxy implements
+        PropertyChangeListener {
+
+    String propertyName;
+
+    public PropertyChangeListenerProxy(String propertyName,
+            PropertyChangeListener listener) {
+        super(listener);
+        this.propertyName = propertyName;
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void propertyChange(PropertyChangeEvent event) {
+        PropertyChangeListener listener = (PropertyChangeListener) getListener();
+        listener.propertyChange(event);
+    }
+}
diff --git a/awt/java/beans/PropertyChangeSupport.java b/awt/java/beans/PropertyChangeSupport.java
new file mode 100644
index 0000000..d56e63a
--- /dev/null
+++ b/awt/java/beans/PropertyChangeSupport.java
@@ -0,0 +1,351 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class PropertyChangeSupport implements Serializable {
+
+    private static final long serialVersionUID = 6401253773779951803l;
+
+    private transient Object sourceBean;
+
+    private transient List<PropertyChangeListener> allPropertiesChangeListeners =
+            new ArrayList<PropertyChangeListener>();
+
+    private transient Map<String, List<PropertyChangeListener>>
+            selectedPropertiesChangeListeners =
+            new HashMap<String, List<PropertyChangeListener>>();
+
+    // fields for serialization compatibility
+    private Hashtable<String, List<PropertyChangeListener>> children;
+
+    private Object source;
+
+    private int propertyChangeSupportSerializedDataVersion = 1;
+
+    public PropertyChangeSupport(Object sourceBean) {
+        if (sourceBean == null) {
+            throw new NullPointerException();
+        }
+        this.sourceBean = sourceBean;
+    }
+
+    public void firePropertyChange(String propertyName, Object oldValue,
+            Object newValue) {
+        PropertyChangeEvent event = createPropertyChangeEvent(propertyName,
+                oldValue, newValue);
+        doFirePropertyChange(event);
+    }
+
+    public void fireIndexedPropertyChange(String propertyName, int index,
+            Object oldValue, Object newValue) {
+
+        // nulls and equals check done in doFire...
+        doFirePropertyChange(new IndexedPropertyChangeEvent(sourceBean,
+                propertyName, oldValue, newValue, index));
+    }
+
+    public synchronized void removePropertyChangeListener(String propertyName,
+            PropertyChangeListener listener) {
+        if ((propertyName != null) && (listener != null)) {
+            List<PropertyChangeListener> listeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (listeners != null) {
+                listeners.remove(listener);
+            }
+        }
+    }
+
+    public synchronized void addPropertyChangeListener(String propertyName,
+            PropertyChangeListener listener) {
+        if ((listener != null) && (propertyName != null)) {
+            List<PropertyChangeListener> listeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (listeners == null) {
+                listeners = new ArrayList<PropertyChangeListener>();
+                selectedPropertiesChangeListeners.put(propertyName, listeners);
+            }
+
+            // RI compatibility
+            if (listener instanceof PropertyChangeListenerProxy) {
+                PropertyChangeListenerProxy proxy =
+                        (PropertyChangeListenerProxy) listener;
+
+                listeners.add(new PropertyChangeListenerProxy(
+                        proxy.getPropertyName(),
+                        (PropertyChangeListener) proxy.getListener()));
+            } else {
+                listeners.add(listener);
+            }
+        }
+    }
+
+    public synchronized PropertyChangeListener[] getPropertyChangeListeners(
+            String propertyName) {
+        List<PropertyChangeListener> listeners = null;
+
+        if (propertyName != null) {
+            listeners = selectedPropertiesChangeListeners.get(propertyName);
+        }
+
+        return (listeners == null) ? new PropertyChangeListener[] {}
+                : listeners.toArray(
+                        new PropertyChangeListener[listeners.size()]);
+    }
+
+    public void firePropertyChange(String propertyName, boolean oldValue,
+            boolean newValue) {
+        PropertyChangeEvent event = createPropertyChangeEvent(propertyName,
+                oldValue, newValue);
+        doFirePropertyChange(event);
+    }
+
+    public void fireIndexedPropertyChange(String propertyName, int index,
+            boolean oldValue, boolean newValue) {
+
+        if (oldValue != newValue) {
+            fireIndexedPropertyChange(propertyName, index, Boolean
+                    .valueOf(oldValue), Boolean.valueOf(newValue));
+        }
+    }
+
+    public void firePropertyChange(String propertyName, int oldValue,
+            int newValue) {
+        PropertyChangeEvent event = createPropertyChangeEvent(propertyName,
+                oldValue, newValue);
+        doFirePropertyChange(event);
+    }
+
+    public void fireIndexedPropertyChange(String propertyName, int index,
+            int oldValue, int newValue) {
+
+        if (oldValue != newValue) {
+            fireIndexedPropertyChange(propertyName, index,
+                    new Integer(oldValue), new Integer(newValue));
+        }
+    }
+
+    public synchronized boolean hasListeners(String propertyName) {
+        boolean result = allPropertiesChangeListeners.size() > 0;
+        if (!result && (propertyName != null)) {
+            List<PropertyChangeListener> listeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+            if (listeners != null) {
+                result = listeners.size() > 0;
+            }
+        }
+        return result;
+    }
+
+    public synchronized void removePropertyChangeListener(
+            PropertyChangeListener listener) {
+        if (listener != null) {
+            if (listener instanceof PropertyChangeListenerProxy) {
+                String name = ((PropertyChangeListenerProxy) listener)
+                        .getPropertyName();
+                PropertyChangeListener lst = (PropertyChangeListener)
+                        ((PropertyChangeListenerProxy) listener).getListener();
+
+                removePropertyChangeListener(name, lst);
+            } else {
+                allPropertiesChangeListeners.remove(listener);
+            }
+        }
+    }
+
+    public synchronized void addPropertyChangeListener(
+            PropertyChangeListener listener) {
+        if (listener != null) {
+            if (listener instanceof PropertyChangeListenerProxy) {
+                String name = ((PropertyChangeListenerProxy) listener)
+                        .getPropertyName();
+                PropertyChangeListener lst = (PropertyChangeListener)
+                        ((PropertyChangeListenerProxy) listener).getListener();
+                addPropertyChangeListener(name, lst);
+            } else {
+                allPropertiesChangeListeners.add(listener);
+            }
+        }
+    }
+
+    public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
+        ArrayList<PropertyChangeListener> result =
+                new ArrayList<PropertyChangeListener>(
+                        allPropertiesChangeListeners);
+
+        for (String propertyName : selectedPropertiesChangeListeners.keySet()) {
+            List<PropertyChangeListener> selectedListeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (selectedListeners != null) {
+
+                for (PropertyChangeListener listener : selectedListeners) {
+                    result.add(new PropertyChangeListenerProxy(propertyName,
+                            listener));
+                }
+            }
+        }
+
+        return result.toArray(new PropertyChangeListener[result.size()]);
+    }
+
+    private void writeObject(ObjectOutputStream oos) throws IOException {
+        List<PropertyChangeListener> allSerializedPropertiesChangeListeners =
+                new ArrayList<PropertyChangeListener>();
+
+        for (PropertyChangeListener pcl : allPropertiesChangeListeners) {
+            if (pcl instanceof Serializable) {
+                allSerializedPropertiesChangeListeners.add(pcl);
+            }
+        }
+
+        Map<String, List<PropertyChangeListener>>
+                selectedSerializedPropertiesChangeListeners =
+                        new HashMap<String, List<PropertyChangeListener>>();
+
+        for (String propertyName : selectedPropertiesChangeListeners.keySet()) {
+            List<PropertyChangeListener> keyValues =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (keyValues != null) {
+                List<PropertyChangeListener> serializedPropertiesChangeListeners
+                        = new ArrayList<PropertyChangeListener>();
+
+                for (PropertyChangeListener pcl : keyValues) {
+                    if (pcl instanceof Serializable) {
+                        serializedPropertiesChangeListeners.add(pcl);
+                    }
+                }
+
+                if (!serializedPropertiesChangeListeners.isEmpty()) {
+                    selectedSerializedPropertiesChangeListeners.put(
+                            propertyName, serializedPropertiesChangeListeners);
+                }
+            }
+        }
+
+        children = new Hashtable<String, List<PropertyChangeListener>>(
+                selectedSerializedPropertiesChangeListeners);
+        children.put("", allSerializedPropertiesChangeListeners); //$NON-NLS-1$
+        oos.writeObject(children);
+
+        Object source = null;
+        if (sourceBean instanceof Serializable) {
+            source = sourceBean;
+        }
+        oos.writeObject(source);
+
+        oos.writeInt(propertyChangeSupportSerializedDataVersion);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream ois) throws IOException,
+            ClassNotFoundException {
+        children = (Hashtable<String, List<PropertyChangeListener>>) ois
+                .readObject();
+
+        selectedPropertiesChangeListeners = new HashMap<String, List<PropertyChangeListener>>(
+                children);
+        allPropertiesChangeListeners = selectedPropertiesChangeListeners
+                .remove(""); //$NON-NLS-1$
+        if (allPropertiesChangeListeners == null) {
+            allPropertiesChangeListeners = new ArrayList<PropertyChangeListener>();
+        }
+
+        sourceBean = ois.readObject();
+        propertyChangeSupportSerializedDataVersion = ois.readInt();
+    }
+
+    public void firePropertyChange(PropertyChangeEvent event) {
+        doFirePropertyChange(event);
+    }
+
+    private PropertyChangeEvent createPropertyChangeEvent(String propertyName,
+            Object oldValue, Object newValue) {
+        return new PropertyChangeEvent(sourceBean, propertyName, oldValue,
+                newValue);
+    }
+
+    private PropertyChangeEvent createPropertyChangeEvent(String propertyName,
+            boolean oldValue, boolean newValue) {
+        return new PropertyChangeEvent(sourceBean, propertyName, oldValue,
+                newValue);
+    }
+
+    private PropertyChangeEvent createPropertyChangeEvent(String propertyName,
+            int oldValue, int newValue) {
+        return new PropertyChangeEvent(sourceBean, propertyName, oldValue,
+                newValue);
+    }
+
+    private void doFirePropertyChange(PropertyChangeEvent event) {
+        String propertyName = event.getPropertyName();
+        Object oldValue = event.getOldValue();
+        Object newValue = event.getNewValue();
+
+        if ((newValue != null) && (oldValue != null)
+                && newValue.equals(oldValue)) {
+            return;
+        }
+
+        /*
+         * Copy the listeners collections so they can be modified while we fire
+         * events.
+         */
+
+        // Listeners to all property change events
+        PropertyChangeListener[] listensToAll;
+        // Listens to a given property change
+        PropertyChangeListener[] listensToOne = null;
+        synchronized (this) {
+            listensToAll = allPropertiesChangeListeners
+                    .toArray(new PropertyChangeListener[allPropertiesChangeListeners
+                            .size()]);
+
+            List<PropertyChangeListener> listeners = selectedPropertiesChangeListeners
+                    .get(propertyName);
+            if (listeners != null) {
+                listensToOne = listeners
+                        .toArray(new PropertyChangeListener[listeners.size()]);
+            }
+        }
+
+        // Fire the listeners
+        for (PropertyChangeListener listener : listensToAll) {
+            listener.propertyChange(event);
+        }
+        if (listensToOne != null) {
+            for (PropertyChangeListener listener : listensToOne) {
+                listener.propertyChange(event);
+            }
+        }
+    }
+
+}
diff --git a/awt/java/beans/PropertyDescriptor.java b/awt/java/beans/PropertyDescriptor.java
new file mode 100644
index 0000000..9389152
--- /dev/null
+++ b/awt/java/beans/PropertyDescriptor.java
@@ -0,0 +1,300 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Vector;
+import org.apache.harmony.beans.internal.nls.Messages;
+
+public class PropertyDescriptor extends FeatureDescriptor {
+    private Method getter;
+
+    private Method setter;
+
+    private Class<?> propertyEditorClass;
+
+    private boolean constrained;
+
+    private boolean bound;
+
+    public PropertyDescriptor(String propertyName, Class<?> beanClass, String getterName,
+            String setterName) throws IntrospectionException {
+        super();
+        if (beanClass == null) {
+            throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
+        }
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
+        }
+        this.setName(propertyName);
+        this.setDisplayName(propertyName);
+        if (setterName != null) {
+            if (hasMethod(beanClass, setterName)) {
+                setWriteMethod(beanClass, setterName);
+            } else {
+                throw new IntrospectionException(Messages.getString("beans.20")); //$NON-NLS-1$
+            }
+        }
+        if (getterName != null) {
+            if (hasMethod(beanClass, getterName)) {
+                setReadMethod(beanClass, getterName);
+            } else {
+                throw new IntrospectionException(Messages.getString("beans.1F")); //$NON-NLS-1$
+            }
+        }
+    }
+
+    public PropertyDescriptor(String propertyName, Method getter, Method setter)
+            throws IntrospectionException {
+        super();
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
+        }
+        this.setName(propertyName);
+        this.setDisplayName(propertyName);
+        setWriteMethod(setter);
+        setReadMethod(getter);
+    }
+
+    public PropertyDescriptor(String propertyName, Class<?> beanClass)
+            throws IntrospectionException {
+        String getterName;
+        String setterName;
+        if (beanClass == null) {
+            throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
+        }
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
+        }
+        this.setName(propertyName);
+        this.setDisplayName(propertyName);
+        getterName = createDefaultMethodName(propertyName, "is"); //$NON-NLS-1$
+        if (hasMethod(beanClass, getterName)) {
+            setReadMethod(beanClass, getterName);
+        } else {
+            getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
+            if (hasMethod(beanClass, getterName)) {
+                setReadMethod(beanClass, getterName);
+            }
+        }
+        setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
+        if (hasMethod(beanClass, setterName)) {
+            setWriteMethod(beanClass, setterName);
+        }
+        if (getter == null && setter == null) {
+            throw new IntrospectionException(Messages.getString("beans.01", propertyName)); //$NON-NLS-1$
+        }
+    }
+
+    public void setWriteMethod(Method setter) throws IntrospectionException {
+        if (setter != null) {
+            int modifiers = setter.getModifiers();
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.05")); //$NON-NLS-1$
+            }
+            Class<?>[] parameterTypes = setter.getParameterTypes();
+            if (parameterTypes.length != 1) {
+                throw new IntrospectionException(Messages.getString("beans.06")); //$NON-NLS-1$
+            }
+            Class<?> parameterType = parameterTypes[0];
+            Class<?> propertyType = getPropertyType();
+            if (propertyType != null && !propertyType.equals(parameterType)) {
+                throw new IntrospectionException(Messages.getString("beans.07")); //$NON-NLS-1$
+            }
+        }
+        this.setter = setter;
+    }
+
+    public void setReadMethod(Method getter) throws IntrospectionException {
+        if (getter != null) {
+            int modifiers = getter.getModifiers();
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.0A")); //$NON-NLS-1$
+            }
+            Class<?>[] parameterTypes = getter.getParameterTypes();
+            if (parameterTypes.length != 0) {
+                throw new IntrospectionException(Messages.getString("beans.08")); //$NON-NLS-1$
+            }
+            Class<?> returnType = getter.getReturnType();
+            if (returnType.equals(Void.TYPE)) {
+                throw new IntrospectionException(Messages.getString("beans.33")); //$NON-NLS-1$
+            }
+            Class<?> propertyType = getPropertyType();
+            if ((propertyType != null) && !returnType.equals(propertyType)) {
+                throw new IntrospectionException(Messages.getString("beans.09")); //$NON-NLS-1$
+            }
+        }
+        this.getter = getter;
+    }
+
+    public Method getWriteMethod() {
+        return setter;
+    }
+
+    public Method getReadMethod() {
+        return getter;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        boolean result = (object != null && object instanceof PropertyDescriptor);
+        if (result) {
+            PropertyDescriptor pd = (PropertyDescriptor) object;
+            boolean gettersAreEqual = (this.getter == null) && (pd.getReadMethod() == null)
+                    || (this.getter != null) && (this.getter.equals(pd.getReadMethod()));
+            boolean settersAreEqual = (this.setter == null) && (pd.getWriteMethod() == null)
+                    || (this.setter != null) && (this.setter.equals(pd.getWriteMethod()));
+            boolean propertyTypesAreEqual = this.getPropertyType() == pd.getPropertyType();
+            boolean propertyEditorClassesAreEqual = this.getPropertyEditorClass() == pd
+                    .getPropertyEditorClass();
+            boolean boundPropertyAreEqual = this.isBound() == pd.isBound();
+            boolean constrainedPropertyAreEqual = this.isConstrained() == pd.isConstrained();
+            result = gettersAreEqual && settersAreEqual && propertyTypesAreEqual
+                    && propertyEditorClassesAreEqual && boundPropertyAreEqual
+                    && constrainedPropertyAreEqual;
+        }
+        return result;
+    }
+
+    public void setPropertyEditorClass(Class<?> propertyEditorClass) {
+        this.propertyEditorClass = propertyEditorClass;
+    }
+
+    public Class<?> getPropertyType() {
+        Class<?> result = null;
+        if (getter != null) {
+            result = getter.getReturnType();
+        } else if (setter != null) {
+            Class<?>[] parameterTypes = setter.getParameterTypes();
+            result = parameterTypes[0];
+        }
+        return result;
+    }
+
+    public Class<?> getPropertyEditorClass() {
+        return propertyEditorClass;
+    }
+
+    public void setConstrained(boolean constrained) {
+        this.constrained = constrained;
+    }
+
+    public void setBound(boolean bound) {
+        this.bound = bound;
+    }
+
+    public boolean isConstrained() {
+        return constrained;
+    }
+
+    public boolean isBound() {
+        return bound;
+    }
+
+    boolean hasMethod(Class<?> beanClass, String methodName) {
+        Method[] methods = findMethods(beanClass, methodName);
+        return (methods.length > 0);
+    }
+
+    String createDefaultMethodName(String propertyName, String prefix) {
+        String result = null;
+        if (propertyName != null) {
+            String bos = propertyName.substring(0, 1).toUpperCase();
+            String eos = propertyName.substring(1, propertyName.length());
+            result = prefix + bos + eos;
+        }
+        return result;
+    }
+
+    Method[] findMethods(Class<?> aClass, String methodName) {
+        Method[] allMethods = aClass.getMethods();
+        Vector<Method> matchedMethods = new Vector<Method>();
+        Method[] result;
+        for (Method method : allMethods) {
+            if (method.getName().equals(methodName)) {
+                matchedMethods.add(method);
+            }
+        }
+        result = new Method[matchedMethods.size()];
+        for (int j = 0; j < matchedMethods.size(); ++j) {
+            result[j] = matchedMethods.elementAt(j);
+        }
+        return result;
+    }
+
+    void setReadMethod(Class<?> beanClass, String getterName) {
+        boolean result = false;
+        Method[] getters = findMethods(beanClass, getterName);
+        for (Method element : getters) {
+            try {
+                setReadMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {
+            }
+            if (result) {
+                break;
+            }
+        }
+    }
+
+    void setWriteMethod(Class<?> beanClass, String setterName) throws IntrospectionException {
+        boolean result = false;
+        Method[] setters = findMethods(beanClass, setterName);
+        for (Method element : setters) {
+            try {
+                setWriteMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {
+            }
+            if (result) {
+                break;
+            }
+        }
+    }
+
+    public PropertyEditor createPropertyEditor(Object bean) {
+        PropertyEditor editor;
+        if (propertyEditorClass == null) {
+            return null;
+        }
+        if (!PropertyEditor.class.isAssignableFrom(propertyEditorClass)) {
+            // beans.48=Property editor is not assignable from the
+            // PropertyEditor interface
+            throw new ClassCastException(Messages.getString("beans.48")); //$NON-NLS-1$
+        }
+        try {
+            Constructor<?> constr;
+            try {
+                // try to look for the constructor with single Object argument
+                constr = propertyEditorClass.getConstructor(Object.class);
+                editor = (PropertyEditor) constr.newInstance(bean);
+            } catch (NoSuchMethodException e) {
+                // try no-argument constructor
+                constr = propertyEditorClass.getConstructor();
+                editor = (PropertyEditor) constr.newInstance();
+            }
+        } catch (Exception e) {
+            // beans.47=Unable to instantiate property editor
+            RuntimeException re = new RuntimeException(Messages.getString("beans.47"), e); //$NON-NLS-1$
+            throw re;
+        }
+        return editor;
+    }
+}
diff --git a/awt/java/beans/PropertyEditor.java b/awt/java/beans/PropertyEditor.java
new file mode 100644
index 0000000..65bedea
--- /dev/null
+++ b/awt/java/beans/PropertyEditor.java
@@ -0,0 +1,49 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+
+public interface PropertyEditor {
+
+    public void paintValue(Graphics gfx, Rectangle box);
+
+    public void setAsText(String text) throws IllegalArgumentException;
+
+    public String[] getTags();
+
+    public String getJavaInitializationString();
+
+    public String getAsText();
+
+    public void setValue(Object value);
+
+    public Object getValue();
+
+    public void removePropertyChangeListener(PropertyChangeListener listener);
+
+    public void addPropertyChangeListener(PropertyChangeListener listener);
+
+    public Component getCustomEditor();
+
+    public boolean supportsCustomEditor();
+
+    public boolean isPaintable();
+}
diff --git a/awt/java/beans/PropertyEditorManager.java b/awt/java/beans/PropertyEditorManager.java
new file mode 100644
index 0000000..ed55829
--- /dev/null
+++ b/awt/java/beans/PropertyEditorManager.java
@@ -0,0 +1,114 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PropertyEditorManager {
+
+    private static String[] path = { "org.apache.harmony.beans.editors" }; //$NON-NLS-1$
+
+    private static final Map<Class<?>, Class<?>> registeredEditors = new HashMap<Class<?>, Class<?>>();
+
+    public PropertyEditorManager() {
+    }
+
+    public static void registerEditor(Class<?> targetType, Class<?> editorClass) {
+        if (targetType == null) {
+            throw new NullPointerException();
+        }
+
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertiesAccess();
+        }
+        if (editorClass != null) {
+            registeredEditors.put(targetType, editorClass);
+        } else {
+            registeredEditors.remove(targetType);
+        }
+    }
+
+    public static synchronized PropertyEditor findEditor(Class<?> targetType) {
+        if (targetType == null) {
+            throw new NullPointerException();
+        }
+
+        Class<?> editorClass = null;
+        PropertyEditor editor = null;
+
+        editorClass = registeredEditors.get(targetType);
+
+        if (editorClass == null) {
+            String editorClassName = targetType.getName() + "Editor"; //$NON-NLS-1$
+            ClassLoader loader = targetType.getClassLoader();
+
+            if (loader == null) {
+                loader = Thread.currentThread().getContextClassLoader();
+            }
+
+            try {
+                editorClass = Class.forName(editorClassName, true, loader);
+            } catch (ClassNotFoundException cnfe) {
+                String shortEditorClassName = editorClassName
+                        .substring(editorClassName.lastIndexOf(".") + 1); //$NON-NLS-1$
+
+                if (targetType.isPrimitive()) {
+                    shortEditorClassName = shortEditorClassName.substring(0, 1)
+                            .toUpperCase()
+                            + shortEditorClassName.substring(1);
+                }
+
+                for (String element : path) {
+                    editorClassName = element + "." + shortEditorClassName; //$NON-NLS-1$
+
+                    try {
+                        editorClass = Class.forName(editorClassName, true,
+                                loader);
+                        break;
+                    } catch (Exception e) {
+                    }
+                }
+            } catch (Exception e) {
+            }
+        }
+
+        if (editorClass != null) {
+            try {
+                editor = (PropertyEditor) editorClass.newInstance();
+            } catch (Exception e) {
+            }
+        }
+
+        return editor;
+    }
+
+    public static synchronized void setEditorSearchPath(String[] apath) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertiesAccess();
+        }
+
+        path = apath;
+    }
+
+    public static synchronized String[] getEditorSearchPath() {
+        return path;
+    }
+}
diff --git a/awt/java/beans/PropertyEditorSupport.java b/awt/java/beans/PropertyEditorSupport.java
new file mode 100644
index 0000000..c3929a1
--- /dev/null
+++ b/awt/java/beans/PropertyEditorSupport.java
@@ -0,0 +1,129 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package java.beans;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.harmony.beans.internal.nls.Messages;
+
+public class PropertyEditorSupport implements PropertyEditor {
+
+    Object source = null;
+
+    List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
+
+    Object oldValue = null;
+
+    Object newValue = null;
+
+    public PropertyEditorSupport(Object source) {
+        if (source == null) {
+            throw new NullPointerException(Messages.getString("beans.0C")); //$NON-NLS-1$
+        }
+        this.source = source;
+    }
+
+    public PropertyEditorSupport() {
+        source = this;
+    }
+
+    public void paintValue(Graphics gfx, Rectangle box) {
+    }
+
+    public void setAsText(String text) throws IllegalArgumentException {
+        if (newValue instanceof String) {
+            setValue(text);
+        } else {
+            throw new IllegalArgumentException(text);
+        }
+    }
+
+    public String[] getTags() {
+        return null;
+    }
+
+    public String getJavaInitializationString() {
+        return "???"; //$NON-NLS-1$
+    }
+
+    public String getAsText() {
+        return newValue == null ? "null" : newValue.toString(); //$NON-NLS-1$
+    }
+
+    public void setValue(Object value) {
+        this.oldValue = this.newValue;
+        this.newValue = value;
+        firePropertyChange();
+    }
+
+    public Object getValue() {
+        return newValue;
+    }
+
+    public void setSource(Object source) {
+        if (source == null) {
+            throw new NullPointerException(Messages.getString("beans.0C")); //$NON-NLS-1$
+        }
+        this.source = source;
+    }
+
+    public Object getSource() {
+        return source;
+    }
+
+    public synchronized void removePropertyChangeListener(
+            PropertyChangeListener listener) {
+        if (listeners != null) {
+            listeners.remove(listener);
+        }
+    }
+
+    public synchronized void addPropertyChangeListener(
+            PropertyChangeListener listener) {
+        listeners.add(listener);
+    }
+
+    public Component getCustomEditor() {
+        return null;
+    }
+
+    public boolean supportsCustomEditor() {
+        return false;
+    }
+
+    public boolean isPaintable() {
+        return false;
+    }
+
+    public void firePropertyChange() {
+        if (listeners.size() > 0) {
+            PropertyChangeEvent event = new PropertyChangeEvent(source, null,
+                    oldValue, newValue);
+            Iterator<PropertyChangeListener> iterator = listeners.iterator();
+
+            while (iterator.hasNext()) {
+                PropertyChangeListener listener = iterator.next();
+                listener.propertyChange(event);
+            }
+        }
+    }
+}
diff --git a/awt/java/beans/PropertyVetoException.java b/awt/java/beans/PropertyVetoException.java
new file mode 100644
index 0000000..c7f092a
--- /dev/null
+++ b/awt/java/beans/PropertyVetoException.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+/**
+ * Indicates that a proposed property change is unacceptable.
+ */
+public class PropertyVetoException extends Exception {
+
+    private static final long serialVersionUID = 129596057694162164L;
+
+    private final PropertyChangeEvent evt;
+
+    /**
+     * <p>
+     * Constructs an instance with a message and the change event.
+     * </p>
+     * 
+     * @param message
+     *            A description of the veto.
+     * @param event
+     *            The event that was vetoed.
+     */
+    public PropertyVetoException(String message, PropertyChangeEvent event) {
+        super(message);
+        this.evt = event;
+    }
+
+    /**
+     * <p>
+     * Gets the property change event.
+     * </p>
+     * 
+     * @return An instance of {@link PropertyChangeEvent}
+     */
+    public PropertyChangeEvent getPropertyChangeEvent() {
+        return evt;
+    }
+}
diff --git a/awt/javax/imageio/IIOException.java b/awt/javax/imageio/IIOException.java
new file mode 100644
index 0000000..fbfeb42
--- /dev/null
+++ b/awt/javax/imageio/IIOException.java
@@ -0,0 +1,52 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import java.io.IOException;
+
+/**
+ * The IIOException class indicates errors in reading/writing operations.
+ */
+public class IIOException extends IOException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -3216210718638985251L;
+
+    /**
+     * Instantiates a new IIOException.
+     * 
+     * @param message the detailed message.
+     */
+    public IIOException(String message) {
+        super(message);
+    }
+
+    /**
+     * Instantiates a new IIOException.
+     * 
+     * @param message the detailed message.
+     * @param cause the cause of this exception.
+     */
+    public IIOException(String message, Throwable cause) {
+        super(message);
+        initCause(cause);
+    }
+}
diff --git a/awt/javax/imageio/IIOImage.java b/awt/javax/imageio/IIOImage.java
new file mode 100644
index 0000000..e17a9fc
--- /dev/null
+++ b/awt/javax/imageio/IIOImage.java
@@ -0,0 +1,203 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import javax.imageio.metadata.IIOMetadata;
+import java.awt.image.RenderedImage;
+import java.awt.image.Raster;
+import java.awt.image.BufferedImage;
+import java.util.List;
+
+/**
+ * The IIOImage class combines the image, image's thumbnail and image's metadata.
+ * The image can be presented as RenderedImage or Raster object.
+ */
+public class IIOImage {
+
+    /** The image of this IIOImage. */
+    protected RenderedImage image;
+    
+    /** The raster of this IIOImage. */
+    protected Raster raster;
+    
+    /** The list with thumbnails associated with the image. */
+    protected List<? extends BufferedImage> thumbnails;
+    
+    /** The metadata associated with the image. */
+    protected IIOMetadata metadata;
+
+    /**
+     * Instantiates a new IIOImage with the specified RenderedImage, 
+     * list of thumbnails and metadata.
+     * 
+     * @param image the image specified by RenderedImage.
+     * @param thumbnails the list of BufferedImage objects which 
+     * represent the thumbnails of the image.
+     * @param metadata the metadata of the image.
+     */
+    public IIOImage(RenderedImage image, List<? extends BufferedImage> thumbnails, IIOMetadata metadata) {
+        if (image == null) {
+            throw new IllegalArgumentException("image should not be NULL");
+        }
+        this.raster = null;
+        this.image = image;
+        this.thumbnails = thumbnails;
+        this.metadata = metadata;
+    }
+
+    /**
+     * Instantiates a new IIOImage with the specified Raster, list of
+     * thumbnails and metadata.
+     * 
+     * @param raster the Raster.
+     * @param thumbnails the list of BufferedImage objects which 
+     * represent the thumbnails of Raster data.
+     * @param metadata the metadata.
+     */
+    public IIOImage(Raster raster, List<? extends BufferedImage> thumbnails, IIOMetadata metadata) {
+        if (raster == null) {
+            throw new IllegalArgumentException("raster should not be NULL");
+        }
+        this.image = null;
+        this.raster = raster;
+        this.thumbnails = thumbnails;
+        this.metadata = metadata;
+    }
+
+    /**
+     * Gets the RenderedImage object or returns null if this IIOImage 
+     * object is associated with a Raster.
+     * 
+     * @return the RenderedImage object or null if this IIOImage 
+     * object is associated with a Raster.
+     */
+    public RenderedImage getRenderedImage() {
+        return image;
+    }
+
+    /**
+     * Sets the RenderedImage to this IIOImage object.
+     * 
+     * @param image the RenderedImage to be set to this IIOImage.
+     */
+    public void setRenderedImage(RenderedImage image) {
+        if (image == null) {
+            throw new IllegalArgumentException("image should not be NULL");
+        }
+        raster = null;
+        this.image = image;
+    }
+
+    /**
+     * Returns true if the IIOImage object associated with a Raster, or 
+     * false if it's associated with a RenderedImage.
+     * 
+     * @return true if the IIOImage object associated with a Raster, or 
+     * false if it's associated with a RenderedImage.
+     */
+    public boolean hasRaster() {
+        return raster != null;
+    }
+
+    /**
+     * Gets the Raster object or returns null if this IIOImage object is
+     * associated with a RenderedImage.
+     * 
+     * @return the Raster or null if this IIOImage object
+     * is associated with a RenderedImage.
+     */
+    public Raster getRaster() {
+        return raster;
+    }
+
+    /**
+     * Sets the Raster to the IIOImage.
+     * 
+     * @param raster the new Raster to the IIOImage.
+     */
+    public void setRaster(Raster raster) {
+        if (raster == null) {
+            throw new IllegalArgumentException("raster should not be NULL");
+        }
+        image = null;
+        this.raster = raster;
+    }
+
+    /**
+     * Gets the number of thumbnails for this IIOImage.
+     * 
+     * @return the number of thumbnails for this IIOImage.
+     */
+    public int getNumThumbnails() {
+        return thumbnails != null ? thumbnails.size() : 0;
+    }
+
+    /**
+     * Gets the thumbnail with the specified index in the list.
+     * 
+     * @param index the index of the thumbnail in the list.
+     * 
+     * @return the thumbnail with the specified index in the list.
+     */
+    public BufferedImage getThumbnail(int index) {
+        if (thumbnails != null) {
+            return thumbnails.get(index);
+        }
+        throw new IndexOutOfBoundsException("no thumbnails were set");
+    }
+
+    /**
+     * Gets the list of thumbnails.
+     * 
+     * @return the list of thumbnails.
+     */
+    public List<? extends BufferedImage> getThumbnails() {
+        return thumbnails;
+    }
+
+    /**
+     * Sets the list of thumbnails images to this IIOImage object.
+     * 
+     * @param thumbnails the list of BufferedImage which represent
+     * thumbnails.
+     */
+    public void setThumbnails(List<? extends BufferedImage> thumbnails) {
+        this.thumbnails = thumbnails;
+    }
+
+    /**
+     * Gets the metadata of this IIOImage.
+     * 
+     * @return the metadata of this IIOImage.
+     */
+    public IIOMetadata getMetadata() {
+        return metadata;
+    }
+
+    /**
+     * Sets the metadata to this IIOImage object.
+     * 
+     * @param metadata the IIOMetadata, or null.
+     */
+    public void setMetadata(IIOMetadata metadata) {
+        this.metadata = metadata;
+    }
+}
diff --git a/awt/javax/imageio/IIOParam.java b/awt/javax/imageio/IIOParam.java
new file mode 100644
index 0000000..d998b6e
--- /dev/null
+++ b/awt/javax/imageio/IIOParam.java
@@ -0,0 +1,316 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import java.awt.*;
+
+/**
+ * The IIOParam abstract class is superclass for     
+ * ImageReadParam and ImageWriteParam classes and provides 
+ * methods and variables which they share.
+ */
+public abstract class IIOParam {
+    
+    /** The source region. */
+    protected Rectangle sourceRegion;
+    
+    /** The source x subsampling. */
+    protected int sourceXSubsampling = 1;
+    
+    /** The source y subsampling. */
+    protected int sourceYSubsampling = 1;
+    
+    /** The subsampling x offset. */
+    protected int subsamplingXOffset;
+    
+    /** The subsampling y offset. */
+    protected int subsamplingYOffset;
+    
+    /** The source bands. */
+    protected int[] sourceBands;
+    
+    /** The destination type. */
+    protected ImageTypeSpecifier destinationType;
+    
+    /** The destination offset. */
+    protected Point destinationOffset = new Point(0, 0);
+    
+    /** The default controller. */
+    protected IIOParamController defaultController;
+    
+    /** The controller. */
+    protected IIOParamController controller;
+
+    /**
+     * Instantiates a new IIOParam.
+     */
+    protected IIOParam() {}
+
+    /**
+     * Sets the source region as a Rectangle object.
+     * 
+     * @param sourceRegion the Rectangle which specifies the source region.
+     */
+    public void setSourceRegion(Rectangle sourceRegion) {
+        if (sourceRegion != null) {
+            if (sourceRegion.x < 0) {
+                throw new IllegalArgumentException("x < 0");
+            }
+            if (sourceRegion.y < 0) {
+                throw new IllegalArgumentException("y < 0");
+            }
+            if (sourceRegion.width <= 0) {
+                throw new IllegalArgumentException("width <= 0");
+            }
+            if (sourceRegion.height <= 0) {
+                throw new IllegalArgumentException("height <= 0");
+            }
+
+            if (sourceRegion.width <= subsamplingXOffset) {
+                throw new IllegalArgumentException("width <= subsamplingXOffset");
+            }
+
+            if (sourceRegion.height <= subsamplingYOffset) {
+                throw new IllegalArgumentException("height <= subsamplingXOffset");
+            }
+            //-- clone it to avoid unexpected modifications
+            this.sourceRegion = (Rectangle) sourceRegion.clone();
+        } else {
+            this.sourceRegion = null;
+        }
+    }
+
+    /**
+     * Gets the source region.
+     * 
+     * @return the source region as Rectangle.
+     */
+    public Rectangle getSourceRegion() {
+        if (sourceRegion == null) {
+            return null;
+        }
+        //-- clone it to avoid unexpected modifications
+        return (Rectangle) sourceRegion.clone();
+    }
+
+    /**
+     * Sets the source subsampling. The sourceXSubsampling and 
+     * sourceYSubsampling parameters specify the number of rows 
+     * and columns to advance after every source pixel.
+     * 
+     * @param sourceXSubsampling the source X subsampling.
+     * @param sourceYSubsampling the source Y subsampling.
+     * @param subsamplingXOffset the subsampling X offset.
+     * @param subsamplingYOffset the subsampling Y offset.
+     */
+    public void setSourceSubsampling(int sourceXSubsampling,
+                                 int sourceYSubsampling,
+                                 int subsamplingXOffset,
+                                 int subsamplingYOffset) {
+
+        if (sourceXSubsampling <= 0) {
+            throw new IllegalArgumentException("sourceXSubsampling <= 0");
+        }
+        if (sourceYSubsampling <= 0) {
+            throw new IllegalArgumentException("sourceYSubsampling <= 0");
+        }
+
+        if (subsamplingXOffset <= 0 || subsamplingXOffset >= sourceXSubsampling) {
+            throw new IllegalArgumentException("subsamplingXOffset is wrong");
+        }
+
+        if (subsamplingYOffset <= 0 || subsamplingYOffset >= sourceYSubsampling) {
+            throw new IllegalArgumentException("subsamplingYOffset is wrong");
+        }
+
+        //-- does region contain pixels
+        if (sourceRegion != null) {
+            if (sourceRegion.width <= subsamplingXOffset ||
+                    sourceRegion.height <= subsamplingYOffset) {
+                throw new IllegalArgumentException("there are no pixels in region");
+            }
+        }
+
+        this.sourceXSubsampling = sourceXSubsampling;
+        this.sourceYSubsampling = sourceYSubsampling;
+        this.subsamplingXOffset = subsamplingXOffset;
+        this.subsamplingYOffset = subsamplingYOffset;
+    }
+
+    /**
+     * Gets the source X subsampling - the number of source 
+     * columns to advance for each pixel.
+     * 
+     * @return the source X subsampling.
+     */
+    public int getSourceXSubsampling() {
+        return sourceXSubsampling;
+    }
+
+    /**
+     * Gets the source Y subsampling - the number of source 
+     * rows to advance for each pixel.
+     * 
+     * @return the source Y subsampling.
+     */
+    public int getSourceYSubsampling() {
+        return sourceYSubsampling;
+    }
+
+    /**
+     * Gets the horizontal offset of the subsampling grid.
+     * 
+     * @return the horizontal offset of the subsampling grid.
+     */
+    public int getSubsamplingXOffset() {
+        return subsamplingXOffset;
+    }
+
+    /**
+     * Gets the vertical offset of the subsampling grid.
+     * 
+     * @return the vertical offset of the subsampling grid.
+     */
+    public int getSubsamplingYOffset() {
+        return subsamplingYOffset;
+    }
+
+    /**
+     * Sets the indices of the source bands.
+     * 
+     * @param sourceBands the indices of the source bands.
+     */
+    public void setSourceBands(int[] sourceBands) {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Gets the array of source bands.
+     * 
+     * @return the array of source bands.
+     */
+    public int[] getSourceBands() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Sets the specified ImageTypeSpecifier for the destination image.
+     * 
+     * @param destinationType the ImageTypeSpecifier.
+     */
+    public void setDestinationType(ImageTypeSpecifier destinationType) {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Gets the type of the destination image as an ImageTypeSpecifier. .
+     *  
+     * @return the ImageTypeSpecifier.
+     */
+    public ImageTypeSpecifier getDestinationType() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Sets the offset in the destination image where 
+     * the decoded pixels are placed as a result of reading, 
+     * or specified an area to be written while writing operation.
+     * 
+     * @param destinationOffset the destination offset.
+     */
+    public void setDestinationOffset(Point destinationOffset) {
+        if (destinationOffset == null) {
+            throw new IllegalArgumentException("destinationOffset == null!");
+        }
+        
+        this.destinationOffset = (Point) destinationOffset.clone();
+    }
+
+    /**
+     * Gets the offset in the destination image for placing pixels.
+     * 
+     * @return the offset in the destination image.
+     */
+    public Point getDestinationOffset() {
+        return (Point) destinationOffset.clone();        
+    }
+
+    /**
+     * Sets the IIOParamController to this IIOParam object for
+     * providing settings to this IIOParam.
+     * 
+     * @param controller the new IIOParamController.
+     */
+    public void setController(IIOParamController controller) {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Gets the current IIOParamController controller 
+     * for this IIOParam.
+     * 
+     * @return the current IIOParamController controller 
+     * for this IIOParam.
+     */
+    public IIOParamController getController() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Gets the default IIOParamController controller 
+     * for this IIOParam.
+     * 
+     * @return the default IIOParamController controller 
+     * for this IIOParam, or null.
+     */
+    public IIOParamController getDefaultController() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Returns true if IIOParamController is installed for 
+     * this IIOParam. 
+     * 
+     * @return true if IIOParamController is installed for 
+     * this IIOParam, false otherwise.
+     */
+    public boolean hasController() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Activates the controller.
+     * 
+     * @return true, if successful, false otherwise.
+     */
+    public boolean activateController() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+}
diff --git a/awt/javax/imageio/IIOParamController.java b/awt/javax/imageio/IIOParamController.java
new file mode 100644
index 0000000..31522c1
--- /dev/null
+++ b/awt/javax/imageio/IIOParamController.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio;
+
+/* 
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The IIOParamController specifies an activate method that invokes the 
+ * controller.
+ */
+public interface IIOParamController {
+
+    /**
+     * Activates the controller. 
+     * 
+     * @param param the IIOParam.
+     * 
+     * @return true if the IIOParam has been modified, false otherwise.
+     */
+    boolean activate(IIOParam param);
+}
+
diff --git a/awt/javax/imageio/ImageIO.java b/awt/javax/imageio/ImageIO.java
new file mode 100644
index 0000000..d4cd1dd
--- /dev/null
+++ b/awt/javax/imageio/ImageIO.java
@@ -0,0 +1,777 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.spi.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.Arrays;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+import java.net.URL;
+
+/**
+ * The ImageIO class provides static methods to perfom 
+ * reading and writing operations using registered
+ * ImageReader and ImageWriter objects.
+ */
+public final class ImageIO {
+
+    /** The Constant registry. */
+    private static final IIORegistry registry = IIORegistry.getDefaultInstance();
+
+    /**
+     * Instantiates a new image io.
+     */
+    private ImageIO() {}
+    
+
+    /**
+     * Scans for plug-ins in the class path, 
+     * loads spi classes, and registers them with the IIORegistry.
+     */
+    public static void scanForPlugins() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Sets flag which indicates whether a cache file is used when 
+     * creating ImageInputStreams and ImageOutputStreams or not.
+     * 
+     * @param useCache the use cache flag.
+     */
+    public static void setUseCache(boolean useCache) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the flag which indicates whether a cache file is used when 
+     * creating ImageInputStreams and ImageOutputStreams or not.
+     * This method returns the current value which is set by setUseCache
+     * method.
+     * 
+     * @return the use cache flag.
+     */
+    public static boolean getUseCache() {
+        // TODO implement
+        return false;
+    }
+
+    /**
+     * Sets the cache directory.
+     * 
+     * @param cacheDirectory the File which specifies a cache directory.
+     */
+    public static void setCacheDirectory(File cacheDirectory) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the directory where cache files are created, returned
+     * the file which is set by setCacheDirectory method, or null.
+     * 
+     * @return the File object which is set by setCacheDirectory method, 
+     * or null.
+     */
+    public static File getCacheDirectory() {
+        // TODO implement
+        //-- null indicates system-dep default temporary directory
+        return null;
+    }
+
+    /**
+     * Creates an ImageInputStream from the specified Object.
+     * The specified Object should obtain the input source
+     * such as File, or InputStream.   
+     * 
+     * @param input the input Object such as File, or InputStream.   
+     * 
+     * @return the ImageInputStream object, or null.
+     * 
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static ImageInputStream createImageInputStream(Object input)
+            throws IOException {
+
+        if (input == null) {
+            throw new IllegalArgumentException("input source cannot be NULL");
+        }
+
+        Iterator<ImageInputStreamSpi> it = registry.getServiceProviders(ImageInputStreamSpi.class, true);
+
+        while (it.hasNext()) {
+            ImageInputStreamSpi spi = it.next();
+            if (spi.getInputClass().isInstance(input)) {
+                return spi.createInputStreamInstance(input);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Creates an ImageOutputStream using the specified Object.
+     * The specified Object should obtain the output source
+     * such as File, or OutputStream.   
+     * 
+     * @param output the output Object such as File, or OutputStream.   
+     * 
+     * @return the ImageOutputStream object, or null.
+     * 
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static ImageOutputStream createImageOutputStream(Object output)
+            throws IOException {
+        if (output == null) {
+            throw new IllegalArgumentException("output destination cannot be NULL");
+        }
+
+        Iterator<ImageOutputStreamSpi> it = registry.getServiceProviders(ImageOutputStreamSpi.class, true);
+
+        while (it.hasNext()) {
+            ImageOutputStreamSpi spi = it.next();
+            if (spi.getOutputClass().isInstance(output)) {
+                // todo - use getUseCache and getCacheDir here
+                return spi.createOutputStreamInstance(output);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the array of format names as String which can be 
+     * decoded by registered ImageReader objects.
+     * 
+     * @return the array of format names.
+     */
+    public static String[] getReaderFormatNames() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the array of MIME types as String which can be 
+     * decoded by registered ImageReader objects.
+     * 
+     * @return the array of MIME types.
+     */
+    public static String[] getReaderMIMETypes() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the Iterator of registered ImageReader which are able to 
+     * decode an imput data specified by input Object.
+     * 
+     * @param input the input Object with encoded data such as 
+     * ImageInputStream object.
+     * 
+     * @return the Iterator of registered ImageReader. 
+     */
+    public static Iterator<ImageReader> getImageReaders(Object input) {
+        if (input == null) {
+            throw new NullPointerException("input cannot be NULL");
+        }
+
+        Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
+                new CanReadFilter(input), true);
+
+        return new SpiIteratorToReadersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator of registered ImageReader which are able to 
+     * decode the specified format.
+     * 
+     * @param formatName the format name such as "jpeg", or "gif".
+     * 
+     * @return the Iterator of registered ImageReader.
+     */
+    public static Iterator<ImageReader> getImageReadersByFormatName(String formatName) {
+        if (formatName == null) {
+            throw new NullPointerException("format name cannot be NULL");
+        }
+
+        Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
+                new FormatFilter(formatName), true);
+
+        return new SpiIteratorToReadersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator which lists the registered ImageReader objects that
+     * are able to decode files with the specified suffix.
+     * 
+     * @param fileSuffix the file suffix such as "jpg".
+     * 
+     * @return the Iterator of registered ImageReaders.
+     */
+    public static Iterator<ImageReader> getImageReadersBySuffix(String fileSuffix) {
+        if (fileSuffix == null) {
+            throw new NullPointerException("suffix cannot be NULL");
+        }
+        Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
+                new SuffixFilter(fileSuffix), true);
+
+        return new SpiIteratorToReadersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator of registered ImageReader objects that
+     * are able to decode files with the specified MIME type.
+     * 
+     * @param MIMEType the MIME type such as "image/jpeg".
+     * 
+     * @return the Iterator of registered ImageReaders.
+     */
+    public static Iterator<ImageReader> getImageReadersByMIMEType(String MIMEType) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an array of Strings giving the names of the formats supported 
+     * by registered ImageWriter objects.
+     * 
+     * @return the array of format names.
+     */
+    public static String[] getWriterFormatNames() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an array of Strings giving the MIME types of the formats supported 
+     * by registered ImageWriter objects.
+     * 
+     * @return the array of MIME types.
+     */
+    public static String[] getWriterMIMETypes() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the Iterator which lists the registered ImageReader objects that
+     * are able to encode the specified image format.
+     * 
+     * @param formatName the image format name such as "jpeg".
+     * 
+     * @return the Iterator of registered ImageWriter.
+     */
+    public static Iterator<ImageWriter> getImageWritersByFormatName(String formatName) {
+        if (formatName == null) {
+            throw new NullPointerException("format name cannot be NULL");
+        }
+
+        Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class,
+                new FormatFilter(formatName), true);
+
+        return new SpiIteratorToWritersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator which lists the registered ImageReader objects that
+     * are able to encode the specified suffix.
+     * 
+     * @param fileSuffix the file suffix such as "jpg".
+     * 
+     * @return the Iterator of registered ImageWriter.
+     */
+    public static Iterator<ImageWriter> getImageWritersBySuffix(String fileSuffix) {
+        if (fileSuffix == null) {
+            throw new NullPointerException("suffix cannot be NULL");
+        }
+        Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class,
+                new SuffixFilter(fileSuffix), true);
+        return new SpiIteratorToWritersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator which lists the registered ImageReader objects that
+     * are able to encode the specified MIME type.
+     * 
+     * @param MIMEType the MIME type such as "image/jpeg".
+     * 
+     * @return the Iterator of registered ImageWriter.
+     */
+    public static Iterator<ImageWriter> getImageWritersByMIMEType(String MIMEType) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an ImageWriter object which corresponds to the 
+     * specified ImageReader, or returns null if the specified
+     * ImageReader is not registered. 
+     * 
+     * @param reader the specified ImageReader.
+     * 
+     * @return the ImageWriter, or null.
+     */
+    public static ImageWriter getImageWriter(ImageReader reader) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an ImageReader object which corresponds to the 
+     * specified ImageWriter, or returns null if the specified
+     * ImageWriter is not registered. 
+     * 
+     * @param writer the registered ImageWriter object.
+     * 
+     * @return the ImageReader.
+     */
+    public static ImageReader getImageReader(ImageWriter writer) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the Iterator of ImageWriter objects which are able to
+     * encode images with the specified ImageTypeSpecifier and
+     * format.
+     * 
+     * @param type the ImageTypeSpecifier, which defines layout.
+     * @param formatName the format name.
+     * 
+     * @return the Iterator of ImageWriter objects.
+     */
+    public static Iterator<ImageWriter> getImageWriters(ImageTypeSpecifier type,
+                                           String formatName) {
+        if (type == null) {
+            throw new NullPointerException("type cannot be NULL");
+        }
+
+        if (formatName == null) {
+            throw new NullPointerException("format name cannot be NULL");
+        }
+
+        Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class,
+                new FormatAndEncodeFilter(type, formatName), true);
+
+        return new SpiIteratorToWritersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator of registered ImageTranscoders which 
+     * are able to transcode the metadata of the specified
+     * ImageReader object to a suitable object for encoding 
+     * by the specified ImageWriter.
+     * 
+     * @param reader the specified ImageReader.
+     * @param writer the specified ImageWriter.
+     * 
+     * @return the Iterator of registered ImageTranscoders.
+     */
+    public static Iterator<ImageTranscoder> getImageTranscoders(ImageReader reader,
+                                               ImageWriter writer) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Reads image data from the specified File and decodes it using 
+     * the appropriate registered ImageReader object. 
+     * The File is wrapped in an ImageInputStream.
+     * 
+     * @param input the File to be read.
+     * 
+     * @return the BufferedImage decoded from the specified File, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static BufferedImage read(File input) throws IOException {
+        if (input == null) {
+            throw new IllegalArgumentException("input == null!");
+        }
+
+        ImageInputStream stream = createImageInputStream(input);
+        return read(stream);
+    }
+
+    /**
+     * Reads image data from the specified InputStream and decodes it 
+     * using an appropriate registered an ImageReader object.
+     * 
+     * @param input the InputStream.
+     * 
+     * @return the BufferedImage decoded from the specified InputStream,
+     * or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static BufferedImage read(InputStream input) throws IOException {
+        if (input == null) {
+            throw new IllegalArgumentException("input == null!");
+        }
+
+        ImageInputStream stream = createImageInputStream(input);
+        return read(stream);
+    }
+
+    /**
+     * Reads image data from the specified URL and decodes it using 
+     * the appropriate registered ImageReader object. 
+     *  
+     * @param input the URL to be read.
+     * 
+     * @return the BufferedImage decoded from the specified URL, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static BufferedImage read(URL input) throws IOException {
+        if (input == null) {
+            throw new IllegalArgumentException("input == null!");
+        }
+
+        InputStream stream = input.openStream();
+        BufferedImage res = read(stream);
+        stream.close();
+        
+        return res;
+    }
+
+    /**
+     * Reads image data from the specified ImageInputStream and decodes it 
+     * using appropriate registered an ImageReader object.
+     * 
+     * @param stream the ImageInputStream.
+     * 
+     * @return the BufferedImage decoded from the specified ImageInputStream,
+     * or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static BufferedImage read(ImageInputStream stream) throws IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+
+        Iterator<ImageReader> imageReaders = getImageReaders(stream);
+        if (!imageReaders.hasNext()) {
+            return null;
+        }
+
+        ImageReader reader = imageReaders.next();
+        reader.setInput(stream, false, true);
+        BufferedImage res = reader.read(0);
+        reader.dispose();
+
+        try {
+            stream.close();
+        } catch (IOException e) {
+            // Stream could be already closed, proceed silently in this case
+        }
+        
+        return res;
+    }
+
+    /**
+     * Writes the specified image in the specified format (using an 
+     * appropriate ImageWriter) to the specified ImageOutputStream.
+     * 
+     * @param im the RenderedImage.
+     * @param formatName the format name.
+     * @param output the ImageOutputStream where Image to be written.
+     * 
+     * @return true, if Image is written successfully, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static boolean write(RenderedImage im,
+                                String formatName,
+                                ImageOutputStream output)
+            throws IOException {
+
+        if (im == null) {
+            throw new IllegalArgumentException("image cannot be NULL");
+        }
+        if (formatName == null) {
+            throw new IllegalArgumentException("format name cannot be NULL");
+        }
+        if (output == null) {
+            throw new IllegalArgumentException("output cannot be NULL");
+        }
+
+        Iterator<ImageWriter> it = getImageWriters(ImageTypeSpecifier.createFromRenderedImage(im), formatName);
+        if (it.hasNext()) {
+            ImageWriter writer = it.next();
+            writer.setOutput(output);
+            writer.write(im);
+            output.flush();
+            writer.dispose();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Writes the specified image in the specified format (using an 
+     * appropriate ImageWriter) to the specified File.
+     * 
+     * @param im the RenderedImage.
+     * @param formatName the format name.
+     * @param output the output File where Image to be written.
+     * 
+     * @return true, if Image is written successfully, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static boolean write(RenderedImage im,
+                                String formatName,
+                                File output)
+            throws IOException {
+
+        if (output == null) {
+            throw new IllegalArgumentException("output cannot be NULL");
+        }
+
+        if (output.exists()) {
+            output.delete();
+        }
+
+        ImageOutputStream ios = createImageOutputStream(output);
+        boolean rt = write(im, formatName, ios);
+        ios.close();
+        return rt;
+    }
+
+    /**
+     * Writes the specified image in the specified format (using an 
+     * appropriate ImageWriter) to the specified OutputStream.
+     * 
+     * @param im the RenderedImage.
+     * @param formatName the format name.
+     * @param output the OutputStream where Image is to be written.
+     * 
+     * @return true, if Image is written successfully, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static boolean write(RenderedImage im,
+                                String formatName,
+                                OutputStream output)
+            throws IOException {
+
+        if (output == null) {
+            throw new IllegalArgumentException("output cannot be NULL");
+        }
+
+        ImageOutputStream ios = createImageOutputStream(output);
+        boolean rt = write(im, formatName, ios);
+        ios.close();
+        return rt;
+    }
+
+
+    /**
+     * Filter to match spi by format name.
+     */
+    static class FormatFilter implements ServiceRegistry.Filter {
+        
+        /** The name. */
+        private String name;
+
+        /**
+         * Instantiates a new format filter.
+         * 
+         * @param name the name
+         */
+        public FormatFilter(String name) {
+            this.name = name;
+        }
+
+        public boolean filter(Object provider) {
+            ImageReaderWriterSpi spi = (ImageReaderWriterSpi) provider;
+            return Arrays.asList(spi.getFormatNames()).contains(name);
+        }
+    }
+
+    /**
+     * Filter to match spi by format name and encoding possibility.
+     */
+    static class FormatAndEncodeFilter extends FormatFilter {
+
+        /** The type. */
+        private ImageTypeSpecifier type;
+
+        /**
+         * Instantiates a new format and encode filter.
+         * 
+         * @param type the type
+         * @param name the name
+         */
+        public FormatAndEncodeFilter(ImageTypeSpecifier type, String name) {
+            super(name);
+            this.type = type;
+        }
+
+        @Override
+        public boolean filter(Object provider) {
+            ImageWriterSpi spi = (ImageWriterSpi) provider;
+            return super.filter(provider) && spi.canEncodeImage(type);
+        }
+    }
+
+    /**
+     * Filter to match spi by suffix.
+     */
+    static class SuffixFilter implements ServiceRegistry.Filter {
+        
+        /** The suf. */
+        private String suf;
+
+        /**
+         * Instantiates a new suffix filter.
+         * 
+         * @param suf the suf
+         */
+        public SuffixFilter(String suf) {
+            this.suf = suf;
+        }
+
+        public boolean filter(Object provider) {
+            ImageReaderWriterSpi spi = (ImageReaderWriterSpi) provider;
+            return Arrays.asList(spi.getFileSuffixes()).contains(suf);
+        }
+    }
+
+    /**
+     * Filter to match spi by decoding possibility.
+     */
+    static class CanReadFilter implements ServiceRegistry.Filter {
+        
+        /** The input. */
+        private Object input;
+
+        /**
+         * Instantiates a new can read filter.
+         * 
+         * @param input the input
+         */
+        public CanReadFilter(Object input) {
+            this.input = input;
+        }
+
+        public boolean filter(Object provider) {
+            ImageReaderSpi spi = (ImageReaderSpi) provider;
+            try {
+                return spi.canDecodeInput(input);
+            } catch (IOException e) {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Wraps Spi's iterator to ImageWriter iterator.
+     */
+    static class SpiIteratorToWritersIteratorWrapper implements Iterator<ImageWriter> {
+
+        /** The backend. */
+        private Iterator<ImageWriterSpi> backend;
+
+        /**
+         * Instantiates a new spi iterator to writers iterator wrapper.
+         * 
+         * @param backend the backend
+         */
+        public SpiIteratorToWritersIteratorWrapper(Iterator<ImageWriterSpi> backend) {
+            this.backend = backend;
+        }
+
+        /**
+         * Next.
+         * 
+         * @return the image writer
+         */
+        public ImageWriter next() {
+            try {
+                return backend.next().createWriterInstance();
+            } catch (IOException e) {
+                e.printStackTrace();
+                return null;
+            }
+        }
+
+        /**
+         * Checks for next.
+         * 
+         * @return true, if successful
+         */
+        public boolean hasNext() {
+            return backend.hasNext();
+        }
+
+        /**
+         * Removes the.
+         */
+        public void remove() {
+            throw new UnsupportedOperationException("Use deregisterServiceprovider instead of Iterator.remove()");
+        }
+    }
+
+    /**
+     * Wraps spi's iterator to ImageReader iterator.
+     */
+    static class SpiIteratorToReadersIteratorWrapper implements Iterator<ImageReader> {
+        
+        /** The backend. */
+        private Iterator<ImageReaderSpi> backend;
+
+        /**
+         * Instantiates a new spi iterator to readers iterator wrapper.
+         * 
+         * @param backend the backend
+         */
+        public SpiIteratorToReadersIteratorWrapper(Iterator<ImageReaderSpi> backend) {
+            this.backend = backend;
+        }
+
+        /**
+         * Next.
+         * 
+         * @return the image reader
+         */
+        public ImageReader next() {
+            try {
+                return backend.next().createReaderInstance();
+            } catch (IOException e) {
+                e.printStackTrace();
+                return null;
+            }
+        }
+
+        /**
+         * Checks for next.
+         * 
+         * @return true, if successful
+         */
+        public boolean hasNext() {
+            return backend.hasNext();
+        }
+
+        /**
+         * Removes the.
+         */
+        public void remove() {
+            throw new UnsupportedOperationException("Use deregisterServiceprovider instead of Iterator.remove()");
+        }
+    }
+}
diff --git a/awt/javax/imageio/ImageReadParam.java b/awt/javax/imageio/ImageReadParam.java
new file mode 100644
index 0000000..e67ed7d
--- /dev/null
+++ b/awt/javax/imageio/ImageReadParam.java
@@ -0,0 +1,193 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio;
+
+import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+
+/*
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The ImageReadParam class provides information to the ImageReader about
+ * how an image is to be decoded.
+ */
+
+public class ImageReadParam extends IIOParam {
+
+    /** 
+     * This flag indicates if this ImageReadParam supports setting the source 
+     * rendering size.  
+     */
+    protected boolean canSetSourceRenderSize;
+    
+    /** 
+     * The destination BufferedImage. 
+     */
+    protected BufferedImage destination;
+    
+    /** The destination bands. */
+    protected int[] destinationBands;
+    
+    /** 
+     * The minimum progressive pass.  
+     */
+    protected int minProgressivePass;
+    
+    /** 
+     * The number of progressive passes.  
+     */
+    protected int numProgressivePasses;
+    
+    /** The source render size. */
+    protected Dimension sourceRenderSize;
+
+    /**
+     * Returns true if this ImageReaderParam supports rendering a
+     * source image at an arbitrary size.
+     * 
+     * @return true if this ImageReaderParam supports rendering a
+     * source image at an arbitrary size, false otherwise.
+     */
+    public boolean canSetSourceRenderSize() {
+        return canSetSourceRenderSize;
+    }
+
+    /**
+     * Gets the current destination image as BufferedImage.
+     * 
+     * @return the BufferedImage which represents the destination.
+     */
+    public BufferedImage getDestination() {
+        return destination;
+    }
+
+    /**
+     * Gets the indices of destination bands.
+     * 
+     * @return the array of destination bands.
+     */
+    public int[] getDestinationBands() {
+        return destinationBands;
+    }
+
+    /**
+     * Gets the index of the maximum pass to be decoded.
+     * This method returns Integer.MAX_VALUE, if 
+     * getSourceNumProgressivePasses() method returns value
+     * that is equal to Integer.MAX_VALUE. Otherwise
+     * this method returns 
+     * getSourceMinProgressivePass() + getSourceNumProgressivePasses() - 1.
+     * 
+     * @return the index of the maximum pass to be decoded.
+     */
+    public int getSourceMaxProgressivePass() {
+        if (getSourceNumProgressivePasses() == Integer.MAX_VALUE) {
+            return Integer.MAX_VALUE;
+        }
+        return getSourceMinProgressivePass() + getSourceNumProgressivePasses() - 1;
+    }
+
+    /**
+     * Gets the index of the minimum progressive pass that is decoded,
+     * default is 0. 
+     * 
+     * @return the index of the minimum progressive pass that is decoded,
+     * default is 0.
+     */
+    public int getSourceMinProgressivePass() {
+        return minProgressivePass;
+    }
+
+    /**
+     * Gets the number of progressive passes.
+     * The default value is Integer.MAX_VALUE. 
+     * 
+     * @return the number of progressive passes.
+     */
+    public int getSourceNumProgressivePasses() {
+        return numProgressivePasses;
+    }
+
+    /**
+     * Gets the dimension of source image which will be rendered
+     * during decoding process.
+     * 
+     * @return the source render size.
+     */
+    public Dimension getSourceRenderSize() {
+        return sourceRenderSize;
+    }
+
+    /**
+     * Sets the specified destination image.
+     * This image will be used by read, readAll, and readRaster methods,
+     * and a reference to it will be returned by those methods.
+     * 
+     * @param destination the destination image.
+     */
+    public void setDestination(BufferedImage destination) {
+        this.destination = destination;
+    }
+
+    /**
+     * Sets the indices of the destination bands.
+     * 
+     * @param destinationBands the indices of the destination bands.
+     */
+    public void setDestinationBands(int[] destinationBands) {
+        this.destinationBands = destinationBands;
+    }
+
+    @Override
+    public void setDestinationType(ImageTypeSpecifier destinationType) {
+        this.destinationType = destinationType;
+    }
+
+    /**
+     * Sets the source progressive passes.
+     * 
+     * @param minPass the index of the minimum pass to be decoded.
+     * @param numPasses the number of passes to be decoded.
+     */
+    public void setSourceProgressivePasses(int minPass, int numPasses) {
+        minProgressivePass = minPass;
+        numProgressivePasses = numPasses;
+    }
+
+    /**
+     * Sets the dimension size of source image if an
+     * image can be rendered at an arbitrary size.
+     * 
+     * @param size the size of rendered image.
+     * 
+     * @throws UnsupportedOperationException the unsupported operation exception
+     */
+    public void setSourceRenderSize(Dimension size) throws UnsupportedOperationException {
+        if (!canSetSourceRenderSize) {
+            throw new UnsupportedOperationException("can't set source renderer size");
+        }
+        sourceRenderSize = size;        
+    }
+}
+
diff --git a/awt/javax/imageio/ImageReader.java b/awt/javax/imageio/ImageReader.java
new file mode 100644
index 0000000..780de26
--- /dev/null
+++ b/awt/javax/imageio/ImageReader.java
@@ -0,0 +1,1100 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.event.IIOReadWarningListener;
+import javax.imageio.event.IIOReadProgressListener;
+import javax.imageio.event.IIOReadUpdateListener;
+import java.util.Locale;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Set;
+import java.io.IOException;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.*;
+
+/**
+ * The ImageReader class is an abstract class for decoding images.
+ * ImageReader objects are instantiated by the service provider 
+ * interface, ImageReaderSpi class, for the specific format. 
+ * ImageReaderSpi class should be registered with the IIORegistry, 
+ * which uses them for format recognition and presentation of available 
+ * format readers and writers.
+ */
+public abstract class ImageReader {
+
+    /** The originating provider. */
+    protected ImageReaderSpi originatingProvider;
+
+    /** The input object such as ImageInputStream. */
+    protected Object input;
+
+    /** The seek forward only. */
+    protected boolean seekForwardOnly;
+
+    /** 
+     * The ignore metadata flag indicates whether current input source 
+     * has been marked as metadata is allowed to be ignored by setInput. 
+     */
+    protected boolean ignoreMetadata;
+
+    /** The minimum index. */
+    protected int minIndex;
+
+    /** The available locales. */
+    protected Locale[] availableLocales;
+
+    /** The locale. */
+    protected Locale locale;
+
+    /** The list of warning listeners. */
+    protected List<IIOReadWarningListener> warningListeners;
+
+    /** The list of warning locales. */
+    protected List<Locale> warningLocales;
+
+    /** The list of progress listeners. */
+    protected List<IIOReadProgressListener> progressListeners;
+
+    /** The list of update listeners. */
+    protected List<IIOReadUpdateListener> updateListeners;
+
+    /**
+     * Instantiates a new ImageReader.
+     * 
+     * @param originatingProvider the ImageReaderSpi which 
+     * instanties this ImageReader.
+     */
+    protected ImageReader(ImageReaderSpi originatingProvider) {
+        this.originatingProvider = originatingProvider;
+    }
+
+    /**
+     * Gets the format name of this input source.
+     * 
+     * @return the format name of this input source.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public String getFormatName() throws IOException {
+        return originatingProvider.getFormatNames()[0];
+    }
+
+    /**
+     * Gets the ImageReaderSpi which instantiated this ImageReader. 
+     * 
+     * @return the ImageReaderSpi.
+     */
+    public ImageReaderSpi getOriginatingProvider() {
+        return originatingProvider;
+    }
+
+    /**
+     * Sets the specified Object as the input source of this ImageReader. 
+     * 
+     * @param input the input source, it can 
+     * be an ImageInputStream or other supported objects.
+     * @param seekForwardOnly indicates whether the stream must
+     * be read sequentially from its current starting point.
+     * @param ignoreMetadata parameter which indicates
+     * if metadata may be ignored during reads or not.
+     */
+    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
+        if (input != null) {
+            if (!isSupported(input) && !(input instanceof ImageInputStream)) {
+                throw new IllegalArgumentException("input " + input + " is not supported");
+            }
+        }
+        this.minIndex = 0;
+        this.seekForwardOnly = seekForwardOnly;
+        this.ignoreMetadata = ignoreMetadata;
+        this.input = input;
+    }
+
+    /**
+     * Checks if is supported.
+     * 
+     * @param input the input
+     * 
+     * @return true, if is supported
+     */
+    private boolean isSupported(Object input) {
+        ImageReaderSpi spi = getOriginatingProvider();
+        if (null != spi) {
+            Class[] outTypes = spi.getInputTypes();
+            for (Class<?> element : outTypes) {
+                if (element.isInstance(input)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Sets the specified Object as the input source of this ImageReader.
+     * Metadata is not ignored.
+     * 
+     * @param input the input source, it can 
+     * be an ImageInputStream or other supported objects.
+     * @param seekForwardOnly indicates whether the stream must
+     * be read sequentially from its current starting point.
+     */
+    public void setInput(Object input, boolean seekForwardOnly) {
+        setInput(input, seekForwardOnly, false);
+    }
+
+    /**
+     * Sets the specified Object as the input source of this ImageReader.
+     * Metadata is not ignored and forward seeking is not required.
+     * 
+     * @param input the input source, it can 
+     * be ImageInputStream or other objects.
+     */
+    public void setInput(Object input) {
+        setInput(input, false, false);
+    }
+
+    /**
+     * Gets the input source object of this ImageReader, or returns null.
+     * 
+     * @return the the input source object such as ImageInputStream,
+     * or null.
+     */
+    public Object getInput() {
+        return input;
+    }
+
+    /**
+     * Checks if the input source supports only forward reading, or not.
+     * 
+     * @return true, if the input source supports only forward reading, 
+     * false otherwise.
+     */
+    public boolean isSeekForwardOnly() {
+        return seekForwardOnly;
+    }
+
+    /**
+     * Returns true if the current input source allows 
+     * to metadata to be ignored by passing true as 
+     * the ignoreMetadata argument to the setInput method.
+     * 
+     * @return true, if true if the current input source allows 
+     * to metadata to be ignored by passing true as 
+     * the ignoreMetadata argument to the setInput method.
+     */
+    public boolean isIgnoringMetadata() {
+        return ignoreMetadata;
+    }
+
+    /**
+     * Gets the minimum valid index for reading an image, thumbnail, 
+     * or image metadata. 
+     * 
+     * @return the minimum valid index for reading an image, thumbnail, 
+     * or image metadata.
+     */
+    public int getMinIndex() {
+        return minIndex;
+    }
+
+    /**
+     * Gets the available locales.
+     * 
+     * @return an array of the available locales.
+     */
+    public Locale[] getAvailableLocales() {
+        return availableLocales;
+    }
+
+    /**
+     * Sets the locale to this ImageReader.
+     * 
+     * @param locale the Locale.
+     */
+    public void setLocale(Locale locale) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets the locale of this ImageReader.
+     * 
+     * @return the locale of this ImageReader.
+     */
+    public Locale getLocale() {
+        return locale;
+    }
+
+    /**
+     * Gets the number of images available in the current input source.
+     * 
+     * @param allowSearch the parameter which indicates what
+     * a search is required; if false, the reader may return -1  
+     * without searching.
+     * 
+     * @return the number of images.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract int getNumImages(boolean allowSearch) throws IOException;
+
+    /**
+     * Gets the width of the specified image in input source.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return the width in pixels.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract int getWidth(int imageIndex) throws IOException;
+
+    /**
+     * Gets the height of the specified image in input source.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return the height in pixels.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract int getHeight(int imageIndex) throws IOException;
+
+    /**
+     * Checks if the storage format of the specified image places 
+     * an impediment on random pixels access or not. 
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return true, if the storage format of the specified image places 
+     * an impediment on random pixels access, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean isRandomAccessEasy(int imageIndex) throws IOException {
+        return false; //def
+    }
+
+    /**
+     * Gets the aspect ratio (width devided by height) of the image.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return the aspect ratio of the image.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public float getAspectRatio(int imageIndex) throws IOException {
+        return (float) getWidth(imageIndex) / getHeight(imageIndex);
+    }
+
+    /**
+     * Gets an ImageTypeSpecifier which indicates the type of the 
+     * specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the ImageTypeSpecifier.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageTypeSpecifier getRawImageType(int imageIndex) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets an Iterator of ImageTypeSpecifier objects which are associated
+     * with image types that may be used when decoding specified image.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return an Iterator of ImageTypeSpecifier objects.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException;
+
+    /**
+     * Gets the default ImageReadParam object.
+     * 
+     * @return the ImageReadParam object.
+     */
+    public ImageReadParam getDefaultReadParam() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets an IIOMetadata object for this input source.
+     * 
+     * @return the IIOMetadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract IIOMetadata getStreamMetadata() throws IOException;
+
+    /**
+     * Gets an IIOMetadata object for this input source.
+     * 
+     * @param formatName the desired metadata format to be used in the 
+     * returned IIOMetadata object.
+     * @param nodeNames the node names of the document.
+     * 
+     * @return the IIOMetadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public IIOMetadata getStreamMetadata(String formatName, Set<String> nodeNames)
+            throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets the image metadata of the specified image in input source.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return the IIOMetadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract IIOMetadata getImageMetadata(int imageIndex) throws IOException;
+
+    /**
+     * Gets the image metadata of the specified image input source.
+     * 
+     * @param imageIndex the image index.
+     * @param formatName the desired metadata format to be used in the 
+     * returned IIOMetadata object.
+     * @param nodeNames the node names which can be contained in
+     * the document.
+     * 
+     * @return the IIOMetadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public IIOMetadata getImageMetadata(int imageIndex, String formatName,
+                                        Set<String> nodeNames) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Reads the specified image and returns it as a BufferedImage
+     * using the default ImageReadParam.
+     *  
+     * @param imageIndex the image index.
+     * 
+     * @return the BufferedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public BufferedImage read(int imageIndex) throws IOException {
+        return read(imageIndex, null);
+    }
+
+    /**
+     * Reads the specified image and returns it as a BufferedImage
+     * using the specified ImageReadParam.
+     * 
+     * @param imageIndex the image index.
+     * @param param the ImageReadParam.
+     * 
+     * @return the BufferedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract BufferedImage read(int imageIndex, ImageReadParam param) throws IOException;
+
+    /**
+     * Reads the specified image and returns an IIOImage with this image,
+     * thumbnails, and metadata for this image, using 
+     * the specified ImageReadParam.
+     * 
+     * @param imageIndex the image index.
+     * @param param the ImageReadParam.
+     * 
+     * @return the IIOImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public IIOImage readAll(int imageIndex, ImageReadParam param) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Returns an Iterator of IIOImages from the input source. 
+     * 
+     * @param params the Iterator of ImageReadParam objects.
+     * 
+     * @return the iterator of IIOImages.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public Iterator<IIOImage> readAll(Iterator<? extends ImageReadParam> params) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Checks whether or not this plug-in supports reading a Raster.
+     * 
+     * @return true, if this plug-in supports reading a Raster,
+     * false otherwise.
+     */
+    public boolean canReadRaster() {
+        return false; //def
+    }
+
+    /**
+     * Reads a new Raster object which contains the raw pixel data from 
+     * the image. 
+     * 
+     * @param imageIndex the image index.
+     * @param param the ImageReadParam.
+     * 
+     * @return the Raster.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public Raster readRaster(int imageIndex, ImageReadParam param) throws IOException {
+        throw new UnsupportedOperationException("Unsupported");
+    }
+
+    /**
+     * Checks if the specified image has tiles or not.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return true, if the specified image has tiles,
+     * false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean isImageTiled(int imageIndex) throws IOException {
+        return false; //def
+    }
+
+    /**
+     * Gets the tile width in the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the tile width.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getTileWidth(int imageIndex) throws IOException {
+        return getWidth(imageIndex); //def
+    }
+
+    /**
+     * Gets the tile height in the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the tile height.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getTileHeight(int imageIndex) throws IOException {
+        return getHeight(imageIndex); //def
+    }
+
+    /**
+     * Gets the X coordinate of the upper left corner of the tile grid in the 
+     * specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the X coordinate of the upper left corner of the tile grid.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getTileGridXOffset(int imageIndex) throws IOException {
+        return 0; //def
+    }
+
+    /**
+     * Gets the Y coordinate of the upper left corner of the tile grid in the 
+     * specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the Y coordinate of the upper left corner of the tile grid.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getTileGridYOffset(int imageIndex) throws IOException {
+        return 0; //def
+    }
+
+    /**
+     * Reads the tile specified by the tileX and tileY parameters
+     * of the specified image and returns it as a BufferedImage. 
+     * 
+     * @param imageIndex the image index.
+     * @param tileX the X index of tile.
+     * @param tileY the Y index of tile.
+     * 
+     * @return the BufferedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public BufferedImage readTile(int imageIndex, int tileX, int tileY) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Reads the tile specified by the tileX and tileY parameters
+     * of the specified image and returns it as a Raster. 
+     * 
+     * @param imageIndex the image index.
+     * @param tileX the X index of tile.
+     * @param tileY the Y index of tile.
+     * 
+     * @return the Raster.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public Raster readTileRaster(int imageIndex, int tileX, int tileY) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Reads the specified image using the specified 
+     * ImageReadParam and returns it as a RenderedImage.
+     * 
+     * @param imageIndex the image index.
+     * @param param the ImageReadParam.
+     * 
+     * @return the RenderedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public RenderedImage readAsRenderedImage(int imageIndex, ImageReadParam param) throws IOException {
+        return read(imageIndex, param);
+    }
+
+    /**
+     * Returns true if the image format supported by this reader 
+     * supports thumbnail preview images.
+     * 
+     * @return true if the image format supported by this reader 
+     * supports thumbnail preview images, false otherwise.
+     */
+    public boolean readerSupportsThumbnails() {
+        return false; //def
+    }
+
+    /**
+     * Checks if the specified image has thumbnails or not.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return true, if the specified image has thumbnails,
+     * false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean hasThumbnails(int imageIndex) throws IOException {
+        return getNumThumbnails(imageIndex) > 0; //def
+    }
+
+    /**
+     * Gets the number of thumbnails for the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the number of thumbnails.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getNumThumbnails(int imageIndex) throws IOException {
+        return 0; //def
+    }
+
+    /**
+     * Gets the width of the specified thumbnail for the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * @param thumbnailIndex the thumbnail's index.
+     * 
+     * @return the thumbnail width.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getThumbnailWidth(int imageIndex, int thumbnailIndex) throws IOException {
+        return readThumbnail(imageIndex, thumbnailIndex).getWidth();  //def
+    }
+
+    /**
+     * Gets the height of the specified thumbnail for the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * @param thumbnailIndex the thumbnail's index.
+     * 
+     * @return the thumbnail height.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getThumbnailHeight(int imageIndex, int thumbnailIndex) throws IOException {
+        return readThumbnail(imageIndex, thumbnailIndex).getHeight();  //def
+    }
+
+    /**
+     * Reads the thumbnail image for the specified image
+     * as a BufferedImage.
+     *  
+     * @param imageIndex the image index.
+     * @param thumbnailIndex the thumbnail index.
+     * 
+     * @return the BufferedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public BufferedImage readThumbnail(int imageIndex, int thumbnailIndex) throws IOException {
+        throw new UnsupportedOperationException("Unsupported"); //def
+    }
+
+    /**
+     * Requests an abort operation for current reading operation. 
+     */
+    public void abort() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Checks whether or not a request to abort the current read operation 
+     * has been made successfully.
+     * 
+     * @return true, if the request to abort the current read operation 
+     * has been made successfully, false otherwise.
+     */
+    protected boolean abortRequested() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Clears all previous abort request, and abortRequested returns false
+     * after calling this method.
+     */
+    protected void clearAbortRequest() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Adds the IIOReadWarningListener.
+     * 
+     * @param listener the IIOReadWarningListener.
+     */
+    public void addIIOReadWarningListener(IIOReadWarningListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes the specified IIOReadWarningListener.
+     * 
+     * @param listener the IIOReadWarningListener to be removed.
+     */
+    public void removeIIOReadWarningListener(IIOReadWarningListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes all registered IIOReadWarningListeners.
+     */
+    public void removeAllIIOReadWarningListeners() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Adds the IIOReadProgressListener.
+     * 
+     * @param listener the IIOReadProgressListener.
+     */
+    public void addIIOReadProgressListener(IIOReadProgressListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes the specified IIOReadProgressListener.
+     * 
+     * @param listener the IIOReadProgressListener to be removed.
+     */
+    public void removeIIOReadProgressListener(IIOReadProgressListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes registered IIOReadProgressListeners.
+     */
+    public void removeAllIIOReadProgressListeners() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Adds the IIOReadUpdateListener.
+     * 
+     * @param listener the IIOReadUpdateListener.
+     */
+    public void addIIOReadUpdateListener(IIOReadUpdateListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes the specified IIOReadUpdateListener.
+     * 
+     * @param listener the IIOReadUpdateListener to be removed.
+     */
+    public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes registered IIOReadUpdateListeners.
+     */
+    public void removeAllIIOReadUpdateListeners() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the start of an sequence of image reads
+     * by calling the sequenceStarted method on all registered 
+     * IIOReadProgressListeners. 
+     * 
+     * @param minIndex the minimum index.
+     */
+    protected void processSequenceStarted(int minIndex) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the completion of an sequence of image reads
+     * by calling sequenceComplete method on all registered 
+     * IIOReadProgressListeners. 
+     */
+    protected void processSequenceComplete() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the start of an image read by calling the imageStarted
+     * method on all registered IIOReadProgressListeners.
+     * 
+     * @param imageIndex the image index.
+     */
+    protected void processImageStarted(int imageIndex) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the current percentage of image completion by calling 
+     * the imageProgress method on all registered IIOReadProgressListeners.
+     * 
+     * @param percentageDone the percentage done.
+     */
+    protected void processImageProgress(float percentageDone) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes image completion by calling the imageComplete method
+     * on all registered IIOReadProgressListeners. 
+     */
+    protected void processImageComplete() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the start of a thumbnail read by calling the
+     * thumbnailStarted method on all registered IIOReadProgressListeners. 
+     * 
+     * @param imageIndex the image index.
+     * @param thumbnailIndex the thumbnail index.
+     */
+    protected void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the current percentage of thumbnail completion 
+     * by calling the thumbnailProgress method on all registered 
+     * IIOReadProgressListeners.
+     * 
+     * @param percentageDone the percentage done.
+     */
+    protected void processThumbnailProgress(float percentageDone) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the completion of a thumbnail read 
+     * by calling the thumbnailComplete method 
+     * on all registered IIOReadProgressListeners. 
+     */
+    protected void processThumbnailComplete() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes a read aborted event by calling the readAborted 
+     * method on all registered IIOReadProgressListeners.
+     */
+    protected void processReadAborted() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the beginning of a progressive pass by calling 
+     * the passStarted method on all registered IIOReadUpdateListeners.
+     * 
+     * @param theImage the image to be updated.
+     * @param pass the current pass index.
+     * @param minPass the minimum pass index.
+     * @param maxPass the maximum pass index.
+     * @param minX the X coordinate of of the upper left pixel. 
+     * @param minY the Y coordinate of of the upper left pixel.
+     * @param periodX the horizontal separation between pixels.
+     * @param periodY the vertical separation between pixels.
+     * @param bands the number of affected bands.
+     */
+    protected void processPassStarted(BufferedImage theImage,
+                                  int pass,
+                                  int minPass,
+                                  int maxPass,
+                                  int minX,
+                                  int minY,
+                                  int periodX,
+                                  int periodY,
+                                  int[] bands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the update of a set of samples by calling 
+     * the imageUpdate method on all registered IIOReadUpdateListeners.  
+     * 
+     * @param theImage the image to be updated.
+     * @param minX the X coordinate of the upper left pixel.
+     * @param minY the Y coordinate of the upper left pixel.
+     * @param width the width of updated area.
+     * @param height the height of updated area.
+     * @param periodX the horizontal separation between pixels.
+     * @param periodY the vertical separation between pixels.
+     * @param bands the number of affected bands.
+     */
+    protected void processImageUpdate(BufferedImage theImage,
+                                  int minX,
+                                  int minY,
+                                  int width,
+                                  int height,
+                                  int periodX,
+                                  int periodY,
+                                  int[] bands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the end of a progressive pass by calling passComplete
+     * method of registered IIOReadUpdateListeners.
+     * 
+     * @param theImage the image to be updated.
+     */
+    protected void processPassComplete(BufferedImage theImage) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the beginning of a thumbnail progressive pass
+     * by calling the thumbnailPassStarted method on all 
+     * registered IIOReadUpdateListeners.
+     * 
+     * @param theThumbnail the the thumbnail to be updated.
+     * @param pass the current pass index.
+     * @param minPass the minimum pass index.
+     * @param maxPass the maximum pass index.
+     * @param minX the X coordinate of the upper left pixel. 
+     * @param minY the Y coordinate of the upper left pixel.
+     * @param periodX the horizontal separation between pixels.
+     * @param periodY the vertical separation between pixels.
+     * @param bands the number of affected bands.
+     */
+    protected void processThumbnailPassStarted(BufferedImage theThumbnail,
+                                           int pass,
+                                           int minPass,
+                                           int maxPass,
+                                           int minX,
+                                           int minY,
+                                           int periodX,
+                                           int periodY,
+                                           int[] bands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the update of a set of samples in a thumbnail 
+     * image by calling the thumbnailUpdate method on all
+     * registered IIOReadUpdateListeners. 
+     * 
+     * @param theThumbnail the the thumbnail to be updated.
+     * @param minX the X coordinate of the upper left pixel. 
+     * @param minY the Y coordinate of the upper left pixel.
+     * @param periodX the horizontal separation between pixels.
+     * @param periodY the vertical separation between pixels.
+     * @param bands the number of affected bands.
+     */
+    protected void processThumbnailUpdate(BufferedImage theThumbnail,
+                                      int minX,
+                                      int minY,
+                                      int width,
+                                      int height,
+                                      int periodX,
+                                      int periodY,
+                                       int[] bands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the end of a thumbnail progressive pass 
+     * by calling the thumbnailPassComplete method
+     * on all registered IIOReadUpdateListeners. 
+     * 
+     * @param theThumbnail the thumbnail to be updated.
+     */
+    protected void processThumbnailPassComplete(BufferedImage theThumbnail) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes a warning message by calling warningOccurred method
+     * of registered IIOReadWarningListeners.
+     * 
+     * @param warning the warning.
+     */
+    protected void processWarningOccurred(String warning) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes a warning by calling the warningOccurred method 
+     * of on all registered IIOReadWarningListeners.
+     * 
+     * @param baseName the base name of ResourceBundles.
+     * @param keyword the keyword to index the warning among ResourceBundles.
+     */
+    protected void processWarningOccurred(String baseName, String keyword) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Resets this ImageReader.
+     */
+    public void reset() {
+        // def
+        setInput(null, false);
+        setLocale(null);
+        removeAllIIOReadUpdateListeners();
+        removeAllIIOReadWarningListeners();
+        removeAllIIOReadProgressListeners();
+        clearAbortRequest();
+    }
+
+    /**
+     * Disposes of any resources.
+     */
+    public void dispose() {
+        // do nothing by def
+    }
+
+    /**
+     * Gets the region of source image that should be read with the 
+     * specified width, height and ImageReadParam. 
+     * 
+     * @param param the ImageReadParam object, or null.
+     * @param srcWidth the source image's width.
+     * @param srcHeight the source image's  height.
+     * 
+     * @return the Rectangle of source region.
+     */
+    protected static Rectangle getSourceRegion(ImageReadParam param, int srcWidth, int srcHeight) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Computes the specified source region and the specified destination 
+     * region with the specified the width and height of the source image,
+     * an optional destination image, and an ImageReadParam. 
+     * 
+     * @param param the an ImageReadParam object, or null.
+     * @param srcWidth the source image's width.
+     * @param srcHeight the source image's height.
+     * @param image the destination image.
+     * @param srcRegion the source region.
+     * @param destRegion the destination region.
+     */
+    protected static void computeRegions(ImageReadParam param,
+                                     int srcWidth,
+                                     int srcHeight,
+                                     BufferedImage image,
+                                     Rectangle srcRegion,
+                                     Rectangle destRegion) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Checks the validity of the source and destination band and is called
+     * when the reader knows the number of bands of the source image and 
+     * the number of bands of the destination image. 
+     * 
+     * @param param the ImageReadParam for reading the Image.
+     * @param numSrcBands the number of bands in the source.
+     * @param numDstBands the number of bands in the destination.
+     */
+    protected static void checkReadParamBandSettings(ImageReadParam param,
+                                                 int numSrcBands,
+                                                 int numDstBands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets the destination image where the decoded data is written. 
+     * 
+     * @param param the ImageReadParam.
+     * @param imageTypes the iterator of ImageTypeSpecifier objects.
+     * @param width the width of the image being decoded.
+     * @param height the height of the image being decoded.
+     * 
+     * @return the BufferedImage where decoded pixels should be written.
+     * 
+     * @throws IIOException the IIOException is thrown if 
+     * there is no suitable ImageTypeSpecifier.
+     */
+    protected static BufferedImage getDestination(ImageReadParam param, Iterator<ImageTypeSpecifier> imageTypes,
+                                              int width,
+                                              int height)
+                                       throws IIOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+}
diff --git a/awt/javax/imageio/ImageTranscoder.java b/awt/javax/imageio/ImageTranscoder.java
new file mode 100644
index 0000000..1a0de76
--- /dev/null
+++ b/awt/javax/imageio/ImageTranscoder.java
@@ -0,0 +1,60 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.ImageTypeSpecifier;
+
+/**
+ * The ImageTranscoder interface is to be implemented by classes that
+ * perform image transcoding operations, that is, take images written
+ * in one format and write them in another format using
+ * read/write operations. Some image data can be lost in such processes.
+ * The ImageTranscoder interface converts metadata objects (IIOMetadata)
+ * of ImageReader to apropriate metadata object for ImageWriter.
+ */
+public interface ImageTranscoder {
+    
+    /**
+     * Converts the specified IIOMetadata object using the specified
+     * ImageWriteParam for obtaining writer's metadata structure.
+     * 
+     * @param inData the IIOMetadata.
+     * @param param the ImageWriteParam.
+     * 
+     * @return the IIOMetadata, or null.
+     */
+    IIOMetadata convertStreamMetadata(IIOMetadata inData, ImageWriteParam param);
+
+    /**
+     * Converts the specified IIOMetadata object using the specified
+     * ImageWriteParam for obtaining writer's metadata structure 
+     * and ImageTypeSpecifier object for obtaining the layout and 
+     * color information of the image for this metadata.
+     * 
+     * @param inData the IIOMetadata.
+     * @param imageType the ImageTypeSpecifier.
+     * @param param the ImageWriteParam.
+     * 
+     * @return the IIOMetadata, or null.
+     */
+    IIOMetadata convertImageMetadata(IIOMetadata inData, ImageTypeSpecifier imageType, ImageWriteParam param);
+}
diff --git a/awt/javax/imageio/ImageTypeSpecifier.java b/awt/javax/imageio/ImageTypeSpecifier.java
new file mode 100644
index 0000000..c93f269
--- /dev/null
+++ b/awt/javax/imageio/ImageTypeSpecifier.java
@@ -0,0 +1,339 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import java.awt.image.ColorModel;
+import java.awt.image.SampleModel;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+import java.awt.color.ColorSpace;
+
+/**
+ * The ImageTypeSpecifier class performs conversion operations
+ * on the SampleModel and the ColorModel of an image.
+ */
+public class ImageTypeSpecifier {
+    
+    /** 
+     * The ColorModel of this ImageTypeSpecifier.
+     */
+    protected ColorModel colorModel;
+    
+    /** 
+     * The SampleModel of this ImageTypeSpecifier. 
+     */
+    protected SampleModel sampleModel;
+
+    /**
+     * Instantiates a new ImageTypeSpecifier with the specified
+     * ColorModel and SampleModel objects.
+     * 
+     * @param colorModel the ColorModel.
+     * @param sampleModel the SampleModel.
+     */
+    public ImageTypeSpecifier(ColorModel colorModel, SampleModel sampleModel) {
+        if (colorModel == null) {
+            throw new IllegalArgumentException("color model should not be NULL");
+        }
+        if (sampleModel == null) {
+            throw new IllegalArgumentException("sample model should not be NULL");
+        }
+        if (!colorModel.isCompatibleSampleModel(sampleModel)) {
+            throw new IllegalArgumentException("color and sample models are not compatible");
+        }
+
+        this.colorModel = colorModel;
+        this.sampleModel = sampleModel;
+    }
+
+    /**
+     * Instantiates a new ImageTypeSpecifier using the specified 
+     * RenderedImage.
+     * 
+     * @param renderedImage the RenderedImage.
+     */
+    public ImageTypeSpecifier(RenderedImage renderedImage) {
+        if (renderedImage == null) {
+            throw new IllegalArgumentException("image should not be NULL");
+        }
+        this.colorModel = renderedImage.getColorModel();
+        this.sampleModel = renderedImage.getSampleModel();
+    }
+
+    /**
+     * Creates an ImageTypeSpecifier with the specified
+     * DirectColorModel and a packed SampleModel.
+     * 
+     * @param colorSpace the ColorSpace.
+     * @param redMask the red mask.
+     * @param greenMask the green mask.
+     * @param blueMask the blue mask.
+     * @param alphaMask the alpha mask.
+     * @param transferType the transfer type.
+     * @param isAlphaPremultiplied the parameter indicates
+     * if the color channel is premultiplied by alpha.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createPacked(ColorSpace colorSpace,
+                                                  int redMask,
+                                                  int greenMask,
+                                                  int blueMask,
+                                                  int alphaMask,
+                                                  int transferType,
+                                                  boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates an ImageTypeSpecifier with specified
+     * ComponentColorModel and a PixelInterleavedSampleModel.
+     * 
+     * @param colorSpace the ColorSpace.
+     * @param bandOffsets the band offsets.
+     * @param dataType the data type.
+     * @param hasAlpha the parameter indicates if alpha channel
+     * is needed.
+     * @param isAlphaPremultiplied the parameter indicates
+     * if the color channel is premultiplied by alpha.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createInterleaved(ColorSpace colorSpace,
+                                                       int[] bandOffsets,
+                                                       int dataType,
+                                                       boolean hasAlpha,
+                                                       boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+
+    /**
+     * Creates a ImageTypeSpecifier for a image with a 
+     * BandedSampleModel and a ComponentColorModel.
+     * 
+     * @param colorSpace the ColorSpace.
+     * @param bankIndices the bank indices.
+     * @param bandOffsets the band offsets.
+     * @param dataType the data type.
+     * @param hasAlpha the parameter indicates a presence of alpha channel.
+     * @param isAlphaPremultiplied the parameter indicates whether
+     * or not color channel is alpha premultiplied.
+     * 
+     * @return the image type specifier
+     */
+    public static ImageTypeSpecifier createBanded(ColorSpace colorSpace,
+                                                  int[] bankIndices,
+                                                  int[] bandOffsets,
+                                                  int dataType,
+                                                  boolean hasAlpha,
+                                                  boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates a ImageTypeSpecifier for a grayscale image.
+     * 
+     * @param bits the number of bits per gray value.
+     * @param dataType the data type.
+     * @param isSigned a signed flag.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createGrayscale(int bits,
+                                                     int dataType,
+                                                     boolean isSigned) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates a ImageTypeSpecifier for a grayscale image.
+     * 
+     * @param bits the number of bits per gray value.
+     * @param dataType the data type.
+     * @param isSigned a signed flag.
+     * @param isAlphaPremultiplied the parameter indicates
+     * if color channel is premultiplied by alpha, or not.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createGrayscale(int bits,
+                                                     int dataType,
+                                                     boolean isSigned,
+                                                     boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates a ImageTypeSpecifier with the indexed image format.
+     * 
+     * @param redLUT the red values of indecies.
+     * @param greenLUT the green values of indecies.
+     * @param blueLUT the blue values of indecies.
+     * @param alphaLUT the alpha values of indecies.
+     * @param bits the bits number for each index.
+     * @param dataType the data type.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createIndexed(byte[] redLUT,
+                                                   byte[] greenLUT,
+                                                   byte[] blueLUT,
+                                                   byte[] alphaLUT,
+                                                   int bits,
+                                                   int dataType) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates the ImageTypeSpecifier from 
+     * the specified buffered image type.
+     * 
+     * @param bufferedImageType the buffered image type.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createFromBufferedImageType(int bufferedImageType) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates the ImageTypeSpecifier from 
+     * the specified RenderedImage.
+     * 
+     * @param image the RenderedImage.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createFromRenderedImage(RenderedImage image) {
+        if (null == image) {
+            throw new IllegalArgumentException("image should not be NULL");
+        }
+        return new ImageTypeSpecifier(image);
+    }
+
+    /**
+     * Gets the BufferedImage type.
+     * 
+     * @return the BufferedImage type.
+     */
+    public int getBufferedImageType() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the number of components.
+     * 
+     * @return the number of components
+     */
+    public int getNumComponents() {
+        return colorModel.getNumComponents();
+    }
+
+    /**
+     * Gets the number of bands.
+     * 
+     * @return the number of bands
+     */
+    public int getNumBands() {
+        return sampleModel.getNumBands();
+    }
+
+    /**
+     * Gets the number of bits per the specified band.
+     * 
+     * @param band the index of band.
+     * 
+     * @return the number of bits per the specified band.
+     */
+    public int getBitsPerBand(int band) {
+        if (band < 0 || band >= getNumBands()) {
+            throw new IllegalArgumentException();
+        }
+        return sampleModel.getSampleSize(band);
+    }
+
+    /**
+     * Gets the SampleModel associated with this ImageTypeSpecifier.
+     * 
+     * @return the SampleModel associated with this ImageTypeSpecifier.
+     */
+    public SampleModel getSampleModel() {
+        return sampleModel;
+    }
+
+    /**
+     * Gets a compatible SampleModel with the specified width and height.
+     * 
+     * @param width the width.
+     * @param height the height.
+     * 
+     * @return the SampleModel.
+     */
+    public SampleModel getSampleModel(int width, int height) {
+        if ((long)width*height > Integer.MAX_VALUE) {
+            throw new IllegalArgumentException("width * height > Integer.MAX_VALUE");
+        }
+        return sampleModel.createCompatibleSampleModel(width, height);
+    }
+
+    /**
+     * Gets the ColorModel associated with this ImageTypeSpecifier.
+     * 
+     * @return the ColorModel associated with this ImageTypeSpecifier. 
+     */
+    public ColorModel getColorModel() {
+        return colorModel;
+    }
+
+    /**
+     * Creates the BufferedImage with the specified width and height 
+     * and the ColorMadel and SampleModel which are specified by this 
+     * ImageTypeSpecifier.
+     * 
+     * @param width the width of the BufferedImage.
+     * @param height the height of the BufferedImage.
+     * 
+     * @return the BufferedImage.
+     */
+    public BufferedImage createBufferedImage(int width, int height) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Compares this ImageTypeSpecifier object with the specified 
+     * object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if the object is an ImageTypeSpecifier with the same
+     * data as this ImageTypeSpecifier, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        boolean rt = false;
+        if (o instanceof ImageTypeSpecifier) {
+            ImageTypeSpecifier ts = (ImageTypeSpecifier) o;
+            rt = colorModel.equals(ts.colorModel) && sampleModel.equals(ts.sampleModel);
+        }
+        return rt;
+    }
+}
\ No newline at end of file
diff --git a/awt/javax/imageio/ImageWriteParam.java b/awt/javax/imageio/ImageWriteParam.java
new file mode 100644
index 0000000..d32fa59
--- /dev/null
+++ b/awt/javax/imageio/ImageWriteParam.java
@@ -0,0 +1,633 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import java.util.Locale;
+import java.awt.*;
+
+/**
+ * The ImageWriteParam class provides information to an ImageWriter 
+ * about how an image is to be encoded.
+ */
+public class ImageWriteParam extends IIOParam {
+
+    /** 
+     * The Constant MODE_DISABLED indicates that 
+     * stream is not tiled, progressive, or compressed.
+     */
+    public static final int MODE_DISABLED = 0;
+    
+    /** 
+     * The Constant MODE_DEFAULT indicates that the stream will be tiled, 
+     * progressive, or compressed according to the plug-in's default. 
+     */
+    public static final int MODE_DEFAULT = 1;
+    
+    /** 
+     * The Constant MODE_EXPLICIT indicates that the stream will be tiled,
+     * progressive, or compressed according to current settings
+     * which are defined by set methods. 
+     */
+    public static final int MODE_EXPLICIT = 2;
+    
+    /** 
+     * The Constant MODE_COPY_FROM_METADATA indicates that the stream
+     * will be tiled, progressive, or compressed according to
+     * stream or image metadata. 
+     */
+    public static final int MODE_COPY_FROM_METADATA = 3;
+    
+    /** Whether the ImageWriter can write tiles. */
+    protected boolean canWriteTiles = false;
+    
+    /** The tiling mode. */
+    protected int tilingMode = MODE_COPY_FROM_METADATA;
+    
+    /** The preferred tile sizes. */
+    protected Dimension[] preferredTileSizes = null;
+    
+    /** The tiling set. */
+    protected boolean tilingSet = false;
+    
+    /** The tile width. */
+    protected int tileWidth = 0;
+    
+    /** The tile height. */
+    protected int tileHeight = 0;
+    
+    /** Whether the ImageWriter can offset tiles. */
+    protected boolean canOffsetTiles = false;
+    
+    /** The tile grid x offset. */
+    protected int tileGridXOffset = 0;
+    
+    /** The tile grid y offset. */
+    protected int tileGridYOffset = 0;
+    
+    /** Whether the ImageWriter can write in progressive mode. */
+    protected boolean canWriteProgressive = false;
+    
+    /** The progressive mode. */
+    protected int progressiveMode = MODE_COPY_FROM_METADATA;
+    
+    /** Whether the ImageWriter can write in compressed mode. */
+    protected boolean canWriteCompressed = false;
+    
+    /** The compression mode. */
+    protected int compressionMode = MODE_COPY_FROM_METADATA;
+    
+    /** The compression types. */
+    protected String[] compressionTypes = null;
+    
+    /** The compression type. */
+    protected String compressionType = null;
+    
+    /** The compression quality. */
+    protected float compressionQuality = 1.0f;
+    
+    /** The locale. */
+    protected Locale locale = null;
+
+    /**
+     * Instantiates a new ImageWriteParam.
+     */
+    protected ImageWriteParam() {}
+
+    /**
+     * Instantiates a new ImageWriteParam with the specified Locale.
+     * 
+     * @param locale the Locale.
+     */
+    public ImageWriteParam(Locale locale) {
+        this.locale = locale;
+
+    }
+
+    /**
+     * Gets the mode for writing the stream in a progressive sequence. 
+     * 
+     * @return the current progressive mode.
+     */
+    public int getProgressiveMode() {
+        if (canWriteProgressive()) {
+            return progressiveMode;
+        }
+        throw new UnsupportedOperationException("progressive mode is not supported");
+    }
+
+    /**
+     * Returns true if images can be written using 
+     * increasing quality passes by progressive.  
+     * 
+     * @return true if images can be written using 
+     * increasing quality passes by progressive, false otherwise.
+     */
+    public boolean canWriteProgressive() {
+        return canWriteProgressive;
+    }
+
+    /**
+     * Sets the progressive mode which defines whether the stream 
+     * contains a progressive sequence of increasing quality
+     * during writing. The progressive mode should be one of
+     * the following values: MODE_DISABLED, MODE_DEFAULT, or
+     * MODE_COPY_FROM_METADATA.
+     * 
+     * @param mode the new progressive mode.
+     */
+    public void setProgressiveMode(int mode) {
+        if (canWriteProgressive()) {
+            if (mode < MODE_DISABLED || mode > MODE_COPY_FROM_METADATA || mode == MODE_EXPLICIT) {
+                throw new IllegalArgumentException("mode is not supported");
+            }
+            this.progressiveMode = mode;
+        }
+        throw new UnsupportedOperationException("progressive mode is not supported");
+    }
+
+    /**
+     * Returns true if the writer can use tiles with non zero 
+     * grid offsets while writing. 
+     * 
+     * @return true if the writer can use tiles with non zero 
+     * grid offsets while writing, false otherwise.
+     */
+    public boolean canOffsetTiles() {
+        return canOffsetTiles;
+    }
+
+    /**
+     * Returns true if this writer can write images with 
+     * compression.  
+     * 
+     * @return true, true if this writer can write images with 
+     * compression, false otherwise.
+     */
+    public boolean canWriteCompressed() {
+        return canWriteCompressed;
+    }
+
+    /**
+     * Returns true if the writer can write tiles.
+     * 
+     * @return true if the writer can write tiles, false otherwise.
+     */
+    public boolean canWriteTiles() {
+        return canWriteTiles;
+    }
+
+    /**
+     * Check write compressed.
+     */
+    private final void checkWriteCompressed() {
+        if (!canWriteCompressed()) {
+            throw new UnsupportedOperationException("Compression not supported.");
+        }
+    }
+
+    /**
+     * Check compression mode.
+     */
+    private final void checkCompressionMode() {
+        if (getCompressionMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
+        }
+    }
+
+    /**
+     * Check compression type.
+     */
+    private final void checkCompressionType() {
+        if (getCompressionTypes() != null && getCompressionType() == null) {
+            throw new IllegalStateException("No compression type set!");
+        }
+    }
+
+    /**
+     * Gets the compression mode.
+     * 
+     * @return the compression mode if it's supported.
+     */
+    public int getCompressionMode() {
+        checkWriteCompressed();
+        return compressionMode;
+    }
+
+    /**
+     * Gets the an array of supported compression types.
+     * 
+     * @return the an array of supported compression types.
+     */
+    public String[] getCompressionTypes() {
+        checkWriteCompressed();
+        if (compressionTypes != null) {
+            return compressionTypes.clone();
+        }
+        return null;
+    }
+
+    /**
+     * Gets the current compression type, or returns null.
+     * 
+     * @return the current compression type, or returns null 
+     * if it is not set.
+     */
+    public String getCompressionType() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        return compressionType;
+    }
+
+    /**
+     * Gets a bit rate which represents an estimate of the number of bits 
+     * of output data for each bit of input image data with the specified 
+     * quality.
+     * 
+     * @param quality the quality.
+     * 
+     * @return an estimate of the bit rate, or -1.0F if there is no 
+     * estimate. 
+     */
+    public float getBitRate(float quality) {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        if (quality < 0 || quality > 1) {
+            throw new IllegalArgumentException("Quality out-of-bounds!");
+        }
+        return -1.0f;
+    }
+
+    /**
+     * Gets the compression quality.
+     * 
+     * @return the compression quality.
+     */
+    public float getCompressionQuality() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return compressionQuality;
+    }
+
+    /**
+     * Gets the array of compression quality descriptions.
+     * 
+     * @return the string array of compression quality descriptions.
+     */
+    public String[] getCompressionQualityDescriptions() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return null;
+    }
+
+    /**
+     * Gets an array of floats which decribe 
+     * compression quality levels. 
+     * 
+     * @return the array of compression quality values.
+     */
+    public float[] getCompressionQualityValues() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return null;
+    }
+
+    /**
+     * Gets the locale of this ImageWriteParam.
+     * 
+     * @return the locale of this ImageWriteParam.
+     */
+    public Locale getLocale() {
+        return locale;
+    }
+
+    /**
+     * Gets the current compression type using the current Locale. 
+     * 
+     * @return the current compression type using the current Locale.
+     */
+    public String getLocalizedCompressionTypeName() {
+        checkWriteCompressed();
+        checkCompressionMode();
+
+        String compressionType = getCompressionType();
+        if (compressionType == null) {
+            throw new IllegalStateException("No compression type set!");
+        }
+        return compressionType;
+
+    }
+
+    /**
+     * Check tiling.
+     */
+    private final void checkTiling() {
+        if (!canWriteTiles()) {
+            throw new UnsupportedOperationException("Tiling not supported!");
+        }
+    }
+
+    /**
+     * Check tiling mode.
+     */
+    private final void checkTilingMode() {
+        if (getTilingMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
+        }
+    }
+
+    /**
+     * Check tiling params.
+     */
+    private final void checkTilingParams() {
+        if (!tilingSet) {
+            throw new IllegalStateException("Tiling parameters not set!");
+        }
+    }
+
+    /**
+     * Gets the tiling mode if tiling is supported.
+     * 
+     * @return the tiling mode if tiling is supported.
+     */
+    public int getTilingMode() {
+        checkTiling();
+        return tilingMode;
+    }
+
+    /**
+     * Gets an array of Dimensions giving the sizes of the tiles as 
+     * they are encoded in the output file or stream. 
+     * 
+     * @return the preferred tile sizes.
+     */
+    public Dimension[] getPreferredTileSizes() {
+        checkTiling();
+        if (preferredTileSizes == null) {
+            return null;
+        }
+
+        Dimension[] retval = new Dimension[preferredTileSizes.length];
+        for (int i = 0; i < preferredTileSizes.length; i++) {
+            retval[i] = new Dimension(retval[i]);
+        }
+        return retval;
+    }
+
+    /**
+     * Gets the tile grid X offset for encoding.
+     * 
+     * @return the tile grid X offset for encoding.
+     */
+    public int getTileGridXOffset() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileGridXOffset;
+    }
+
+    /**
+     * Gets the tile grid Y offset for encoding.
+     * 
+     * @return the tile grid Y offset for encoding.
+     */
+    public int getTileGridYOffset() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileGridYOffset;
+    }
+
+    /**
+     * Gets the tile height in an image as it is written to the 
+     * output stream.
+     * 
+     * @return the tile height in an image as it is written to the 
+     * output stream.
+     */
+    public int getTileHeight() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileHeight;
+    }
+
+    /**
+     * Gets the tile width in an image as it is written to the 
+     * output stream.
+     * 
+     * @return the tile width in an image as it is written to the 
+     * output stream.
+     */
+    public int getTileWidth() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileWidth;
+    }
+
+    /**
+     * Checks if the current compression type has lossless 
+     * compression or not. 
+     * 
+     * @return true, if the current compression type has lossless 
+     * compression, false otherwise.
+     */
+    public boolean isCompressionLossless() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return true;
+    }
+
+    /**
+     * Removes current compression type.
+     */
+    public void unsetCompression() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        compressionType = null;
+        compressionQuality = 1;
+    }
+
+    /**
+     * Sets the compression mode to the specified value.
+     * The specified mode can be one of the predefined
+     * constants: MODE_DEFAULT, MODE_DISABLED, MODE_EXPLICIT, 
+     * or MODE_COPY_FROM_METADATA.
+     *  
+     * @param mode the new compression mode to be set.
+     */
+    public void setCompressionMode(int mode) {
+        checkWriteCompressed();
+        switch (mode) {
+            case MODE_EXPLICIT: {
+                compressionMode = mode;
+                unsetCompression();
+                break;
+            }
+            case MODE_COPY_FROM_METADATA:
+            case MODE_DISABLED:
+            case MODE_DEFAULT: {
+                compressionMode = mode;
+                break;
+            }
+            default: {
+                throw new IllegalArgumentException("Illegal value for mode!");
+            }
+        }
+    }
+
+    /**
+     * Sets the compression quality. The value should be between 0 and 1.
+     * 
+     * @param quality the new compression quality, 
+     * float value between 0 and 1. 
+     */
+    public void setCompressionQuality(float quality) {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        if (quality < 0 || quality > 1) {
+            throw new IllegalArgumentException("Quality out-of-bounds!");
+        }
+        compressionQuality = quality;
+    }
+
+    /**
+     * Sets the compression type. The specified string
+     * should be one of the values returned 
+     * by getCompressionTypes method.
+     * 
+     * @param compressionType the new compression type.
+     */
+    public void setCompressionType(String compressionType) {
+        checkWriteCompressed();
+        checkCompressionMode();
+
+        if (compressionType == null) { // Don't check anything
+            this.compressionType = null;
+        } else {
+            String[] compressionTypes = getCompressionTypes();
+            if (compressionTypes == null) {
+                throw new UnsupportedOperationException("No settable compression types");
+            }
+
+            for (int i = 0; i < compressionTypes.length; i++) {
+                if (compressionTypes[i].equals(compressionType)) {
+                    this.compressionType = compressionType;
+                    return;
+                }
+            }
+
+            // Compression type is not in the list.
+            throw new IllegalArgumentException("Unknown compression type!");
+        }
+    }
+
+    /**
+     * Sets the instruction that tiling should be performed for 
+     * the image in the output stream with the specified parameters. 
+     * 
+     * @param tileWidth the tile's width.
+     * @param tileHeight the tile's height.
+     * @param tileGridXOffset the tile grid's x offset.
+     * @param tileGridYOffset the tile grid's y offset.
+     */
+    public void setTiling(int tileWidth, int tileHeight, int tileGridXOffset, int tileGridYOffset) {
+        checkTiling();
+        checkTilingMode();
+
+        if (!canOffsetTiles() && (tileGridXOffset != 0 || tileGridYOffset != 0)) {
+            throw new UnsupportedOperationException("Can't offset tiles!");
+        }
+
+        if (tileWidth <=0 || tileHeight <= 0) {
+            throw new IllegalArgumentException("tile dimensions are non-positive!");
+        }
+
+        Dimension preferredTileSizes[] = getPreferredTileSizes();
+        if (preferredTileSizes != null) {
+            for (int i = 0; i < preferredTileSizes.length; i+=2) {
+                Dimension minSize = preferredTileSizes[i];
+                Dimension maxSize = preferredTileSizes[i+1];
+                if (
+                        tileWidth < minSize.width || tileWidth > maxSize.width ||
+                        tileHeight < minSize.height || tileHeight > maxSize.height
+                ) {
+                    throw new IllegalArgumentException("Illegal tile size!");
+                }
+            }
+        }
+
+        tilingSet = true;
+        this.tileWidth = tileWidth;
+        this.tileHeight = tileHeight;
+        this.tileGridXOffset = tileGridXOffset;
+        this.tileGridYOffset = tileGridYOffset;
+    }
+
+    /**
+     * Clears all tiling settings.
+     */
+    public void unsetTiling() {
+        checkTiling();
+        checkTilingMode();
+
+        tilingSet = false;
+        tileWidth = 0;
+        tileHeight = 0;
+        tileGridXOffset = 0;
+        tileGridYOffset = 0;
+    }
+
+    /**
+     * Sets the tiling mode. The specified mode should be one of the 
+     * following values: MODE_DISABLED, MODE_DEFAULT, MODE_EXPLICIT,
+     * or MODE_COPY_FROM_METADATA.
+     * 
+     * @param mode the new tiling mode.
+     */
+    public void setTilingMode(int mode) {
+        checkTiling();
+
+        switch (mode) {
+            case MODE_EXPLICIT: {
+                tilingMode = mode;
+                unsetTiling();
+                break;
+            }
+            case MODE_COPY_FROM_METADATA:
+            case MODE_DISABLED:
+            case MODE_DEFAULT: {
+                tilingMode = mode;
+                break;
+            }
+            default: {
+                throw new IllegalArgumentException("Illegal value for mode!");
+            }
+        }
+    }
+}
+
diff --git a/awt/javax/imageio/ImageWriter.java b/awt/javax/imageio/ImageWriter.java
new file mode 100644
index 0000000..d6119b0
--- /dev/null
+++ b/awt/javax/imageio/ImageWriter.java
@@ -0,0 +1,951 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.imageio.event.IIOWriteProgressListener;
+import javax.imageio.event.IIOWriteWarningListener;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageWriterSpi;
+
+/**
+ * The ImageWriter class is an abstract class for encoding images.
+ * ImageWriter objects are instantiated by the service provider 
+ * interface, ImageWriterSpi class, for the specific format. 
+ * ImageWriterSpi class should be registered with the IIORegistry, 
+ * which uses them for format recognition and presentation of available 
+ * format readers and writers.
+ */
+public abstract class ImageWriter implements ImageTranscoder {
+
+    /** The available locales. */
+    protected Locale[] availableLocales;
+    
+    /** The locale. */
+    protected Locale locale;
+    
+    /** The originating provider. */
+    protected ImageWriterSpi originatingProvider;
+    
+    /** The output. */
+    protected Object output;
+    
+    /** The progress listeners. */
+    protected List<IIOWriteProgressListener> progressListeners;
+    
+    /** The warning listeners. */
+    protected List<IIOWriteWarningListener> warningListeners;
+    
+    /** The warning locales. */
+    protected List<Locale> warningLocales;
+
+    // Indicates that abort operation is requested
+    // Abort mechanism should be thread-safe
+    /** The aborted. */
+    private boolean aborted;
+
+    /**
+     * Instantiates a new ImageWriter.
+     * 
+     * @param originatingProvider the ImageWriterSpi which 
+     * instanties this ImageWriter.
+     */
+    protected ImageWriter(ImageWriterSpi originatingProvider) {
+        this.originatingProvider = originatingProvider;
+    }
+
+    public abstract IIOMetadata convertStreamMetadata(IIOMetadata iioMetadata,
+                                             ImageWriteParam imageWriteParam);
+
+    public abstract IIOMetadata convertImageMetadata(IIOMetadata iioMetadata,
+                                            ImageTypeSpecifier imageTypeSpecifier,
+                                            ImageWriteParam imageWriteParam);
+
+    /**
+     * Gets the ImageWriterSpi which instantiated this ImageWriter. 
+     * 
+     * @return the ImageWriterSpi.
+     */
+    public ImageWriterSpi getOriginatingProvider() {
+        return originatingProvider;
+    }
+
+    /**
+     * Processes the start of an image read by calling their imageStarted
+     * method of registered IIOWriteProgressListeners.
+     * 
+     * @param imageIndex the image index.
+     */
+    protected void processImageStarted(int imageIndex) {
+        if (null != progressListeners) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.imageStarted(this, imageIndex);
+            }
+        }
+    }
+
+    /**
+     * Processes the current percentage of image completion by calling 
+     * imageProgress method of registered IIOWriteProgressListener.
+     * 
+     * @param percentageDone the percentage done.
+     */
+    protected void processImageProgress(float percentageDone) {
+        if (null != progressListeners) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.imageProgress(this, percentageDone);
+            }
+        }
+    }
+
+    /**
+     * Processes image completion by calling imageComplete method
+     * of registered IIOWriteProgressListeners. 
+     */
+    protected void processImageComplete() {
+        if (null != progressListeners) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.imageComplete(this);
+            }
+        }
+    }
+
+    /**
+     * Processes a warning message by calling warningOccurred method
+     * of registered IIOWriteWarningListeners.
+     * 
+     * @param imageIndex the image index.
+     * @param warning the warning.
+     */
+    protected void processWarningOccurred(int imageIndex, String warning) {
+        if (null == warning) {
+            throw new NullPointerException("warning message should not be NULL");
+        }
+        if (null != warningListeners) {
+            for (IIOWriteWarningListener listener : warningListeners) {
+                listener.warningOccurred(this, imageIndex, warning);
+            }
+        }
+    }
+
+    /**
+     * Processes a warning message by calling warningOccurred method
+     * of registered IIOWriteWarningListeners with string from 
+     * ResourceBundle.
+     * 
+     * @param imageIndex the image index.
+     * @param bundle the name of ResourceBundle.
+     * @param key the keyword.
+     */
+    protected void processWarningOccurred(int imageIndex, String bundle, String key) {
+        if (warningListeners != null) { // Don't check the parameters
+            return;
+        }
+
+        if (bundle == null) {
+            throw new IllegalArgumentException("baseName == null!");
+        }
+        if (key == null) {
+            throw new IllegalArgumentException("keyword == null!");
+        }
+
+        // Get the context class loader and try to locate the bundle with it first
+        ClassLoader contextClassloader = AccessController.doPrivileged(
+                new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        return Thread.currentThread().getContextClassLoader();
+                    }
+        });
+
+        // Iterate through both listeners and locales
+        int n = warningListeners.size();
+        for (int i=0; i < n; i++) {
+            IIOWriteWarningListener listener = warningListeners.get(i);
+            Locale locale = warningLocales.get(i);
+
+            // Now try to get the resource bundle
+            ResourceBundle rb;
+            try {
+                rb = ResourceBundle.getBundle(bundle, locale, contextClassloader);
+            } catch (MissingResourceException e) {
+                try {
+                    rb = ResourceBundle.getBundle(bundle, locale);
+                } catch (MissingResourceException e1) {
+                    throw new IllegalArgumentException("Bundle not found!");
+                }
+            }
+
+            try {
+                String warning = rb.getString(key);
+                listener.warningOccurred(this, imageIndex, warning);
+            } catch (MissingResourceException e) {
+                throw new IllegalArgumentException("Resource is missing!");
+            } catch (ClassCastException e) {
+                throw new IllegalArgumentException("Resource is not a String!");
+            }
+        }
+    }
+
+    /**
+     * Sets the specified Object to the output of this ImageWriter. 
+     * 
+     * @param output the Object which represents destination, it can 
+     * be ImageOutputStream or other objects.
+     */
+    public void setOutput(Object output) {
+        if (output != null) {
+            ImageWriterSpi spi = getOriginatingProvider();
+            if (null != spi) {
+                Class[] outTypes = spi.getOutputTypes();
+                boolean supported = false;
+                for (Class<?> element : outTypes) {
+                    if (element.isInstance(output)) {
+                        supported = true;
+                        break;
+                    }
+                }
+                if (!supported) {
+                    throw new IllegalArgumentException("output " + output + " is not supported");
+                }
+            }
+        }
+        this.output = output;
+    }
+
+    /**
+     * Writes a completed image stream that contains the specified image, 
+     * default metadata, and thumbnails to the output.
+     * 
+     * @param image the specified image to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred
+     * during writting.
+     */
+    public void write(IIOImage image) throws IOException {
+        write(null, image, null);
+    }
+
+    /**
+     * Writes a completed image stream that contains the specified 
+     * rendered image, default metadata, and thumbnails to the output.
+     * 
+     * @param image the specified RenderedImage to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred
+     * during writting.
+     */
+    public void write(RenderedImage image) throws IOException {
+        write(null, new IIOImage(image, null, null), null);
+    }
+
+    /**
+     * Writes a completed image stream that contains the specified image,
+     * metadata and thumbnails to the output.
+     * 
+     * @param streamMetadata the stream metadata, or null.
+     * @param image the specified image to be written, if
+     * canWriteRaster() method returns false, then Image must contain 
+     * only RenderedImage.
+     * @param param the ImageWriteParam, or null.
+     * 
+     * @throws IOException - if an error occurs during writing.
+     */
+    public abstract void write(IIOMetadata streamMetadata,
+                               IIOImage image, ImageWriteParam param) throws IOException;
+
+    /**
+     * Disposes of any resources.
+     */
+    public void dispose() {
+        // def impl. does nothing according to the spec.
+    }
+
+    /**
+     * Requests an abort operation for current writing operation. 
+     */
+    public synchronized void abort() {
+        aborted = true;
+    }
+
+    /**
+     * Checks whether or not a request to abort the current write operation 
+     * has been made successfully.
+     * 
+     * @return true, if the request to abort the current write operation 
+     * has been made successfully, false otherwise.
+     */
+    protected synchronized boolean abortRequested() {
+        return aborted;
+    }
+
+    /**
+     * Clears all previous abort request, and abortRequested returns false
+     * after calling this method.
+     */
+    protected synchronized void clearAbortRequest() {
+        aborted = false;
+    }
+
+    /**
+     * Adds the IIOWriteProgressListener listener.
+     * 
+     * @param listener the IIOWriteProgressListener listener.
+     */
+    public void addIIOWriteProgressListener(IIOWriteProgressListener listener) {
+        if (listener == null) {
+            return;
+        }
+
+        if (progressListeners == null) {
+            progressListeners = new ArrayList<IIOWriteProgressListener>();
+        }
+
+        progressListeners.add(listener);
+    }
+
+    /**
+     * Adds the IIOWriteWarningListener.
+     * 
+     * @param listener the IIOWriteWarningListener listener.
+     */
+    public void addIIOWriteWarningListener(IIOWriteWarningListener listener) {
+        if (listener == null) {
+            return;
+        }
+
+        if (warningListeners == null) {
+            warningListeners = new ArrayList<IIOWriteWarningListener>();
+            warningLocales = new ArrayList<Locale>();
+        }
+
+        warningListeners.add(listener);
+        warningLocales.add(getLocale());
+    }
+
+    /**
+     * Gets the output object that was set by setOutput method.
+     * 
+     * @return the output object such as ImageOutputStream, or null if
+     * it is not set.
+     */
+    public Object getOutput() {
+        return output;
+    }
+
+    /**
+     * Check output return false.
+     * 
+     * @return true, if successful
+     */
+    private final boolean checkOutputReturnFalse() {
+        if (getOutput() == null) {
+            throw new IllegalStateException("getOutput() == null!");
+        }
+        return false;
+    }
+
+    /**
+     * Unsupported operation.
+     */
+    private final void unsupportedOperation() {
+        if (getOutput() == null) {
+            throw new IllegalStateException("getOutput() == null!");
+        }
+        throw new UnsupportedOperationException("Unsupported write variant!");
+    }
+
+
+    /**
+     * Returns true if a new empty image can be inserted at 
+     * the specified index. 
+     * 
+     * @param imageIndex the specified index of image.
+     * 
+     * @return true if a new empty image can be inserted at 
+     * the specified index, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canInsertEmpty(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if a new image can be inserted at the specified index. 
+     * 
+     * @param imageIndex the specified index of image.
+     * 
+     * @return true if a new image can be inserted at the specified index, 
+     * false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canInsertImage(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returnes true if the image with the specified index can be removed.
+     * 
+     * @param imageIndex the specified index of image.
+     * 
+     * @return true if the image with the specified index can be removed,
+     * false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canRemoveImage(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if metadata of the image with the specified index
+     * can be replaced.
+     * 
+     * @param imageIndex the specified image index.
+     * 
+     * @return true if metadata of the image with the specified index
+     * can be replaced, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canReplaceImageMetadata(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if pixels of the image with the specified index 
+     * can be replaced by the replacePixels  methods.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return true if pixels of the image with the specified index 
+     * can be replaced by the replacePixels  methods, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canReplacePixels(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if the stream metadata presented in the output
+     * can be removed.
+     * 
+     * @return true if the stream metadata presented in the output
+     * can be removed, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canReplaceStreamMetadata() throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if the writing of a complete image stream which
+     * contains a single image is supported with undefined pixel 
+     * values and associated metadata and thumbnails to the output. 
+     * 
+     * @return true if the writing of a complete image stream which
+     * contains a single image is supported, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canWriteEmpty() throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if the methods which taken an IIOImageParameter 
+     * can deal with a Raster source image.
+     * 
+     * @return true if the methods which taken an IIOImageParameter 
+     * can deal with a Raster source image, false otherwise.
+     */
+    public boolean canWriteRasters() {
+        return false;
+    }
+
+    /**
+     * Returns true if the writer can add an image to stream that
+     * already contains header information.
+     * 
+     * @return if the writer can add an image to stream that
+     * already contains header information, false otherwise.
+     */
+    public boolean canWriteSequence() {
+        return false;
+    }
+
+    /**
+     * Ends the insertion of a new image.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void endInsertEmpty() throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Ends the repalce pixels operation.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void endReplacePixels() throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Ends an empty write operation.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void endWriteEmpty() throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Ends the sequence of write operations.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void endWriteSequence() throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Gets an array of available locales.
+     * 
+     * @return an of array available locales.
+     */
+    public Locale[] getAvailableLocales() {
+        if (availableLocales == null) {
+            return null;
+        }
+
+        return availableLocales.clone();
+    }
+
+    /**
+     * Gets an IIOMetadata object that contains default values 
+     * for encoding an image with the specified type. 
+     * 
+     * @param imageType the ImageTypeSpecifier.
+     * @param param the ImageWriteParam.
+     * 
+     * @return the IIOMetadata object.
+     */
+    public abstract IIOMetadata getDefaultImageMetadata(
+            ImageTypeSpecifier imageType,
+            ImageWriteParam param
+    );
+
+    /**
+     * Gets an IIOMetadata object that contains default values 
+     * for encoding a stream of images.
+     * 
+     * @param param the ImageWriteParam.
+     * 
+     * @return the IIOMetadata object.
+     */
+    public abstract IIOMetadata getDefaultStreamMetadata(ImageWriteParam param);
+
+    /**
+     * Gets the current locale of this ImageWriter.
+     * 
+     * @return the current locale of this ImageWriter.
+     */
+    public Locale getLocale() {
+        return locale;
+    }
+
+    /**
+     * Gets the default write param.
+     * Gets a new ImageWriteParam object for this ImageWriter with the
+     * current Locale.
+     * 
+     * @return a new ImageWriteParam object for this ImageWriter.
+     */
+    public ImageWriteParam getDefaultWriteParam() {
+        return new ImageWriteParam(getLocale());
+    }
+
+    /**
+     * Gets the number of thumbnails suported by the format 
+     * being written with supported image type, image write 
+     * parameters, stream, and image metadata objects.
+     * 
+     * @param imageType the ImageTypeSpecifier.
+     * @param param the image's parameters.
+     * @param streamMetadata the stream metadata.
+     * @param imageMetadata the image metadata.
+     * 
+     * @return the number of thumbnails supported
+     */
+    public int getNumThumbnailsSupported(
+            ImageTypeSpecifier imageType,
+            ImageWriteParam param,
+            IIOMetadata streamMetadata,
+            IIOMetadata imageMetadata
+    ) {
+        return 0;
+    }
+
+    /**
+     * Gets the preferred thumbnail sizes.
+     * Gets an array of Dimensions with the sizes for thumbnail images 
+     * as they are encoded in the output file or stream. 
+     * 
+     * @param imageType the ImageTypeSpecifier.
+     * @param param the ImageWriteParam.
+     * @param streamMetadata the stream metadata.
+     * @param imageMetadata the image metadata.
+     * 
+     * @return the preferred thumbnail sizes
+     */
+    public Dimension[] getPreferredThumbnailSizes(
+            ImageTypeSpecifier imageType,
+            ImageWriteParam param,
+            IIOMetadata streamMetadata,
+            IIOMetadata imageMetadata
+    ) {
+        return null;
+    }
+
+    /**
+     * Prepares insertion of an empty image by requesting the insertion of 
+     * a new image into an existing image stream.
+     * 
+     * @param imageIndex the image index.
+     * @param imageType the image type.
+     * @param width the width of the image.
+     * @param height the height of the image.
+     * @param imageMetadata the image metadata, or null.
+     * @param thumbnails the array thumbnails for this image, or null.
+     * @param param the ImageWriteParam, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void prepareInsertEmpty(
+            int imageIndex, ImageTypeSpecifier imageType,
+            int width, int height,
+            IIOMetadata imageMetadata, List<? extends BufferedImage> thumbnails,
+            ImageWriteParam param
+    ) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Prepares the writer to call the replacePixels method for the
+     * specified region. 
+     * 
+     * @param imageIndex the image's index.
+     * @param region the specified region.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void prepareReplacePixels(int imageIndex, Rectangle region) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Prepares the writer for writing an empty image by beginning the 
+     * process of writing a complete image stream that contains a single image 
+     * with undefined pixel values, metadata and thumbnails, 
+     * to the output. 
+     * 
+     * @param streamMetadata the stream metadata.
+     * @param imageType the image type.
+     * @param width the width of the image.
+     * @param height the height of the image.
+     * @param imageMetadata the image's metadata, or null.
+     * @param thumbnails the image's thumbnails, or null.
+     * @param param the image's parameters, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void prepareWriteEmpty(
+            IIOMetadata streamMetadata, ImageTypeSpecifier imageType,
+            int width, int height,
+            IIOMetadata imageMetadata, List<? extends BufferedImage> thumbnails,
+            ImageWriteParam param
+    ) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Prepares a stream to accept calls of writeToSequence method 
+     * using the metadata object. 
+     * 
+     * @param streamMetadata the stream metadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void prepareWriteSequence(IIOMetadata streamMetadata) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Processes the completion of a thumbnail read 
+     * by calling their thumbnailComplete method 
+     * of registered IIOWriteProgressListeners. 
+     */
+    protected void processThumbnailComplete() {
+        if (progressListeners != null) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.thumbnailComplete(this);
+            }
+        }
+    }
+
+    /**
+     * Processes the current percentage of thumbnail completion 
+     * by calling their thumbnailProgress method of registered 
+     * IIOWriteProgressListeners.
+     * 
+     * @param percentageDone the percentage done.
+     */
+    protected void processThumbnailProgress(float percentageDone) {
+        if (progressListeners != null) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.thumbnailProgress(this, percentageDone);
+            }
+        }
+    }
+
+    /**
+     * Processes the start of a thumbnail read by calling 
+     * thumbnailStarted method of registered IIOWriteProgressListeners. 
+     * 
+     * @param imageIndex the image index.
+     * @param thumbnailIndex the thumbnail index.
+     */
+    protected void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
+        if (progressListeners != null) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
+            }
+        }
+    }
+
+    /**
+     * Processes that the writing has been aborted by calling writeAborted 
+     * method of registered IIOWriteProgressListeners.
+     */
+    protected void processWriteAborted() {
+        if (progressListeners != null) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.writeAborted(this);
+            }
+        }
+    }
+
+    /**
+     * Removes the all IIOWriteProgressListener listeners.
+     */
+    public void removeAllIIOWriteProgressListeners() {
+        progressListeners = null;
+    }
+
+    /**
+     * Removes the all IIOWriteWarningListener listeners.
+     */
+    public void removeAllIIOWriteWarningListeners() {
+        warningListeners = null;
+        warningLocales = null;
+    }
+
+    /**
+     * Removes the specified IIOWriteProgressListener listener.
+     * 
+     * @param listener the registered IIOWriteProgressListener 
+     * to be removed.
+     */
+    public void removeIIOWriteProgressListener(IIOWriteProgressListener listener) {
+        if (progressListeners != null && listener != null) {
+            if (progressListeners.remove(listener) && progressListeners.isEmpty()) {
+                progressListeners = null;
+            }
+        }
+    }
+
+    /**
+     * Removes the specified IIOWriteWarningListener listener.
+     * 
+     * @param listener the registered IIOWriteWarningListener listener
+     * to be removed.
+     */
+    public void removeIIOWriteWarningListener(IIOWriteWarningListener listener) {
+        if (warningListeners == null || listener == null) {
+            return;
+        }
+
+        int idx = warningListeners.indexOf(listener);
+        if (idx > -1) {
+            warningListeners.remove(idx);
+            warningLocales.remove(idx);
+
+            if (warningListeners.isEmpty()) {
+                warningListeners = null;
+                warningLocales = null;
+            }
+        }
+    }
+
+    /**
+     * Removes the image with the specified index from the stream.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void removeImage(int imageIndex) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Replaces image metadata of the image with specified index.
+     * 
+     * @param imageIndex the image's index.
+     * @param imageMetadata the image metadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void replaceImageMetadata(int imageIndex, IIOMetadata imageMetadata) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Replaces a part of an image presented in the output
+     * with the specified RenderedImage.
+     * 
+     * @param image the RenderedImage.
+     * @param param the ImageWriteParam.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void replacePixels(RenderedImage image, ImageWriteParam param) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Replaces a part of an image presented in the output
+     * with the specified Raster.
+     * 
+     * @param raster the Raster.
+     * @param param the ImageWriteParam.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void replacePixels(Raster raster, ImageWriteParam param) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Replaces the stream metadata of the output with new IIOMetadata.
+     * 
+     * @param streamMetadata the new stream metadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void replaceStreamMetadata(IIOMetadata streamMetadata) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Sets the locale of this ImageWriter.
+     * 
+     * @param locale the new locale.
+     */
+    public void setLocale(Locale locale) {
+        if (locale == null) {
+            this.locale = null;
+            return;
+        }
+
+        Locale[] locales = getAvailableLocales();
+        boolean validLocale = false;
+        if (locales != null) {
+            for (int i = 0; i < locales.length; i++) {
+                if (locale.equals(locales[i])) {
+                    validLocale = true;
+                    break;
+                }
+            }
+        }
+
+        if (validLocale) {
+            this.locale = locale;
+        } else {
+            throw new IllegalArgumentException("Invalid locale!");
+        }
+    }
+
+    /**
+     * Resets this ImageWriter.
+     */
+    public void reset() {
+        setOutput(null);
+        setLocale(null);
+        removeAllIIOWriteWarningListeners();
+        removeAllIIOWriteProgressListeners();
+        clearAbortRequest();
+    }
+
+    /**
+     * Inserts image into existing output stream. 
+     * 
+     * @param imageIndex the image index where an image will be written.
+     * @param image the specified image to be written.
+     * @param param the ImageWriteParam, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void writeInsert(int imageIndex, IIOImage image, ImageWriteParam param) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Writes the specified image to the sequence.
+     * 
+     * @param image the image to be written.
+     * @param param the ImageWriteParam, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred 
+     * during writting.
+     */
+    public void writeToSequence(IIOImage image, ImageWriteParam param) throws IOException {
+        unsupportedOperation();
+    }
+}
diff --git a/awt/javax/imageio/event/IIOReadProgressListener.java b/awt/javax/imageio/event/IIOReadProgressListener.java
new file mode 100644
index 0000000..3d65807
--- /dev/null
+++ b/awt/javax/imageio/event/IIOReadProgressListener.java
@@ -0,0 +1,103 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.event;
+
+import java.util.EventListener;
+import javax.imageio.ImageReader;
+
+/**
+ * The IIOReadProgressListener interface notifies callers 
+ * about the progress of the image and thumbnail reading methods.
+ */
+public interface IIOReadProgressListener extends EventListener {
+
+    /**
+     * Notifies this listener that the image reading has been completed. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     */
+    void imageComplete(ImageReader source);
+    
+    /**
+     * Notifies this listener about the degree of completion of the read call.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param percentageDone the percentage of decoding done.
+     */
+    void imageProgress(ImageReader source, float percentageDone);
+    
+    /**
+     * Notifies this listener that an image read operation has been started. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param imageIndex the index of the image in an input file or 
+     * stream to be read.
+     */
+    void imageStarted(ImageReader source, int imageIndex);
+    
+    /**
+     * Notifies this listener that a read operation has been aborted.
+     * 
+     * @param source the ImageReader object which calls this method.
+     */
+    void readAborted(ImageReader source);
+    
+    /**
+     * Notifies this listener that a sequence of read operations has been completed. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     */
+    void sequenceComplete(ImageReader source);
+    
+    /**
+     * Notifies this listener that a sequence of read operation has been started. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param minIndex the index of the first image to be read.
+     */
+    void sequenceStarted(ImageReader source, int minIndex);
+    
+    /**
+     * Notifies that a thumbnail read operation has been completed.
+     * 
+     * @param source the ImageReader object which calls this method.
+     */
+    void thumbnailComplete(ImageReader source);
+    
+    /**
+     * Notifies this listener about the degree of completion of the read call.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param percentageDone the percentage of decoding done.
+     */
+    void thumbnailProgress(ImageReader source, float percentageDone);
+    
+    /**
+     * Notifies this listener that a thumbnail reading operation has been started. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param imageIndex the index of the image in an input file or 
+     * stream to be read.
+     * @param thumbnailIndex the index of the thumbnail to be read.
+     */
+    void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex);
+}
+
diff --git a/awt/javax/imageio/event/IIOReadUpdateListener.java b/awt/javax/imageio/event/IIOReadUpdateListener.java
new file mode 100644
index 0000000..ce5e2f1
--- /dev/null
+++ b/awt/javax/imageio/event/IIOReadUpdateListener.java
@@ -0,0 +1,138 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.event;
+
+import java.awt.image.BufferedImage;
+import java.util.EventListener;
+import javax.imageio.ImageReader;
+
+/*
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The IIOReadUpdateListener interface provides functionality 
+ * to receive notification of pixel updates during image and thumbnail 
+ * reading operations.
+ */
+public interface IIOReadUpdateListener extends EventListener {
+
+    /**
+     * Notifies this listener that the specified area of the image has been updated. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theImage the image to be updated.
+     * @param minX the minimum X coordinate of the pixels in the updated area.
+     * @param minY the minimum Y coordinate of the pixels in the updated area.
+     * @param width the width of updated area.
+     * @param height the height of updated area.
+     * @param periodX the horizontal spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels. 
+     * @param periodY the vertical spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels.
+     * @param bands the array of int values indicating the bands being updated.
+     */
+    void imageUpdate(ImageReader source, BufferedImage theImage, int minX,
+            int minY, int width, int height, int periodX, int periodY,
+            int[] bands);
+    
+    /**
+     * Notifies this listener that the current read operation has completed a 
+     * progressive pass.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theImage the image to be updated.
+     */
+    void passComplete(ImageReader source, BufferedImage theImage);
+    
+    /**
+     * Notifies this listener that the current read operation has begun 
+     * a progressive pass.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theImage the image to be updated.
+     * @param pass the numer of the pass.
+     * @param minPass the index of the first pass that will be decoded.
+     * @param maxPass the index of the last pass that will be decoded.
+     * @param minX the minimum X coordinate of the pixels in the updated area.
+     * @param minY the minimum Y coordinate of the pixels in the updated area.
+     * @param periodX the horizontal spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels. 
+      * @param periodY the vertical spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels.
+     * @param bands the array of int values indicating the bands being updated.
+     */
+    void passStarted(ImageReader source, BufferedImage theImage, int pass,
+            int minPass, int maxPass, int minX, int minY, int periodX,
+            int periodY, int[] bands);
+
+    /**
+     * Notifies this listener that the current thumbnail read operation has  
+     * completed a progressive pass.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theImage the thumbnail to be updated.
+     */
+    void thumbnailPassComplete(ImageReader source, BufferedImage theImage);
+    
+    /**
+     * Notifies this listener that the current thumbnail read operation has  
+     * begun a progressive pass.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theThumbnail the thumbnail to be updated.
+     * @param pass the numer of the pass.
+     * @param minPass the index of the first pass that will be decoded.
+     * @param maxPass the index of the last pass that will be decoded.
+     * @param minX the minimum X coordinate of the pixels in the updated area.
+     * @param minY the minimum Y coordinate of the pixels in the updated area.
+     * @param periodX the horizontal spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels. 
+     * @param periodY the vertical spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels.
+     * @param bands the array of int values indicating the bands being updated.
+     */
+    void thumbnailPassStarted(ImageReader source, BufferedImage theThumbnail,
+            int pass, int minPass, int maxPass, int minX, int minY,
+            int periodX, int periodY, int[] bands);
+    
+    /**
+     * Notifies this listener that a specified area of a thumbnail image has been 
+     * updated.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theThumbnail the thumbnail to be updated.
+     * @param minX the minimum X coordinate of the pixels in the updated area.
+     * @param minY the minimum Y coordinate of the pixels in the updated area.
+     * @param width the width of updated area.
+     * @param height the height of updated area.
+     * @param periodX the horizontal spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels. 
+     * @param periodY the vertical spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels.
+     * @param bands the array of int values indicating the bands being updated.
+     */
+    void thumbnailUpdate(ImageReader source, BufferedImage theThumbnail,
+            int minX, int minY, int width, int height, int periodX,
+            int periodY, int[] bands);
+}
+
diff --git a/awt/javax/imageio/event/IIOReadWarningListener.java b/awt/javax/imageio/event/IIOReadWarningListener.java
new file mode 100644
index 0000000..92fa275
--- /dev/null
+++ b/awt/javax/imageio/event/IIOReadWarningListener.java
@@ -0,0 +1,46 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.event;
+
+import java.util.EventListener;
+import javax.imageio.ImageReader;
+
+/* 
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The IIOReadWarningListener provides methods to receive notification
+ * of warning messages generated by image 
+ * and thumbnail reading methods.
+ */
+public interface IIOReadWarningListener extends EventListener {
+
+    /**
+     * Notifies this listener about a warning (non-fatal error) during decoding. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param warning the string describing the warning.
+     */
+    public void warningOccurred(ImageReader source, String warning);
+}
+
diff --git a/awt/javax/imageio/event/IIOWriteProgressListener.java b/awt/javax/imageio/event/IIOWriteProgressListener.java
new file mode 100644
index 0000000..19ae495
--- /dev/null
+++ b/awt/javax/imageio/event/IIOWriteProgressListener.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.event;
+
+import javax.imageio.ImageWriter;
+import java.util.EventListener;
+
+/**
+ * The IIOWriteProgressListener interface provides methods to 
+ * receive notification about the progress of the image and 
+ * thumbnail writing methods.
+ */
+public interface IIOWriteProgressListener extends EventListener {
+    
+    /**
+     * Notifies this listener that an image write operation has been started. 
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param imageIndex the index of the image being written.
+     */
+    void imageStarted(ImageWriter source, int imageIndex);
+    
+    /**
+     * Notifies this listener about the degree of completion of the write call.
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param percentageDone the percentage of encoding done.
+     */
+    void imageProgress(ImageWriter source, float percentageDone);
+    
+    /**
+     * Notifies this listener that the image writing has been completed. 
+     * 
+     * @param source the ImageWriter object which calls this method.
+     */
+    void imageComplete(ImageWriter source);
+    
+    /**
+     * Notifies this listener that a thumbnail write operation has been started. 
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param imageIndex the index of the image being written.
+     * @param thumbnailIndex the index of the thumbnail being written.
+     */
+    void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex);
+    
+    /**
+     * Notifies this listener about the degree of completion of the write call.
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param percentageDone the percentage of encoding done.
+     */
+    void thumbnailProgress(ImageWriter source, float percentageDone);
+    
+    /**
+     * Notifies this listener that a thumbnail write operation has been completed.
+     * 
+     * @param source the ImageWriter object which calls this method.
+     */
+    void thumbnailComplete(ImageWriter source);
+    
+    /**
+     * Notifies this listener that writing operation has been aborted.
+     * 
+     * @param source the ImageWriter object which calls this method.
+     */
+    void writeAborted(ImageWriter source);
+}
diff --git a/awt/javax/imageio/event/IIOWriteWarningListener.java b/awt/javax/imageio/event/IIOWriteWarningListener.java
new file mode 100644
index 0000000..f530d25
--- /dev/null
+++ b/awt/javax/imageio/event/IIOWriteWarningListener.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.event;
+
+import javax.imageio.ImageWriter;
+import java.util.EventListener;
+
+/**
+ * The IIOWriteWarningListener provides methods to receive notification
+ * of warnings generated by image and thumbnail writing methods.
+ */
+public interface IIOWriteWarningListener extends EventListener {
+    
+    /**
+     * Notifies this listener about a warning (non-fatal error) during encoding. 
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param imageIndex the index of the image generating the warning.
+     * @param warning the string describing the warning.
+     */
+    void warningOccurred(ImageWriter source, int imageIndex, String warning);
+}
diff --git a/awt/javax/imageio/metadata/IIOInvalidTreeException.java b/awt/javax/imageio/metadata/IIOInvalidTreeException.java
new file mode 100644
index 0000000..8690b2b
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOInvalidTreeException.java
@@ -0,0 +1,67 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package javax.imageio.metadata;
+
+import org.w3c.dom.Node;
+import javax.imageio.IIOException;
+
+/**
+ * The IIOInvalidTreeException provides notification about
+ * fails of IIOMetadataNodes tree parsing by IIOMetadata object. 
+ */
+public class IIOInvalidTreeException extends IIOException {
+    
+    /** The offending node. */
+    protected Node offendingNode = null;
+
+    /**
+     * Instantiates an IIOInvalidTreeException with the
+     * specified detailed message and specified offending
+     * Node.
+     * 
+     * @param message the detailed message.
+     * @param offendingNode the offending node.
+     */
+    public IIOInvalidTreeException(String message, Node offendingNode) {
+        super(message);
+        this.offendingNode = offendingNode;
+    }
+
+    /**
+     * Instantiates a new IIOInvalidTreeException with the
+     * specified detailed message and specified offending
+     * Node.
+     * 
+     * @param message the detailed message.
+     * @param cause the cause of this exception.
+     * @param offendingNode the offending node
+     */
+    public IIOInvalidTreeException(String message, Throwable cause, Node offendingNode) {
+        super(message, cause);
+        this.offendingNode = offendingNode;
+    }
+
+    /**
+     * Gets the offending node.
+     * 
+     * @return the offending node.
+     */
+    public Node getOffendingNode() {
+        return offendingNode;
+    }
+}
diff --git a/awt/javax/imageio/metadata/IIOMetadata.java b/awt/javax/imageio/metadata/IIOMetadata.java
new file mode 100644
index 0000000..f2387cc
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadata.java
@@ -0,0 +1,371 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package javax.imageio.metadata;
+
+import java.util.ArrayList;
+
+import org.apache.harmony.x.imageio.metadata.IIOMetadataUtils;
+import org.w3c.dom.Node;
+
+/**
+ * The Class IIOMetadata represents the metadata (bundled with an image)
+ * as a Dom-type tree.
+ */
+public abstract class IIOMetadata {
+
+    /** Whether the standard metadata format is supported. */
+    protected boolean standardFormatSupported;
+    
+    /** The native metadata format name. */
+    protected String nativeMetadataFormatName;
+    
+    /** The native metadata format class name. */
+    protected String nativeMetadataFormatClassName;
+    
+    /** The extra metadata format names. */
+    protected String[] extraMetadataFormatNames;
+    
+    /** The extra metadata format class names. */
+    protected String[] extraMetadataFormatClassNames;
+    
+    /** The default controller. */
+    protected IIOMetadataController defaultController;
+    
+    /** The controller. */
+    protected IIOMetadataController controller;
+
+    /**
+     * Instantiates a new IIOMetadata with no data set.
+     */
+    protected IIOMetadata() {}
+
+    /**
+     * Instantiates a new IIOMetadata with the specified data parameters.
+     * 
+     * @param standardMetadataFormatSupported whether the standard metadata format is supported
+     * @param nativeMetadataFormatName the native metadata format name
+     * @param nativeMetadataFormatClassName the native metadata format class name
+     * @param extraMetadataFormatNames the extra metadata format names
+     * @param extraMetadataFormatClassNames the extra metadata format class names
+     */
+    protected IIOMetadata(boolean standardMetadataFormatSupported,
+                          String nativeMetadataFormatName,
+                          String nativeMetadataFormatClassName,
+                          String[] extraMetadataFormatNames,
+                          String[] extraMetadataFormatClassNames) {
+        standardFormatSupported = standardMetadataFormatSupported;
+        this.nativeMetadataFormatName = nativeMetadataFormatName;
+        this.nativeMetadataFormatClassName = nativeMetadataFormatClassName;
+        if (extraMetadataFormatNames == null) {
+            if (extraMetadataFormatClassNames != null) {
+                throw new IllegalArgumentException(
+                        "extraMetadataFormatNames == null && extraMetadataFormatClassNames != null!"
+                );
+            }
+        } else {
+            if (extraMetadataFormatClassNames == null) {
+                throw new IllegalArgumentException(
+                        "extraMetadataFormatNames != null && extraMetadataFormatClassNames == null!"
+                );
+            }
+            if (extraMetadataFormatNames.length == 0) {
+                throw new IllegalArgumentException("extraMetadataFormatNames.length == 0!");
+            }
+            if (extraMetadataFormatClassNames.length != extraMetadataFormatNames.length) {
+                throw new IllegalArgumentException(
+                        "extraMetadataFormatClassNames.length != extraMetadataFormatNames.length!"
+                );
+            }
+            this.extraMetadataFormatNames = extraMetadataFormatNames.clone();
+            this.extraMetadataFormatClassNames = extraMetadataFormatClassNames.clone();
+        }
+    }
+
+    /**
+     * Gets the metadata as tree-type document.
+     * 
+     * @param formatName the format name
+     * 
+     * @return the node in tree format
+     */
+    public abstract Node getAsTree(String formatName);
+    
+    /**
+     * Checks if the metadata is read only.
+     * 
+     * @return true, if the metadata is read only.
+     */
+    public abstract boolean isReadOnly();
+    
+    /**
+     * Merges the specified tree with this metadata tree.
+     * 
+     * @param formatName the format of the specified tree
+     * @param root the root node of the metadata tree
+     * 
+     * @throws IIOInvalidTreeException if the specified tree
+     * is incompatible with the this metadata tree.
+     */
+    public abstract void mergeTree(String formatName, Node root) throws IIOInvalidTreeException;
+    
+    /**
+     * Resets the controller.
+     */
+    public abstract void reset();
+
+    /**
+     * Gets the controller associated with this metadata document.
+     * 
+     * @return the controller
+     */
+    public IIOMetadataController getController() {
+        return controller;
+    }
+
+    /**
+     * Checks whether this metadata has a controller.
+     * 
+     * @return true, if this metadata has a controller
+     */
+    public boolean hasController() {
+        return getController() != null;
+    }
+
+    /**
+     * Activate the controller.
+     * 
+     * @return true, if successful
+     */
+    public boolean activateController() {
+        if (!hasController()) {
+            throw new IllegalStateException("hasController() == false!");
+        }
+        return getController().activate(this);
+    }
+
+    /**
+     * Gets the default controller.
+     * 
+     * @return the default controller
+     */
+    public IIOMetadataController getDefaultController() {
+        return defaultController;
+    }
+
+    /**
+     * Gets the extra metadata format names.
+     * 
+     * @return the extra metadata format names
+     */
+    public String[] getExtraMetadataFormatNames() {
+        return extraMetadataFormatNames == null ? null : extraMetadataFormatNames.clone();
+    }
+
+    /**
+     * Gets the metadata format.
+     * 
+     * @param formatName the format name
+     * 
+     * @return the metadata format
+     */
+    public IIOMetadataFormat getMetadataFormat(String formatName) {
+        return IIOMetadataUtils.instantiateMetadataFormat(
+                formatName,
+                standardFormatSupported,
+                nativeMetadataFormatName, nativeMetadataFormatClassName,
+                extraMetadataFormatNames, extraMetadataFormatClassNames
+        );
+    }
+
+    /**
+     * Gets the native metadata format name.
+     * 
+     * @return the native metadata format name
+     */
+    public String getNativeMetadataFormatName() {
+        return nativeMetadataFormatName;
+    }
+
+    /**
+     * Checks if the standard metadata format is supported.
+     * 
+     * @return true, if the standard metadata format is supported
+     */
+    public boolean isStandardMetadataFormatSupported() {
+        return standardFormatSupported;
+    }
+
+    /**
+     * Gets the metadata format names.
+     * 
+     * @return the metadata format names
+     */
+    public String[] getMetadataFormatNames() {
+        ArrayList<String> res = new ArrayList<String>();
+
+        String nativeMetadataFormatName = getNativeMetadataFormatName();
+        boolean standardFormatSupported = isStandardMetadataFormatSupported();
+        String extraMetadataFormatNames[] = getExtraMetadataFormatNames();
+
+        if (standardFormatSupported) {
+            res.add(IIOMetadataFormatImpl.standardMetadataFormatName);
+        }
+        if (nativeMetadataFormatName != null) {
+            res.add(nativeMetadataFormatName);
+        }
+        if (extraMetadataFormatNames != null) {
+            for (String extraMetadataFormatName : extraMetadataFormatNames) {
+                res.add(extraMetadataFormatName);
+            }
+        }
+
+        return res.size() > 0 ? res.toArray(new String[0]) : null;
+    }
+
+    /**
+     * Gets the standard chroma node.
+     * 
+     * @return the standard chroma node
+     */
+    protected IIOMetadataNode getStandardChromaNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard compression node.
+     * 
+     * @return the standard compression node
+     */
+    protected IIOMetadataNode getStandardCompressionNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard data node.
+     * 
+     * @return the standard data node
+     */
+    protected IIOMetadataNode getStandardDataNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard dimension node.
+     * 
+     * @return the standard dimension node
+     */
+    protected IIOMetadataNode getStandardDimensionNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard document node.
+     * 
+     * @return the standard document node
+     */
+    protected IIOMetadataNode getStandardDocumentNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard text node.
+     * 
+     * @return the standard text node
+     */
+    protected IIOMetadataNode getStandardTextNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard tile node.
+     * 
+     * @return the standard tile node
+     */
+    protected IIOMetadataNode getStandardTileNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard transparency node.
+     * 
+     * @return the standard transparency node
+     */
+    protected IIOMetadataNode getStandardTransparencyNode() {
+        return null;
+    }
+
+    /**
+     * Gets the metadata as a tree in standard format.
+     * 
+     * @return the metadata as a tree in standard format
+     */
+    protected final IIOMetadataNode getStandardTree() {
+        // Create root node
+        IIOMetadataNode root = new IIOMetadataNode(IIOMetadataFormatImpl.standardMetadataFormatName);
+
+        Node node;
+        if ((node = getStandardChromaNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardCompressionNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardDataNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardDimensionNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardDocumentNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardTextNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardTileNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardTransparencyNode()) != null) {
+            root.appendChild(node);
+        }
+        
+        return root;
+    }
+
+    /**
+     * Sets the controller.
+     * 
+     * @param controller the new controller
+     */
+    public void setController(IIOMetadataController controller) {
+        this.controller = controller;
+    }
+
+    /**
+     * Sets the from tree.
+     * 
+     * @param formatName the name of the metatdata format of the from tree
+     * @param root the root node of the from tree
+     * 
+     * @throws IIOInvalidTreeException if the tree or its format is not compatible with 
+     * this metadata.
+     */
+    public void setFromTree(String formatName, Node root) throws IIOInvalidTreeException {
+        reset();
+        mergeTree(formatName, root);
+    }
+}
diff --git a/awt/javax/imageio/metadata/IIOMetadataController.java b/awt/javax/imageio/metadata/IIOMetadataController.java
new file mode 100644
index 0000000..dfd4e5c
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadataController.java
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.metadata;
+
+/* 
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The IIOMetadataController interface provides a method for 
+ * implementing objects to activate the controller without 
+ * defining how the controller obtains values.
+ */
+public interface IIOMetadataController {
+
+    /**
+     * Activates a controller.
+     * 
+     * @param metadata the metadata to be modified.
+     * 
+     * @return true if the IIOMetadata has been modified, 
+     * false otherwise.
+     */
+    public boolean activate(IIOMetadata metadata);
+}
+
diff --git a/awt/javax/imageio/metadata/IIOMetadataFormat.java b/awt/javax/imageio/metadata/IIOMetadataFormat.java
new file mode 100644
index 0000000..9e246b4
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadataFormat.java
@@ -0,0 +1,347 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package javax.imageio.metadata;
+
+import javax.imageio.ImageTypeSpecifier;
+import java.util.Locale;
+
+/**
+ * The Interface IIOMetadataFormat is implemented by classes that 
+ * describe the rules and allowed elements for a metadata document
+ * tree.
+ */
+public interface IIOMetadataFormat {
+
+    /** The CHILD_POLICY_EMPTY. */
+    int CHILD_POLICY_EMPTY = 0;
+    
+    /** The CHILD_POLICY_ALL. */
+    int CHILD_POLICY_ALL = 1;
+    
+    /** The CHILD_POLICY_SOME. */
+    int CHILD_POLICY_SOME = 2;
+    
+    /** The CHILD_POLICY_CHOICE. */
+    int CHILD_POLICY_CHOICE = 3;
+    
+    /** The CHILD_POLICY_SEQUENCE. */
+    int CHILD_POLICY_SEQUENCE = 4;
+    
+    /** The CHILD_POLICY_REPEAT. */
+    int CHILD_POLICY_REPEAT = 5;
+    
+    /** The maximum value for the child policy. */
+    int CHILD_POLICY_MAX = CHILD_POLICY_REPEAT;
+
+    /** The DATATYPE_STRING. */
+    int DATATYPE_STRING = 0;
+    
+    /** The DATATYPE_BOOLEAN. */
+    int DATATYPE_BOOLEAN = 1;
+    
+    /** The DATATYPE_INTEGER. */
+    int DATATYPE_INTEGER = 2;
+    
+    /** The DATATYPE_FLOAT. */
+    int DATATYPE_FLOAT = 3;
+    
+    /** The DATATYPE_DOUBLE. */
+    int DATATYPE_DOUBLE = 4;
+
+    /** The VALUE_NONE. */
+    int VALUE_NONE = 0;
+    
+    /** The VALUE_ARBITRARY. */
+    int VALUE_ARBITRARY = 1;
+    
+    /** The VALUE_RANGE. */
+    int VALUE_RANGE = 2;
+    
+    /** The VALUE_RANGE_MIN_INCLUSIVE_MASK. */
+    int VALUE_RANGE_MIN_INCLUSIVE_MASK = 4;
+    
+    /** The VALUE_RANGE_MAX_INCLUSIVE_MASK. */
+    int VALUE_RANGE_MAX_INCLUSIVE_MASK = 8;
+    
+    /** The VALUE_ENUMERATION. */
+    int VALUE_ENUMERATION = 16;
+    
+    /** The VALUE_LIST. */
+    int VALUE_LIST = 32;
+    
+    /** The VALUE_RANGE_MIN_INCLUSIVE. */
+    int VALUE_RANGE_MIN_INCLUSIVE = VALUE_RANGE | VALUE_RANGE_MIN_INCLUSIVE_MASK;
+    
+    /** The VALUE_RANGE_MAX_INCLUSIVE. */
+    int VALUE_RANGE_MAX_INCLUSIVE = VALUE_RANGE | VALUE_RANGE_MAX_INCLUSIVE_MASK;
+    
+    /** The VALUE_RANGE_MIN_MAX_INCLUSIVE. */
+    int VALUE_RANGE_MIN_MAX_INCLUSIVE =
+            VALUE_RANGE | VALUE_RANGE_MIN_INCLUSIVE_MASK | VALUE_RANGE_MAX_INCLUSIVE_MASK;
+
+    /**
+     * Tells whether the specified element is allowed for the specified 
+     * image type.
+     * 
+     * @param elementName the element name
+     * @param imageType the image type
+     * 
+     * @return true, if the specified element is allowed for the specified 
+     * image type
+     */
+    boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType);
+
+    /**
+     * Gets data type of the specified attribute of the specified element.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the attribute's data type
+     */
+    int getAttributeDataType(String elementName, String attrName);
+    
+    /**
+     * Gets the default value of the specified attribute of the specified element.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the attribute's default value
+     */
+    String getAttributeDefaultValue(String elementName, String attrName);
+    
+    /**
+     * Gets the user-friendly description of the attribute.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * @param locale the locale giving the desired language for the
+     * description
+     * 
+     * @return the attribute description
+     */
+    String getAttributeDescription(String elementName, String attrName, Locale locale);
+    
+    /**
+     * Gets the attribute enumerations.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the attribute enumerations
+     */
+    String[] getAttributeEnumerations(String elementName, String attrName);
+    
+    /**
+     * Gets the maximum length of the attribute list.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the maximum length of the attribute list
+     */
+    int getAttributeListMaxLength(String elementName, String attrName);
+    
+    /**
+     * Gets the minimum length of the attribute list.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the minimum length of the attribute list
+     */
+    int getAttributeListMinLength(String elementName, String attrName);
+    
+    /**
+     * Gets the maximum value allowed for the attribute.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the maximum value allowed for the attribute
+     */
+    String getAttributeMaxValue(String elementName, String attrName);
+    
+    /**
+     * Gets the minimum value allowed for the attribute.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the minimum value allowed for the attribute
+     */
+    String getAttributeMinValue(String elementName, String attrName);
+    
+    /**
+     * Gets the attribute names allowed for the specified element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the attribute names
+     */
+    String[] getAttributeNames(String elementName);
+    
+    /**
+     * Gets the attribute value type.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the attribute value type
+     */
+    int getAttributeValueType(String elementName, String attrName);
+    
+    /**
+     * Checks whether the specified attribute is required 
+     * for the specified element.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return true, if the specified attribute is required for the 
+     * specified element
+     */
+    boolean isAttributeRequired(String elementName, String attrName);
+
+    /**
+     * Gets the names of the possible child elements for the given element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the child names
+     */
+    String[] getChildNames(String elementName);
+    
+    /**
+     * Gets the constant describing the element's child policy.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the child policy
+     */
+    int getChildPolicy(String elementName);
+
+    /**
+     * Gets the user-friendly description of the element.
+     * 
+     * @param elementName the element name
+     * @param locale the locale giving the desired language for the
+     * description
+     * 
+     * @return the element description
+     */
+    String getElementDescription(String elementName, Locale locale);
+    
+    /**
+     * Gets the maximum number of children allowed for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the maximum number of children allowed for the element
+     */
+    int getElementMaxChildren(String elementName);
+    
+    /**
+     * Gets the minimum number of children allowed for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the minimum number of children allowed for the element
+     */
+    int getElementMinChildren(String elementName);
+
+    /**
+     * Gets the maximum object array length allowed for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the maximum object array length allowed for the element
+     */
+    int getObjectArrayMaxLength(String elementName);
+    
+    /**
+     * Gets the minimum object array length allowed for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the minimum object array length allowed for the element
+     */
+    int getObjectArrayMinLength(String elementName);
+    
+    /**
+     * Gets the object class corresponding to the specified element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the object class corresponding to the specified element
+     */
+    Class<?> getObjectClass(String elementName);
+    
+    /**
+     * Gets the object default value for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the object default value for the element
+     */
+    Object getObjectDefaultValue(String elementName);
+    
+    /**
+     * Gets the object enumerations.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the object enumerations
+     */
+    Object[] getObjectEnumerations(String elementName);
+    
+    /**
+     * Gets the maximum value allowed for the element's object.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the maximum value allowed for the element's object
+     */
+    Comparable<?> getObjectMaxValue(String elementName);
+    
+    /**
+     * Gets the minimum value allowed for the element's object.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the minimum value allowed for the element's object
+     */
+    Comparable<?> getObjectMinValue(String elementName);
+    
+    /**
+     * Gets the constant that indicates the type of the element's value.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the constant that indicates the type of the element's value
+     */
+    int getObjectValueType(String elementName);
+
+    /**
+     * Gets the name of the root element.
+     * 
+     * @return the name of the root element
+     */
+    String getRootName();
+}
diff --git a/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java b/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java
new file mode 100644
index 0000000..438ae90
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java
@@ -0,0 +1,939 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package javax.imageio.metadata;
+
+import javax.imageio.ImageTypeSpecifier;
+import java.util.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * The IIOMetadataFormatImpl class provides an implementation of the 
+ * IIOMetadataFormat interface.
+ */
+public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat {
+    
+    /** The Constant standardMetadataFormatName. */
+    @SuppressWarnings({"ConstantDeclaredInAbstractClass"})
+    public static final String standardMetadataFormatName = "javax_imageio_1.0";
+
+    /** The standard format. */
+    @SuppressWarnings({"StaticNonFinalField"})
+    private static IIOMetadataFormatImpl standardFormat;
+
+    /** The root name. */
+    private String rootName;
+    
+    /** The element hash. */
+    private HashMap<String, Element> elementHash = new HashMap<String, Element>();
+
+    /** The resource base name. */
+    private String resourceBaseName = getClass().getName() + "Resources";
+
+    /**
+     * Instantiates an IIOMetadataFormatImpl with the specified root
+     * name and child policy (not CHILD_POLICY_REPEAT).
+     * 
+     * @param rootName the name of root element.
+     * @param childPolicy the child policy defined by one of the 
+     * CHILD_POLICY_* constants  (except CHILD_POLICY_REPEAT).
+     */
+    public IIOMetadataFormatImpl(String rootName, int childPolicy) {
+        if (rootName == null) {
+            throw new IllegalArgumentException("rootName is null");
+        }
+        if (
+                childPolicy < CHILD_POLICY_EMPTY ||
+                childPolicy > CHILD_POLICY_MAX ||
+                childPolicy == CHILD_POLICY_REPEAT
+        ) {
+            throw new IllegalArgumentException("childPolicy is not one of the predefined constants");
+        }
+
+        this.rootName = rootName;
+        Element root = new Element();
+        root.name = rootName;
+        root.childPolicy = childPolicy;
+        elementHash.put(rootName, root);
+    }
+
+    /**
+     * Instantiates an IIOMetadataFormatImpl with the specified root
+     * name and CHILD_POLICY_REPEAT child policy.
+     * 
+     * @param rootName the name of root element.
+     * @param minChildren the minimum number of children.
+     * @param maxChildren the maximum number of children
+     */
+    public IIOMetadataFormatImpl(String rootName, int minChildren, int maxChildren) {
+        if (rootName == null) {
+            throw new IllegalArgumentException("rootName is null");
+        }
+        if (minChildren < 0) {
+            throw new IllegalArgumentException("minChildren < 0!");
+        }
+        if (minChildren > maxChildren) {
+            throw new IllegalArgumentException("minChildren > maxChildren!");
+        }
+
+        this.rootName = rootName;
+        Element root = new Element();
+        root.name = rootName;
+        root.minChildren = minChildren;
+        root.maxChildren = maxChildren;
+        root.childPolicy = CHILD_POLICY_REPEAT;
+        elementHash.put(rootName, root);
+    }
+
+    @SuppressWarnings({"AbstractMethodOverridesAbstractMethod"})
+    public abstract boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType);
+
+    /**
+     * Adds a new attribute to an existing element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param dataType the data type of the new attribute.
+     * @param required the flag which indicates whether this attribute
+     * must be present.
+     * @param listMinLength the minimum legal number of list items.
+     * @param listMaxLength the the maximum legal number of list items.
+     */
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, int listMinLength, int listMaxLength
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+        if (listMinLength < 0 || listMinLength > listMaxLength) {
+            throw new IllegalArgumentException("Invalid list bounds!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.listMinLength = listMinLength;
+        attr.listMaxLength = listMaxLength;
+        attr.valueType = VALUE_LIST;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    /**
+     * Adds a new attribute to an existing element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param dataType the data type of the new attribute.
+     * @param required the flag which indicates whether this attribute
+     * must be present.
+     * @param defaultValue the default value of the attribute.
+     */
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, String defaultValue
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.defaultValue = defaultValue;
+        attr.valueType = VALUE_ARBITRARY;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    /**
+     * Adds a new attribute to an existing element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param dataType the data type of the new attribute.
+     * @param required the flag which indicates whether this attribute
+     * must be present.
+     * @param defaultValue the default value of the attribute.
+     * @param enumeratedValues the legal values for the attribute as 
+     * a list of strings.
+     */
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, String defaultValue, List<String> enumeratedValues
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+        if (enumeratedValues == null || enumeratedValues.isEmpty()) {
+            throw new IllegalArgumentException("enumeratedValues is empty or null");
+        }
+
+        try {
+            for (String enumeratedValue : enumeratedValues) {
+                if (enumeratedValue == null) {
+                    throw new IllegalArgumentException("enumeratedValues contains a null!");
+                }
+            }
+        } catch (ClassCastException e) {
+            throw new IllegalArgumentException("enumeratedValues contains a non-String value!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.defaultValue = defaultValue;
+        attr.enumeratedValues = enumeratedValues;
+        attr.valueType = VALUE_ENUMERATION;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    /**
+     * Adds a new attribute to an existing element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param dataType the data type of the new attribute.
+     * @param required the flag which indicates whether this attribute
+     * must be present.
+     * @param defaultValue the default value of attribute.
+     * @param minValue the minimum legal value of an attribute.
+     * @param maxValue the maximum legal value of an attribute.
+     * @param minInclusive the flag which indicates  
+     * whether the minValue is inclusive.
+     * @param maxInclusive the flag which indicates  
+     * whether the maxValue is inclusive.
+     */
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, String defaultValue,
+            String minValue, String maxValue,
+            boolean minInclusive, boolean maxInclusive
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.defaultValue = defaultValue;
+        attr.minValue = minValue;
+        attr.maxValue = maxValue;
+        attr.minInclusive = minInclusive;
+        attr.maxInclusive = maxInclusive;
+
+        attr.valueType = VALUE_RANGE;
+        attr.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0;
+        attr.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    /**
+     * Adds a new attribute with boolean data type to an existing 
+     * element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param hasDefaultValue the flag which indicates whether this attribute
+     * must have a default value.
+     * @param defaultValue the default value.
+     */
+    protected void addBooleanAttribute(
+            String elementName, String attrName,
+            boolean hasDefaultValue, boolean defaultValue
+    ) {
+        String defaultVal = hasDefaultValue ? (defaultValue ? "TRUE" : "FALSE") : null;
+        ArrayList<String> values = new ArrayList<String>(2);
+        values.add("TRUE");
+        values.add("FALSE");
+
+        addAttribute(elementName, attrName, DATATYPE_BOOLEAN, true, defaultVal, values);
+    }
+
+    /**
+     * Adds an existing element to the list of child elements 
+     * of the specified parent element.
+     * 
+     * @param elementName the name of the element to be added.
+     * @param parentName the parent element name.
+     */
+    protected void addChildElement(String elementName, String parentName) {
+        Element parent = findElement(parentName);
+        Element element = findElement(elementName);
+        parent.children.add(element.name);
+    }
+
+    /**
+     * Adds a new element type to this IIOMetadataFormat with 
+     * a child policy (if policy is not CHILD_POLICY_REPEAT).
+     * 
+     * @param elementName the name of the element to be added.
+     * @param parentName the parent element name.
+     * @param childPolicy one of the CHILD_POLICY_* constants defined
+     * by IIOMetadataFormat.
+     */
+    protected void addElement(String elementName, String parentName, int childPolicy) {
+        if (
+                childPolicy < CHILD_POLICY_EMPTY ||
+                childPolicy > CHILD_POLICY_MAX ||
+                childPolicy == CHILD_POLICY_REPEAT
+        ) {
+            throw new IllegalArgumentException("childPolicy is not one of the predefined constants");
+        }
+        
+        Element parent = findElement(parentName);
+        Element element = new Element();
+        element.name = elementName;
+        element.childPolicy = childPolicy;
+        elementHash.put(elementName, element);
+        parent.children.add(elementName);
+    }
+
+    /**
+     * Adds a new element type to this IIOMetadataFormat with 
+     * CHILD_POLICY_REPEAT and the specified minimum and maximum
+     * number of child elements.
+     * 
+     * @param elementName the element name to be added.
+     * @param parentName the parent element name.
+     * @param minChildren the minimum number of child elements.
+     * @param maxChildren the maximum number of child elements.
+     */
+    protected void addElement(
+            String elementName, String parentName,
+            int minChildren, int maxChildren
+    ) {
+        if (minChildren < 0) {
+            throw new IllegalArgumentException("minChildren < 0!");
+        }
+        if (minChildren > maxChildren) {
+            throw new IllegalArgumentException("minChildren > maxChildren!");
+        }
+
+        Element parent = findElement(parentName);
+        Element element = new Element();
+        element.name = elementName;
+        element.childPolicy = CHILD_POLICY_REPEAT;
+        element.minChildren = minChildren;
+        element.maxChildren = maxChildren;
+        elementHash.put(elementName, element);
+        parent.children.add(elementName);
+    }
+
+    /**
+     * Adds an Object reference with the specified class type to be 
+     * stored as element's value. 
+     * 
+     * @param elementName the element name.
+     * @param classType the class indicates the legal types for 
+     * the object's value.
+     * @param arrayMinLength the minimum legal length for the array.
+     * @param arrayMaxLength the maximum legal length for the array.
+     */
+    protected void addObjectValue(
+            String elementName, Class<?> classType,
+            int arrayMinLength, int arrayMaxLength
+    ) {
+        Element element = findElement(elementName);
+
+        ObjectValue objVal = new ObjectValue();
+        objVal.classType = classType;
+        objVal.arrayMaxLength = arrayMaxLength;
+        objVal.arrayMinLength = arrayMinLength;
+        objVal.valueType = VALUE_LIST;
+
+        element.objectValue = objVal;
+    }
+
+    /**
+     * Adds an Object reference with the specified class type to be 
+     * stored as an element's value. 
+     * 
+     * @param elementName the element name.
+     * @param classType the class indicates the legal types for 
+     * the object's value.
+     * @param required a flag indicated that this object value 
+     * must be present.
+     * @param defaultValue the default value, or null.
+     */
+    protected <T> void addObjectValue(
+            String elementName, Class<T> classType,
+            boolean required, T defaultValue
+    ) {
+        // note: reqired is an unused parameter
+        Element element = findElement(elementName);
+
+        ObjectValue<T> objVal = new ObjectValue<T>();
+        objVal.classType = classType;
+        objVal.defaultValue = defaultValue;
+        objVal.valueType = VALUE_ARBITRARY;
+
+        element.objectValue = objVal;
+    }
+
+    /**
+     * Adds an Object reference with the specified class type to be 
+     * stored as the element's value. 
+     * 
+     * @param elementName the element name.
+     * @param classType the class indicates the legal types for 
+     * the object value.
+     * @param required a flag indicated that this object value 
+     * must be present.
+     * @param defaultValue the default value, or null.
+     * @param enumeratedValues the list of legal values for the object.
+     */
+    protected <T> void addObjectValue(
+            String elementName, Class<T> classType,
+            boolean required, T defaultValue,
+            List<? extends T> enumeratedValues
+    ) {
+        // note: reqired is an unused parameter
+        if (enumeratedValues == null || enumeratedValues.isEmpty()) {
+            throw new IllegalArgumentException("enumeratedValues is empty or null");
+        }
+
+        try {
+            for (T enumeratedValue : enumeratedValues) {
+                if (enumeratedValue == null) {
+                    throw new IllegalArgumentException("enumeratedValues contains a null!");
+                }
+            }
+        } catch (ClassCastException e) {
+            throw new IllegalArgumentException("enumeratedValues contains a value not of class classType!");
+        }
+
+        Element element = findElement(elementName);
+
+        ObjectValue<T> objVal = new ObjectValue<T>();
+        objVal.classType = classType;
+        objVal.defaultValue = defaultValue;
+        objVal.enumeratedValues = enumeratedValues;
+        objVal.valueType = VALUE_ENUMERATION;
+
+        element.objectValue = objVal;
+    }
+
+    /**
+     * Adds an Object reference with the specified class type to be 
+     * stored as the element's value. 
+     * 
+     * @param elementName the element name.
+     * @param classType the class indicates the legal types for 
+     * the object value.
+     * @param defaultValue the default value, or null.
+     * @param minValue the minimum legal value for the object value. 
+     * @param maxValue the maximum legal value for the object value. 
+     * @param minInclusive the flag which indicates 
+     * whether the minValue is inclusive.
+     * @param maxInclusive the flag which indicates 
+     * whether the maxValue is inclusive.
+     */
+    protected <T extends Object & Comparable<? super T>> void addObjectValue(
+            String elementName, Class<T> classType,
+            T defaultValue, Comparable<? super T> minValue, Comparable<? super T> maxValue,
+            boolean minInclusive, boolean maxInclusive
+    ) {
+        Element element = findElement(elementName);
+
+        ObjectValue<T> objVal = new ObjectValue<T>();
+        objVal.classType = classType;
+        objVal.defaultValue = defaultValue;
+        objVal.minValue = minValue;
+        objVal.maxValue = maxValue;
+        objVal.minInclusive = minInclusive;
+        objVal.maxInclusive = maxInclusive;
+
+        objVal.valueType = VALUE_RANGE;
+        objVal.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0;
+        objVal.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0;
+
+        element.objectValue = objVal;
+    }
+
+    public int getAttributeDataType(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        return attr.dataType;
+    }
+
+    public String getAttributeDefaultValue(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        return attr.defaultValue;
+    }
+
+    public String getAttributeDescription(String elementName, String attrName, Locale locale) {
+        findAttribute(elementName, attrName);
+        return getResourceString(elementName + "/" + attrName, locale);
+    }
+
+    public String[] getAttributeEnumerations(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if (attr.valueType != VALUE_ENUMERATION) {
+            throw new IllegalArgumentException("Attribute is not an enumeration!");
+        }
+
+        return attr.enumeratedValues.toArray(new String[attr.enumeratedValues.size()]);
+    }
+
+    public int getAttributeListMaxLength(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if (attr.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Attribute is not a list!");
+        }
+        return attr.listMaxLength;
+    }
+
+    public int getAttributeListMinLength(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if (attr.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Attribute is not a list!");
+        }
+        return attr.listMinLength;
+    }
+
+    public String getAttributeMaxValue(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if ((attr.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Attribute is not a range!");
+        }
+        return attr.maxValue;        
+    }
+
+    public String getAttributeMinValue(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if ((attr.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Attribute is not a range!");
+        }
+        return attr.minValue;
+    }
+
+    public String[] getAttributeNames(String elementName) {
+        Element element = findElement(elementName);
+        return element.attributes.keySet().toArray(new String[element.attributes.size()]);
+    }
+
+    public int getAttributeValueType(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        return attr.valueType;                
+    }
+
+    public String[] getChildNames(String elementName) {
+        Element element = findElement(elementName);
+        if (element.childPolicy == CHILD_POLICY_EMPTY) { // Element cannot have children
+            return null;
+        }
+        return element.children.toArray(new String[element.children.size()]);
+    }
+
+    public int getChildPolicy(String elementName) {
+        Element element = findElement(elementName);
+        return element.childPolicy;
+    }
+
+    public String getElementDescription(String elementName, Locale locale) {
+        findElement(elementName); // Check if there is such element
+        return getResourceString(elementName, locale);
+    }
+
+    public int getElementMaxChildren(String elementName) {
+        Element element = findElement(elementName);
+        if (element.childPolicy != CHILD_POLICY_REPEAT) {
+            throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!");
+        }
+        return element.maxChildren;
+    }
+
+    public int getElementMinChildren(String elementName) {
+        Element element = findElement(elementName);
+        if (element.childPolicy != CHILD_POLICY_REPEAT) {
+            throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!");
+        }
+        return element.minChildren;
+    }
+
+    public int getObjectArrayMaxLength(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || v.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Not a list!");
+        }
+        return v.arrayMaxLength;
+    }
+
+    public int getObjectArrayMinLength(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || v.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Not a list!");
+        }
+        return v.arrayMinLength;
+    }
+
+    public Class<?> getObjectClass(String elementName) {
+        ObjectValue v = findObjectValue(elementName);
+        return v.classType;
+    }
+
+    public Object getObjectDefaultValue(String elementName) {
+        ObjectValue v = findObjectValue(elementName);
+        return v.defaultValue;
+    }
+
+    public Object[] getObjectEnumerations(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || v.valueType != VALUE_ENUMERATION) {
+            throw new IllegalArgumentException("Not an enumeration!");
+        }
+        return v.enumeratedValues.toArray();
+    }
+
+    public Comparable<?> getObjectMaxValue(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || (v.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Not a range!");
+        }
+        return v.maxValue;
+    }
+
+    public Comparable<?> getObjectMinValue(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || (v.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Not a range!");
+        }
+        return v.minValue;
+    }
+
+    public int getObjectValueType(String elementName) {
+        Element element = findElement(elementName);
+        if (element.objectValue == null) {
+            return VALUE_NONE;
+        }
+        return element.objectValue.valueType;
+    }
+
+    /**
+     * Gets the resource base name for locating ResourceBundles.
+     * 
+     * @return the current resource base name.
+     */
+    protected String getResourceBaseName() {
+        return resourceBaseName;
+    }
+
+    public String getRootName() {
+        return rootName;
+    }
+
+    /**
+     * Gets the standard format instance.
+     * 
+     * @return the IIOMetadataFormat instance.
+     */
+    public static IIOMetadataFormat getStandardFormatInstance() {
+        if (standardFormat == null) {
+            standardFormat = new IIOStandardMetadataFormat();
+        }
+
+        return standardFormat;
+    }
+
+    public boolean isAttributeRequired(String elementName, String attrName) {
+        return findAttribute(elementName, attrName).required;
+    }
+
+    /**
+     * Removes the specified attribute from the specified element. 
+     *  
+     * @param elementName the specified element name.
+     * @param attrName the specified attribute name.
+     */
+    protected void removeAttribute(String elementName, String attrName) {
+        Element element = findElement(elementName);
+        element.attributes.remove(attrName);
+    }
+
+    /**
+     * Removes the specified element from this format.
+     * 
+     * @param elementName the specified element name.
+     */
+    protected void removeElement(String elementName) {
+        Element element;
+        if ((element = elementHash.get(elementName)) != null) {
+            elementHash.remove(elementName);
+            for (Element e : elementHash.values()) {
+                e.children.remove(element.name);
+            }
+        }
+    }
+
+    /**
+     * Removes the object value from the specified element.
+     * 
+     * @param elementName the element name.
+     */
+    protected void removeObjectValue(String elementName) {
+        Element element = findElement(elementName);
+        element.objectValue = null;
+    }
+    
+    /**
+     * Sets a new base name for ResourceBundles containing 
+     * descriptions of elements and attributes for this format.
+     * 
+     * @param resourceBaseName the new resource base name.
+     */
+    protected void setResourceBaseName(String resourceBaseName) {
+        if (resourceBaseName == null) {
+            throw new IllegalArgumentException("resourceBaseName == null!");
+        }
+        this.resourceBaseName = resourceBaseName;
+    }
+
+    /**
+     * The Class Element.
+     */
+    @SuppressWarnings({"ClassWithoutConstructor"})
+    private class Element {
+        
+        /** The name. */
+        String name;
+
+        /** The children. */
+        ArrayList<String> children = new ArrayList<String>();
+        
+        /** The attributes. */
+        HashMap<String, Attlist> attributes = new HashMap<String, Attlist>();
+
+        /** The min children. */
+        int minChildren;
+        
+        /** The max children. */
+        int maxChildren;
+        
+        /** The child policy. */
+        int childPolicy;
+
+        /** The object value. */
+        ObjectValue objectValue;
+    }
+
+    /**
+     * The Class Attlist.
+     */
+    @SuppressWarnings({"ClassWithoutConstructor"})
+    private class Attlist {
+        
+        /** The name. */
+        String name;
+
+        /** The data type. */
+        int dataType;
+        
+        /** The required. */
+        boolean required;
+        
+        /** The list min length. */
+        int listMinLength;
+        
+        /** The list max length. */
+        int listMaxLength;
+        
+        /** The default value. */
+        String defaultValue;
+        
+        /** The enumerated values. */
+        List<String> enumeratedValues;
+        
+        /** The min value. */
+        String minValue;
+        
+        /** The max value. */
+        String maxValue;
+        
+        /** The min inclusive. */
+        boolean minInclusive;
+        
+        /** The max inclusive. */
+        boolean maxInclusive;
+
+        /** The value type. */
+        int valueType;
+    }
+
+    /**
+     * The Class ObjectValue.
+     */
+    @SuppressWarnings({"ClassWithoutConstructor"})
+    private class ObjectValue<T> {
+        
+        /** The class type. */
+        Class<T> classType;
+        
+        /** The array min length. */
+        int arrayMinLength;
+        
+        /** The array max length. */
+        int arrayMaxLength;
+        
+        /** The default value. */
+        T defaultValue;
+        
+        /** The enumerated values. */
+        List<? extends T> enumeratedValues;
+        
+        /** The min value. */
+        Comparable<? super T> minValue;
+        
+        /** The max value. */
+        Comparable<? super T> maxValue;
+        
+        /** The min inclusive. */
+        boolean minInclusive;
+        
+        /** The max inclusive. */
+        boolean maxInclusive;
+
+        /** The value type. */
+        int valueType;
+    }
+
+    /**
+     * Find element.
+     * 
+     * @param name the name
+     * 
+     * @return the element
+     */
+    private Element findElement(String name) {
+        Element element;
+        if ((element = elementHash.get(name)) == null) {
+            throw new IllegalArgumentException("element name is null or no such element: " + name);
+        }
+
+        return element;
+    }
+
+    /**
+     * Find attribute.
+     * 
+     * @param elementName the element name
+     * @param attributeName the attribute name
+     * 
+     * @return the attlist
+     */
+    private Attlist findAttribute(String elementName, String attributeName) {
+        Element element = findElement(elementName);
+        Attlist attribute;
+        if ((attribute = element.attributes.get(attributeName)) == null) {
+            throw new IllegalArgumentException("attribute name is null or no such attribute: " + attributeName);
+        }
+
+        return attribute;
+    }
+
+    /**
+     * Find object value.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the object value
+     */
+    private ObjectValue findObjectValue(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null) {
+            throw new IllegalArgumentException("No object within element");
+        }
+        return v;
+    }
+
+    /**
+     * Gets the resource string.
+     * 
+     * @param key the key
+     * @param locale the locale
+     * 
+     * @return the resource string
+     */
+    private String getResourceString(String key, Locale locale) {
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+
+        // Get the context class loader and try to locate the bundle with it first
+        ClassLoader contextClassloader = AccessController.doPrivileged(
+                new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        return Thread.currentThread().getContextClassLoader();
+                    }
+        });
+
+        // Now try to get the resource bundle
+        ResourceBundle rb;
+        try {
+            rb = ResourceBundle.getBundle(resourceBaseName, locale, contextClassloader);
+        } catch (MissingResourceException e) {
+            try {
+                rb = ResourceBundle.getBundle(resourceBaseName, locale);
+            } catch (MissingResourceException e1) {
+                return null;
+            }
+        }
+
+        try {
+            return rb.getString(key);
+        } catch (MissingResourceException e) {
+            return null;
+        } catch (ClassCastException e) {
+            return null; // Not a string resource
+        }
+    }
+}
diff --git a/awt/javax/imageio/metadata/IIOMetadataNode.java b/awt/javax/imageio/metadata/IIOMetadataNode.java
new file mode 100644
index 0000000..d5ab7a5
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadataNode.java
@@ -0,0 +1,675 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package javax.imageio.metadata;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+//???AWT
+//import org.w3c.dom.TypeInfo;
+//import org.w3c.dom.UserDataHandler;
+
+/**
+ * The Class IIOMetadataNode represents a node of the 
+ * (DOM-style) metadata tree.
+ */
+public class IIOMetadataNode implements Element, NodeList {
+
+    /** The node name. */
+    private String nodeName;
+    
+    /** The node value. */
+    private String nodeValue;
+    
+    /** The attributes. */
+    private IIOMetadataNodeList attrs = new IIOMetadataNodeList(new ArrayList<IIOMetadataNode>());
+
+    /** The parent node. */
+    private IIOMetadataNode parent;
+    
+    /** The first child node. */
+    private IIOMetadataNode firstChild;
+    
+    /** The last child node. */
+    private IIOMetadataNode lastChild;
+    
+    /** The previous sibling. */
+    private IIOMetadataNode previousSibling;
+    
+    /** The next sibling. */
+    private IIOMetadataNode nextSibling;
+
+    /** The number of children. */
+    private int nChildren;
+
+    /** The user object associated with this node. */
+    private Object userObject;
+
+    /** The text content of this node. */
+    private String textContent;
+
+    /**
+     * Instantiates a new empty node.
+     */
+    public IIOMetadataNode() {
+    }
+
+    /**
+     * Instantiates a new empty node with the specified name.
+     * 
+     * @param nodeName the node name
+     */
+    public IIOMetadataNode(String nodeName) {
+        this.nodeName = nodeName;
+    }
+
+    /**
+     * Instantiates a new IIOMetadataNode with the specified 
+     * name and value.
+     * 
+     * @param nodeName the node name
+     * @param nodeValue the node value
+     */
+    private IIOMetadataNode(String nodeName, String nodeValue) {
+        this.nodeName = nodeName;
+        this.nodeValue = nodeValue;
+    }
+
+    public String getTagName() {
+        return nodeName;
+    }
+
+    public String getAttribute(String name) {
+        Attr attrNode = (Attr) attrs.getNamedItem(name);
+        return (attrNode == null) ? "" : attrNode.getValue();
+    }
+
+    public void setAttribute(String name, String value) throws DOMException {
+        Attr attr = (Attr) attrs.getNamedItem(name);
+        if (attr != null) {
+            attr.setValue(value);
+        } else {
+            attrs.list.add(new IIOMetadataAttr(name, value, this));
+        }
+    }
+
+    public void removeAttribute(String name) throws DOMException {
+        IIOMetadataAttr attr = (IIOMetadataAttr) attrs.getNamedItem(name);
+        if (attr != null) {
+            attr.setOwnerElement(null);
+            attrs.list.remove(attr);
+        }
+    }
+
+    public Attr getAttributeNode(String name) {
+        return (Attr) attrs.getNamedItem(name);
+    }
+
+    public Attr setAttributeNode(Attr newAttr) throws DOMException {
+        // Check if this attribute is already in use.
+        Element owner = newAttr.getOwnerElement();
+        if (owner != null) {
+            if (owner == this) { // Replacing an attribute node by itself has no effect
+                return null;
+            } else {
+                throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, "Attribute is already in use");
+            }
+        }
+
+        String name = newAttr.getName();
+        Attr oldAttr = getAttributeNode(name);
+        if (oldAttr != null) {
+            removeAttributeNode(oldAttr);
+        }
+
+        IIOMetadataAttr iioAttr;
+        if (newAttr instanceof IIOMetadataAttr) {
+            iioAttr = (IIOMetadataAttr) newAttr;
+            iioAttr.setOwnerElement(this);
+        } else {
+            iioAttr = new IIOMetadataAttr(name, newAttr.getValue(), this);
+        }
+
+        attrs.list.add(iioAttr);
+
+        return oldAttr;
+    }
+
+    public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
+        if (!attrs.list.remove(oldAttr)) { // Not found
+            throw new DOMException(DOMException.NOT_FOUND_ERR, "No such attribute!");
+        }
+
+        ((IIOMetadataAttr)oldAttr).setOwnerElement(null);
+
+        return oldAttr;
+    }
+
+    public NodeList getElementsByTagName(String name) {
+        ArrayList<IIOMetadataNode> nodes = new ArrayList<IIOMetadataNode>();
+
+        // Non-recursive tree walk
+        Node pos = this;
+
+        while (pos != null) {
+            if (pos.getNodeName().equals(name)) {
+                nodes.add((IIOMetadataNode)pos);
+            }
+
+            Node nextNode = pos.getFirstChild();
+
+            while (nextNode == null) {
+                if (pos == this) {
+                    break;
+                }
+
+                nextNode = pos.getNextSibling();
+
+                if (nextNode == null) {
+                    pos = pos.getParentNode();
+
+                    if (pos == null || pos == this) {
+                        nextNode = null;
+                        break;
+                    }
+                }
+            }
+            pos = nextNode;
+        }
+
+        return new IIOMetadataNodeList(nodes);
+    }
+
+    public String getAttributeNS(String namespaceURI, String localName) throws DOMException {
+        return getAttribute(localName);
+    }
+
+    public void setAttributeNS(String namespaceURI, String qualifiedName, String value) throws DOMException {
+        setAttribute(qualifiedName, value);
+    }
+
+    public void removeAttributeNS(String namespaceURI, String localName) throws DOMException {
+        removeAttribute(localName);
+    }
+
+    public Attr getAttributeNodeNS(String namespaceURI, String localName) throws DOMException {
+        return getAttributeNode(localName);
+    }
+
+    public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
+        return setAttributeNode(newAttr);
+    }
+
+    public NodeList getElementsByTagNameNS(String namespaceURI, String localName) throws DOMException {
+        return getElementsByTagName(localName);
+    }
+
+    public boolean hasAttribute(String name) {
+        return attrs.getNamedItem(name) != null;
+    }
+
+    public boolean hasAttributeNS(String namespaceURI, String localName) throws DOMException {
+        return hasAttribute(localName);
+    }
+
+    //???AWT
+    /*
+    public TypeInfo getSchemaTypeInfo() {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }*/
+
+    public void setIdAttribute(String name, boolean isId) throws DOMException {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public void setIdAttributeNS(String namespaceURI, String localName, boolean isId) throws DOMException {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public String getNodeName() {
+        return nodeName;
+    }
+
+    public String getNodeValue() throws DOMException {
+        return nodeValue;
+    }
+
+    public void setNodeValue(String nodeValue) throws DOMException {
+        this.nodeValue = nodeValue;
+    }
+
+    public short getNodeType() {
+        return ELEMENT_NODE;
+    }
+
+    public Node getParentNode() {
+        return parent;
+    }
+
+    public NodeList getChildNodes() {
+        return this;
+    }
+
+    public Node getFirstChild() {
+        return firstChild;
+    }
+
+    public Node getLastChild() {
+        return lastChild;
+    }
+
+    public Node getPreviousSibling() {
+        return previousSibling;
+    }
+
+    public Node getNextSibling() {
+        return nextSibling;
+    }
+
+    public NamedNodeMap getAttributes() {
+        return attrs;
+    }
+
+    public Document getOwnerDocument() {
+        return null;
+    }
+
+    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
+        if (newChild == null) {
+            throw new IllegalArgumentException("newChild == null!");
+        }
+
+        IIOMetadataNode newIIOChild = (IIOMetadataNode) newChild;
+        IIOMetadataNode refIIOChild = (IIOMetadataNode) refChild;
+
+        newIIOChild.parent = this;
+
+        if (refIIOChild == null) {
+            newIIOChild.nextSibling = null;
+            newIIOChild.previousSibling = lastChild;
+
+            // Fix this node
+            lastChild = newIIOChild;
+            if (firstChild == null) {
+                firstChild = newIIOChild;
+            }
+        } else {
+            newIIOChild.nextSibling = refIIOChild;
+            newIIOChild.previousSibling = refIIOChild.previousSibling;
+
+            // Fix this node
+            if (firstChild == refIIOChild) {
+                firstChild = newIIOChild;
+            }
+
+            // Fix next node
+            if (refIIOChild != null) {
+                refIIOChild.previousSibling = newIIOChild;
+            }
+        }
+
+        // Fix prev node
+        if (newIIOChild.previousSibling != null) {
+            newIIOChild.previousSibling.nextSibling = newIIOChild;
+        }
+
+        nChildren++;
+
+        return newIIOChild;
+    }
+
+    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
+        if (newChild == null) {
+            throw new IllegalArgumentException("newChild == null!");
+        }
+
+        IIOMetadataNode newIIOChild = (IIOMetadataNode) newChild;
+        IIOMetadataNode oldIIOChild = (IIOMetadataNode) oldChild;
+
+        IIOMetadataNode next = oldIIOChild.nextSibling;
+        IIOMetadataNode previous = oldIIOChild.previousSibling;
+
+        // Fix new node
+        newIIOChild.parent = this;
+        newIIOChild.nextSibling = next;
+        newIIOChild.previousSibling = previous;
+
+        // Fix this node
+        if (lastChild == oldIIOChild) {
+            lastChild = newIIOChild;
+        }
+        if (firstChild == oldIIOChild) {
+            firstChild = newIIOChild;
+        }
+
+        // Fix siblings
+        if (next != null) {
+            next.previousSibling = newIIOChild;
+        }
+        if (previous != null) {
+            previous.nextSibling = newIIOChild;
+        }
+
+        // Fix old child
+        oldIIOChild.parent = null;
+        oldIIOChild.nextSibling = next;
+        oldIIOChild.previousSibling = previous;
+
+        return oldIIOChild;
+    }
+
+    public Node removeChild(Node oldChild) throws DOMException {
+        if (oldChild == null) {
+            throw new IllegalArgumentException("oldChild == null!");
+        }
+
+        IIOMetadataNode oldIIOChild = (IIOMetadataNode) oldChild;
+
+        // Fix next and previous
+        IIOMetadataNode previous = oldIIOChild.previousSibling;
+        IIOMetadataNode next = oldIIOChild.nextSibling;
+
+        if (previous != null) {
+            previous.nextSibling = next;
+        }
+        if (next != null) {
+            next.previousSibling = previous;
+        }
+
+        // Fix this node
+        if (lastChild == oldIIOChild) {
+            lastChild = previous;
+        }
+        if (firstChild == oldIIOChild) {
+            firstChild = next;
+        }
+        nChildren--;
+
+        // Fix old child
+        oldIIOChild.parent = null;
+        oldIIOChild.previousSibling = null;
+        oldIIOChild.nextSibling = null;
+
+        return oldIIOChild;
+    }
+
+    public Node appendChild(Node newChild) throws DOMException {
+        return insertBefore(newChild, null);
+    }
+
+    public boolean hasChildNodes() {
+        return nChildren != 0;
+    }
+
+    public Node cloneNode(boolean deep) {
+        IIOMetadataNode cloned = new IIOMetadataNode(nodeName);
+        cloned.setUserObject(getUserObject());
+
+        if (deep) { // Clone recursively
+            IIOMetadataNode c = firstChild;
+            while (c != null) {
+                cloned.insertBefore(c.cloneNode(true), null);
+                c = c.nextSibling;
+            }
+        }
+
+        return cloned;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void normalize() {
+        // Do nothing
+    }
+
+    public boolean isSupported(String feature, String version) {
+        return false;
+    }
+
+    public String getNamespaceURI() {
+        return null;
+    }
+
+    public String getPrefix() {
+        return null;
+    }
+
+    public void setPrefix(String prefix) throws DOMException {
+        // Do nothing
+    }
+
+    public String getLocalName() {
+        return nodeName;
+    }
+
+    public boolean hasAttributes() {
+        return attrs.list.size() > 0;
+    }
+
+    public String getBaseURI() {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public short compareDocumentPosition(Node other) throws DOMException {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public String getTextContent() throws DOMException {
+        return textContent;
+    }
+
+    public void setTextContent(String textContent) throws DOMException {
+        this.textContent = textContent;
+    }
+
+    public boolean isSameNode(Node other) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public String lookupPrefix(String namespaceURI) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public boolean isDefaultNamespace(String namespaceURI) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public String lookupNamespaceURI(String prefix) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public boolean isEqualNode(Node arg) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public Object getFeature(String feature, String version) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    //???AWT
+    /*
+    public Object setUserData(String key, Object data, UserDataHandler handler) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }*/
+
+    public Object getUserData(String key) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public Node item(int index) {
+        if (index < 0 || index >= nChildren) {
+            return null;
+        }
+
+        Node n;
+        for (n = getFirstChild(); index > 0; index--) {
+            n = n.getNextSibling();
+        }
+
+        return n;
+    }
+
+    public int getLength() {
+        return nChildren;
+    }
+
+    /**
+     * Gets the user object associated with this node.
+     * 
+     * @return the user object associated with this node
+     */
+    public Object getUserObject() {
+        return userObject;
+    }
+
+    /**
+     * Sets the user object associated with this node.
+     * 
+     * @param userObject the new user object associated with this node
+     */
+    public void setUserObject(Object userObject) {
+        this.userObject = userObject;
+    }
+
+    /**
+     * The Class IIOMetadataAttr.
+     */
+    private class IIOMetadataAttr extends IIOMetadataNode implements Attr {
+        
+        /** The owner element. */
+        private Element ownerElement;
+
+        /**
+         * Instantiates a new iIO metadata attr.
+         * 
+         * @param name the name
+         * @param value the value
+         * @param owner the owner
+         */
+        public IIOMetadataAttr(String name, String value, Element owner) {
+            super(name, value);
+            this.ownerElement = owner;
+        }
+
+        public String getName() {
+            return getNodeName();
+        }
+
+        public boolean getSpecified() {
+            return true;
+        }
+
+        public String getValue() {
+            return nodeValue;
+        }
+
+        public void setValue(String value) throws DOMException {
+            nodeValue = value;
+        }
+
+        public Element getOwnerElement() {
+            return ownerElement;
+        }
+
+        /**
+         * Sets the owner element.
+         * 
+         * @param ownerElement the new owner element
+         */
+        public void setOwnerElement(Element ownerElement) {
+            this.ownerElement = ownerElement;
+        }
+
+        public boolean isId() {
+            throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+        }
+
+        @Override
+        public short getNodeType() {
+            return ATTRIBUTE_NODE;
+        }
+    }
+
+    /**
+     * The Class IIOMetadataNodeList.
+     */
+    private class IIOMetadataNodeList implements NodeList, NamedNodeMap {
+        
+        /** The list. */
+        private List<IIOMetadataNode> list;
+
+        /**
+         * Instantiates a new iIO metadata node list.
+         * 
+         * @param list the list
+         */
+        IIOMetadataNodeList(List<IIOMetadataNode> list) {
+            this.list = list;
+        }
+
+        public Node item(int index) {
+            try {
+                return list.get(index);
+            } catch (IndexOutOfBoundsException e) {
+                return null;
+            }
+        }
+
+        public int getLength() {
+            return list.size();
+        }
+
+        public Node getNamedItem(String name) {
+            for(IIOMetadataNode node:list) {
+                if (name.equals(node.getNodeName())) {
+                    return node;
+                }
+            }
+            return null;
+        }
+
+        public Node setNamedItem(Node arg) throws DOMException {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "This NamedNodeMap is read-only!");
+        }
+
+        public Node removeNamedItem(String name) throws DOMException {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "This NamedNodeMap is read-only!");
+        }
+
+        public Node getNamedItemNS(String namespaceURI, String localName) throws DOMException {
+            return getNamedItem(localName);
+        }
+
+        public Node setNamedItemNS(Node arg) throws DOMException {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "This NamedNodeMap is read-only!");
+        }
+
+        public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "This NamedNodeMap is read-only!");
+        }
+    }
+}
diff --git a/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java b/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java
new file mode 100644
index 0000000..94d2125
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java
@@ -0,0 +1,316 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.metadata;
+
+import javax.imageio.ImageTypeSpecifier;
+import java.util.ArrayList;
+
+/**
+ * The Class IIOStandardMetadataFormat describes the rules of the 
+ * standard metadata format.
+ */
+class IIOStandardMetadataFormat  extends IIOMetadataFormatImpl {
+    
+    /**
+     * Instantiates a new IIOStandardMetadataFormat.
+     */
+    public IIOStandardMetadataFormat() {
+        super(standardMetadataFormatName, CHILD_POLICY_SOME);
+        buildDTD();
+    }
+
+    @Override
+    public boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType) {
+        return true;
+    }
+
+    /**
+     * Builds the dtd that describes the standard metadata format.
+     */
+    private void buildDTD() {
+        // CHROMA
+        addElement("Chroma", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("ColorSpaceType", "Chroma", CHILD_POLICY_EMPTY);
+
+        ArrayList<String> values = new ArrayList<String>(27);
+        values.add("XYZ");
+        values.add("Lab");
+        values.add("Luv");
+        values.add("YCbCr");
+        values.add("Yxy");
+        values.add("YCCK");
+        values.add("PhotoYCC");
+        values.add("RGB");
+        values.add("GRAY");
+        values.add("HSV");
+        values.add("HLS");
+        values.add("CMYK");
+        values.add("CMY");
+        values.add("2CLR");
+        values.add("3CLR");
+        values.add("4CLR");
+        values.add("5CLR");
+        values.add("6CLR");
+        values.add("7CLR");
+        values.add("8CLR");
+        values.add("9CLR");
+        values.add("ACLR");
+        values.add("BCLR");
+        values.add("CCLR");
+        values.add("DCLR");
+        values.add("ECLR");
+        values.add("FCLR");
+        addAttribute("ColorSpaceType", "name", DATATYPE_STRING, true, null, values);
+
+        addElement("NumChannels", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("NumChannels", "value", DATATYPE_INTEGER, true, 0, Integer.MAX_VALUE); // list - why?
+
+        addElement("Gamma", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("Gamma", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("BlackIsZero", "Chroma", CHILD_POLICY_EMPTY);
+        addBooleanAttribute("BlackIsZero", "value", true, true);
+
+        addElement("Palette", "Chroma", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+        addElement("PaletteEntry", "Palette", CHILD_POLICY_EMPTY);
+        addAttribute("PaletteEntry", "index", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "red", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "green", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "blue", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "alpha", DATATYPE_INTEGER, false, "255");
+
+        addElement("BackgroundIndex", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("BackgroundIndex", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("BackgroundColor", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("BackgroundColor", "red", DATATYPE_INTEGER, true, null);
+        addAttribute("BackgroundColor", "green", DATATYPE_INTEGER, true, null);
+        addAttribute("BackgroundColor", "blue", DATATYPE_INTEGER, true, null);
+
+        // COMPRESSION
+        addElement("Compression", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("CompressionTypeName", "Compression", CHILD_POLICY_EMPTY);
+        addAttribute("CompressionTypeName", "value", DATATYPE_STRING, true, null);
+
+        addElement("Lossless", "Compression", CHILD_POLICY_EMPTY);
+        addBooleanAttribute("Lossless", "value", true, true);
+
+        addElement("NumProgressiveScans", "Compression", CHILD_POLICY_EMPTY);
+        addAttribute("NumProgressiveScans", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("BitRate", "Compression", CHILD_POLICY_EMPTY);
+        addAttribute("BitRate", "value", DATATYPE_FLOAT, true, null);
+
+        // DATA
+        addElement("Data", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("PlanarConfiguration", "Data", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(4);
+        values.add("PixelInterleaved");
+        values.add("PlaneInterleaved");
+        values.add("LineInterleaved");
+        values.add("TileInterleaved");
+        addAttribute("PlanarConfiguration", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("SampleFormat", "Data", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(4);
+        values.add("SignedIntegral");
+        values.add("UnsignedIntegral");
+        values.add("Real");
+        values.add("Index");
+        addAttribute("SampleFormat", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("BitsPerSample", "Data", CHILD_POLICY_EMPTY);
+        addAttribute("BitsPerSample", "value", DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE); // list
+
+        addElement("SignificantBitsPerSample", "Data", CHILD_POLICY_EMPTY);
+        addAttribute(
+                "SignificantBitsPerSample", "value",
+                DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE
+        ); // list
+
+        addElement("SampleMSB", "Data", CHILD_POLICY_EMPTY);
+        addAttribute("SampleMSB", "value", DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE); // list
+
+        // DIMENSION
+        addElement("Dimension", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("PixelAspectRatio", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("PixelAspectRatio", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("ImageOrientation", "Dimension", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(8);
+        values.add("Normal");
+        values.add("Rotate90");
+        values.add("Rotate180");
+        values.add("Rotate270");
+        values.add("FlipH");
+        values.add("FlipV");
+        values.add("FlipHRotate90");
+        values.add("FlipVRotate90");
+        addAttribute("ImageOrientation", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("HorizontalPixelSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPixelSize", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("VerticalPixelSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPixelSize", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("HorizontalPhysicalPixelSpacing", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPhysicalPixelSpacing", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("VerticalPhysicalPixelSpacing", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPhysicalPixelSpacing", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("HorizontalPosition", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPosition", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("VerticalPosition", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPosition", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("HorizontalPixelOffset", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPixelOffset", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("VerticalPixelOffset", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPixelOffset", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("HorizontalScreenSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalScreenSize", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("VerticalScreenSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalScreenSize", "value", DATATYPE_INTEGER, true, null);
+
+        // DOCUMENT
+        addElement("Document", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("FormatVersion", "Document", CHILD_POLICY_EMPTY);
+        addAttribute("FormatVersion", "value", DATATYPE_STRING, true, null);
+
+        addElement("SubimageInterpretation", "Document", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(14);
+        values.add("Standalone");
+        values.add("SinglePage");
+        values.add("FullResolution");
+        values.add("ReducedResolution");
+        values.add("PyramidLayer");
+        values.add("Preview");
+        values.add("VolumeSlice");
+        values.add("ObjectView");
+        values.add("Panorama");
+        values.add("AnimationFrame");
+        values.add("TransparencyMask");
+        values.add("CompositingLayer");
+        values.add("SpectralSlice");
+        values.add("Unknown");
+        addAttribute("SubimageInterpretation", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("ImageCreationTime", "Document", CHILD_POLICY_EMPTY);
+        addAttribute("ImageCreationTime", "year", DATATYPE_INTEGER, true, null);
+        addAttribute(
+                "ImageCreationTime", "month",
+                DATATYPE_INTEGER, true, null, "1", "12", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "day",
+                DATATYPE_INTEGER, true, null, "1", "31", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "hour",
+                DATATYPE_INTEGER, false, "0", "0", "23", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "minute",
+                DATATYPE_INTEGER, false, "0", "0", "59", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "second",
+                DATATYPE_INTEGER, false, "0", "0", "60", true, true
+        );
+
+        addElement("ImageModificationTime", "Document", CHILD_POLICY_EMPTY);
+        addAttribute("ImageModificationTime", "year", DATATYPE_INTEGER, true, null);
+        addAttribute(
+                "ImageModificationTime", "month",
+                DATATYPE_INTEGER, true, null, "1", "12", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "day",
+                DATATYPE_INTEGER, true, null, "1", "31", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "hour",
+                DATATYPE_INTEGER, false, "0", "0", "23", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "minute",
+                DATATYPE_INTEGER, false, "0", "0", "59", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "second",
+                DATATYPE_INTEGER, false, "0", "0", "60", true, true
+        );
+
+        // TEXT
+        addElement("Text", standardMetadataFormatName, 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+
+        addElement("TextEntry", "Text", CHILD_POLICY_EMPTY);
+        addAttribute("TextEntry", "keyword", DATATYPE_STRING, false, null);
+        addAttribute("TextEntry", "value", DATATYPE_STRING, true, null);
+        addAttribute("TextEntry", "language", DATATYPE_STRING, false, null);
+        addAttribute("TextEntry", "encoding", DATATYPE_STRING, false, null);
+        values = new ArrayList<String>(5);
+        values.add("none");
+        values.add("lzw");
+        values.add("zip");
+        values.add("bzip");
+        values.add("other");
+        addAttribute("TextEntry", "compression", DATATYPE_STRING, false, "none", values);
+
+        // TRANSPARENCY
+        addElement("Transparency", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("Alpha", "Transparency", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(3);
+        values.add("none");
+        values.add("premultiplied");
+        values.add("nonpremultiplied");
+        addAttribute("Alpha", "value", DATATYPE_STRING, false, "none", values);
+
+        addElement("TransparentIndex", "Transparency", CHILD_POLICY_EMPTY);
+        addAttribute("TransparentIndex", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("TransparentColor", "Transparency", CHILD_POLICY_EMPTY);
+        addAttribute("TransparentColor", "value", DATATYPE_INTEGER, true, 0, Integer.MAX_VALUE);
+
+        addElement("TileTransparencies", "Transparency", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+
+        addElement("TransparentTile", "TileTransparencies", CHILD_POLICY_EMPTY);
+        addAttribute("TransparentTile", "x", DATATYPE_INTEGER, true, null);
+        addAttribute("TransparentTile", "y", DATATYPE_INTEGER, true, null);
+
+        addElement("TileOpacities", "Transparency", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+
+        addElement("OpaqueTile", "TileOpacities", CHILD_POLICY_EMPTY);
+        addAttribute("OpaqueTile", "x", DATATYPE_INTEGER, true, null);
+        addAttribute("OpaqueTile", "y", DATATYPE_INTEGER, true, null);
+    }
+}
+
diff --git a/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties b/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties
new file mode 100644
index 0000000..d185808
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties
@@ -0,0 +1,133 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+# Descriptions of elements and attributes of the plugin neutral metadata format
+# (see IIOStandardMetadataFormat)
+
+# Messages for EN locale
+Chroma=Chroma (color) information
+ColorSpaceType=The raw color space of the image
+ColorSpaceType/name=The raw color space of the image
+NumChannels=The number of channels in the raw image, including alpha
+NumChannels/value=The number of channels in the raw image, including alpha
+Gamma=The image gamma
+Gamma/value=The image gamma
+BlackIsZero=True if smaller values represent darker shades
+BlackIsZero/value=True if smaller values represent darker shades
+Palette=Palette-color information
+PaletteEntry=A palette entry
+PaletteEntry/index=The index of the palette entry
+PaletteEntry/red=The red value for the palette entry
+PaletteEntry/green=The green value for the palette entry
+PaletteEntry/blue=The blue value for the palette entry
+PaletteEntry/alpha=The alpha value for the palette entry
+BackgroundIndex=A palette index to be used as a background
+BackgroundIndex/value=A palette index to be used as a background
+BackgroundColor=An RGB triple to be used as a background
+BackgroundColor/red=The red background value
+BackgroundColor/green=The green background value
+BackgroundColor/blue=The blue background value
+
+Compression=Compression information
+CompressionTypeName=The name of the compression scheme in use
+CompressionTypeName/value=The name of the compression scheme in use
+Lossless=True if the compression scheme is lossless
+Lossless/value=True if the compression scheme is lossless
+NumProgressiveScans=The number of progressive scans used in the image encoding
+NumProgressiveScans/value=The number of progressive scans used in the image encoding
+BitRate=The estimated bit rate of the compression scheme
+BitRate/value=The estimated bit rate of the compression scheme
+
+Data=Information on the image layout
+PlanarConfiguration=The organization of image samples in the stream
+PlanarConfiguration/value=The organization of image samples in the stream
+SampleFormat=The numeric format of image samples
+SampleFormat/value=The numeric format of image samples
+BitsPerSample=The number of bits per sample
+BitsPerSample/value=A list of integers, one per channel
+SignificantBitsPerSample=The number of significant bits per sample
+SignificantBitsPerSample/value=A list of integers, one per channel
+SampleMSB=The position of the most significant bit of each sample
+SampleMSB/value=A list of integers, one per channel
+
+Dimension=Dimension information
+PixelAspectRatio=The width of a pixel divided by its height
+PixelAspectRatio/value=The width of a pixel divided by its height
+ImageOrientation=The desired orientation of the image in terms of flips and counter-clockwise rotations
+ImageOrientation/value=The desired orientation of the image in terms of flips and counter-clockwise rotations
+HorizontalPixelSize=The width of a pixel, in millimeters, as it should be rendered on media
+HorizontalPixelSize/value=The width of a pixel, in millimeters, as it should be rendered on media
+VerticalPixelSize=The height of a pixel, in millimeters, as it should be rendered on media
+VerticalPixelSize/value=The height of a pixel, in millimeters, as it should be rendered on media
+HorizontalPhysicalPixelSpacing=The horizontal distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+HorizontalPhysicalPixelSpacing/value=The horizontal distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+VerticalPhysicalPixelSpacing=The vertical distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+VerticalPhysicalPixelSpacing/value=The vertical distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+HorizontalPosition=The horizontal position, in millimeters, where the image should be rendered on media
+HorizontalPosition/value=The horizontal position, in millimeters, where the image should be rendered on media
+VerticalPosition=The vertical position, in millimeters, where the image should be rendered on media
+VerticalPosition/value=The vertical position, in millimeters, where the image should be rendered on media
+HorizontalPixelOffset=The horizonal position, in pixels, where the image should be rendered onto a raster display
+HorizontalPixelOffset/value=The horizonal position, in pixels, where the image should be rendered onto a raster display
+VerticalPixelOffset=The vertical position, in pixels, where the image should be rendered onto a raster display
+VerticalPixelOffset/value=The vertical position, in pixels, where the image should be rendered onto a raster display
+HorizontalScreenSize=The width, in pixels, of the raster display into which the image should be rendered
+HorizontalScreenSize/value=The width, in pixels, of the raster display into which the image should be rendered
+VerticalScreenSize=The height, in pixels, of the raster display into which the image should be rendered
+VerticalScreenSize/value=The height, in pixels, of the raster display into which the image should be rendered
+
+Document=Document information
+FormatVersion=The version of the format used by the stream
+FormatVersion/value=The version of the format used by the stream
+SubimageInterpretation=The interpretation of this image in relation to the other images stored in the same stream
+SubimageInterpretation/value=The interpretation of this image in relation to the other images stored in the same stream
+ImageCreationTime=The time of image creation
+ImageCreationTime/year=The full year (e.g., 1967, not 67)
+ImageCreationTime/month=The month, with January = 1
+ImageCreationTime/day=The day of the month
+ImageCreationTime/hour=The hour from 0 to 23
+ImageCreationTime/minute=The minute from 0 to 59
+ImageCreationTime/second=The second from 0 to 60 (60 = leap second)
+ImageModificationTime=The time of the last image modification
+ImageModificationTime/year=The full year (e.g., 1967, not 67)
+ImageModificationTime/month=The month, with January = 1
+ImageModificationTime/day=The day of the month
+ImageModificationTime/hour=The hour from 0 to 23
+ImageModificationTime/minute=The minute from 0 to 59
+ImageModificationTime/second=The second from 0 to 60 (60 = leap second)
+
+Text=Text information
+TextEntry=A text entry
+TextEntry/keyword=A keyword associated with the text entry
+TextEntry/value=the text entry
+TextEntry/language=The language of the text
+TextEntry/encoding=The encoding of the text
+TextEntry/compression=The method used to compress the text
+
+Transparency=Transparency information
+Alpha=The type of alpha information contained in the image
+Alpha/value=The type of alpha information contained in the image
+TransparentIndex=A palette index to be treated as transparent
+TransparentIndex/value=A palette index to be treated as transparent
+TransparentColor=An RGB color to be treated as transparent
+TransparentColor/value=An RGB color to be treated as transparent
+TileTransparencies=A list of completely transparent tiles
+TransparentTile=The index of a completely transparent tile
+TransparentTile/x=The tile's X index
+TransparentTile/y=The tile's Y index
+TileOpacities=A list of completely opaque tiles
+OpaqueTile=The index of a completely opaque tile
+OpaqueTile/x=The tile's X index
+OpaqueTile/y=The tile's Y index
diff --git a/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java b/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java
new file mode 100644
index 0000000..0cd44db
--- /dev/null
+++ b/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java
@@ -0,0 +1,75 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.plugins.bmp;
+
+import javax.imageio.ImageWriteParam;
+import java.util.Locale;
+
+/**
+ * The BMPImageWriteParam class allows encoding an image in
+ * BMP format.
+ */
+public class BMPImageWriteParam extends ImageWriteParam {
+    
+    /** The top down. */
+    private boolean topDown; // Default is bottom-up
+
+    /**
+     * Instantiates a new BMPImageWriteParam with default values of all
+     * parameters.
+     */
+    public BMPImageWriteParam() {
+        this(null);
+    }
+
+    /**
+     * Instantiates a new BMPImageWriteParam with the specified Locale.
+     * 
+     * @param locale the specified Locale.
+     */
+    public BMPImageWriteParam(Locale locale) {
+        super(locale);
+
+        // Set the compression
+        canWriteCompressed = true;
+        compressionTypes = new String[] {"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS"};
+        compressionType = compressionTypes[0]; 
+    }
+
+    /**
+     * Sets true if the data will be written in a top-down order, 
+     * false otherwise.
+     * 
+     * @param topDown the new top-down value. 
+     */
+    public void setTopDown(boolean topDown) {
+        this.topDown = topDown;
+    }
+
+    /**
+     * Returns true if the data is written in top-down order, false
+     * otherwise.
+     * 
+     * @return true if the data is written in top-down order, false
+     * otherwise.
+     */
+    public boolean isTopDown() {
+        return topDown;
+    }
+}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java b/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
new file mode 100644
index 0000000..398c960
--- /dev/null
+++ b/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
@@ -0,0 +1,213 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package javax.imageio.plugins.jpeg;
+
+/**
+ * The JPEGHuffmanTable class represents a single JPEG Huffman table. 
+ * It contains the standard tables from the JPEG specification.
+ */
+public class JPEGHuffmanTable {
+    
+    /** The standard DC luminance Huffman table . */
+    public static final JPEGHuffmanTable StdDCLuminance = new JPEGHuffmanTable(
+            new short[] {0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+            new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0A, 0x0B},
+            false
+    );
+
+    /** The standard DC chrominance Huffman table. */
+    public static final JPEGHuffmanTable StdDCChrominance = new JPEGHuffmanTable(
+            new short[] {0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+            new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0A, 0x0B},
+            false
+    );
+
+    /** The standard AC luminance Huffman table. */
+    public static final JPEGHuffmanTable StdACLuminance = new JPEGHuffmanTable(
+            new short[] {0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7D},
+            new short[] {
+                    0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
+                    0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
+                    0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72,
+                    0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
+                    0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45,
+                    0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+                    0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75,
+                    0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+                    0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3,
+                    0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
+                    0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
+                    0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
+                    0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4,
+                    0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
+            },
+            false
+    );
+
+    /** 
+     * The standard AC chrominance Huffman table. */
+    public static final JPEGHuffmanTable StdACChrominance = new JPEGHuffmanTable(
+            new short[] {0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77},
+            new short[] {
+                    0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
+                    0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+                    0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1,
+                    0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
+                    0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
+                    0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+                    0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74,
+                    0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+                    0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
+                    0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
+                    0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+                    0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
+                    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4,
+                    0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
+            },
+            false
+    );
+
+    /** The lengths. */
+    private short lengths[];
+    
+    /** The values. */
+    private short values[];
+
+    /**
+     * Instantiates a new jPEG huffman table.
+     * 
+     * @param lengths the lengths
+     * @param values the values
+     * @param copy the copy
+     */
+    JPEGHuffmanTable(short[] lengths, short[] values, boolean copy) {
+        // Construction of standard tables without checks
+        // The third param is dummy
+        // Could be also used for copying of the existing tables
+        this.lengths = lengths;
+        this.values = values;
+    }
+
+    /**
+     * Instantiates a new JPEGHuffmanTable.
+     * 
+     * @param lengths the array of shorts lengths.
+     * @param values the array of shorts containing 
+     * the values in order of increasing code length.
+     */
+    public JPEGHuffmanTable(short[] lengths, short[] values) {
+        if (lengths == null) {
+            throw new IllegalArgumentException("lengths array is null!");
+        }
+        if (values == null) {
+            throw new IllegalArgumentException("values array is null!");
+        }
+        if (lengths.length > 16) { // According to the spec
+            throw new IllegalArgumentException("lengths array is too long!");
+        }
+        if (values.length > 256) { // According to the spec
+            throw new IllegalArgumentException("values array is too long");
+        }
+        for (short length : lengths) {
+            if (length < 0) {
+                throw new IllegalArgumentException("Values in lengths array must be non-negative.");
+            }
+        }
+        for (short value : values) {
+            if (value < 0) {
+                throw new IllegalArgumentException("Values in values array must be non-negative.");
+            }
+        }
+
+        checkHuffmanTable(lengths, values);
+
+        this.lengths = new short[lengths.length];
+        this.values = new short[values.length];
+        System.arraycopy(lengths, 0, this.lengths, 0, lengths.length);
+        System.arraycopy(values, 0, this.values, 0, values.length);
+    }
+
+    /**
+     * Gets an array of lengths in the Huffman table.
+     * 
+     * @return the array of short values representing the
+     * length values in the Huffman table.
+     */
+    public short[] getLengths() {
+        short newLengths[] = new short[lengths.length];
+        System.arraycopy(lengths, 0, newLengths, 0, lengths.length);
+        return newLengths;
+    }
+
+    /**
+     * Gets an array of values represented by increasing length of 
+     * their codes.
+     * 
+     * @return the array of values.
+     */
+    public short[] getValues() {
+        short newValues[] = new short[values.length];
+        System.arraycopy(values, 0, newValues, 0, values.length);
+        return newValues;
+    }
+
+    /**
+     * Check huffman table.
+     * 
+     * @param lengths the lengths
+     * @param values the values
+     */
+    private static void checkHuffmanTable(short[] lengths, short[] values) {
+        int numLeaves = 0;
+        int possibleLeaves = 2;
+        for (short length : lengths) {
+            numLeaves += length;
+            possibleLeaves -= length;
+            if (possibleLeaves < 0) {
+                throw new IllegalArgumentException("Invalid Huffman table provided, lengths are incorrect.");
+            }
+            possibleLeaves <<= 1;
+        }
+
+        if (values.length != numLeaves) {
+            throw new IllegalArgumentException("Invalid Huffman table provided, sum of lengths != values.");
+        }
+    }
+
+    /**
+     * Returns the string representation of this JPEGHuffmanTable object.
+     * 
+     * @return the string representation of this JPEGHuffmanTable object.
+     */
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("JPEGHuffmanTable:\nlengths:");
+        for (short length : lengths) {
+            sb.append(' ').append(length);
+        }
+
+        sb.append("\nvalues:");
+        for (short value : values) {
+            sb.append(' ').append(value);
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java b/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java
new file mode 100644
index 0000000..dd08d51
--- /dev/null
+++ b/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java
@@ -0,0 +1,116 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package javax.imageio.plugins.jpeg;
+
+import javax.imageio.ImageReadParam;
+
+/**
+ * The JPEGImageReadParam class provides functionality to set Huffman tables 
+ * and quantization tables when using the JPEG reader plug-in.
+ */
+public class JPEGImageReadParam extends ImageReadParam {
+    
+    /** The q tables. */
+    private JPEGQTable qTables[];
+    
+    /** The dc huffman tables. */
+    private JPEGHuffmanTable dcHuffmanTables[];
+    
+    /** The ac huffman tables. */
+    private JPEGHuffmanTable acHuffmanTables[];
+
+    /**
+     * Instantiates a new JPEGImageReadParam.
+     */
+    public JPEGImageReadParam() {
+    }
+
+    /**
+     * Returns true if tables are set, false otherwise.
+     * 
+     * @return true if tables are set, false otherwise.
+     */
+    public boolean areTablesSet() {
+        return qTables != null;
+    }
+
+    /**
+     * Sets the quantization and Huffman tables for using in 
+     * decoding streams.
+     * 
+     * @param qTables the quantization tables.
+     * @param DCHuffmanTables the standart DC Huffman tables.
+     * @param ACHuffmanTables the standart AC huffman tables.
+     */
+    public void setDecodeTables(
+            JPEGQTable[] qTables,
+            JPEGHuffmanTable[] DCHuffmanTables,
+            JPEGHuffmanTable[] ACHuffmanTables
+    ) {
+        if (qTables == null || DCHuffmanTables == null || ACHuffmanTables == null) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+        if(DCHuffmanTables.length != ACHuffmanTables.length) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+        if (qTables.length > 4 || DCHuffmanTables.length > 4) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+
+        // Do the shallow copy, it should be enough
+        this.qTables = qTables.clone();
+        dcHuffmanTables = DCHuffmanTables.clone();
+        acHuffmanTables = ACHuffmanTables.clone();
+    }
+
+    /**
+     * Unset all decoded tables.
+     */
+    public void unsetDecodeTables() {
+        qTables = null;
+        dcHuffmanTables = null;
+        acHuffmanTables = null;
+    }
+
+    /**
+     * Gets the quantization tables.
+     * 
+     * @return the quantization tables, or null.
+     */
+    public JPEGQTable[] getQTables() {
+        return qTables == null ? null : qTables.clone();
+    }
+
+    /**
+     * Gets the DC Huffman tables.
+     * 
+     * @return the DC Huffman tables which are set, or null.
+     */
+    public JPEGHuffmanTable[] getDCHuffmanTables() {
+        return dcHuffmanTables == null ? null : dcHuffmanTables.clone();
+    }
+
+    /**
+     * Gets the AC Huffman tables.
+     * 
+     * @return the AC Huffman tables which are set, or null.
+     */
+    public JPEGHuffmanTable[] getACHuffmanTables() {
+        return acHuffmanTables == null ? null : acHuffmanTables.clone();
+    }    
+}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java b/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
new file mode 100644
index 0000000..34a3cd9
--- /dev/null
+++ b/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
@@ -0,0 +1,193 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package javax.imageio.plugins.jpeg;
+
+import org.apache.harmony.x.imageio.plugins.jpeg.JPEGConsts;
+
+import javax.imageio.ImageWriteParam;
+import java.util.Locale;
+
+/**
+ * The JPEGImageWriteParam class allows to set JPEG Huffman tables 
+ * and quantization when using the JPEG writer plug-in.
+ */
+public class JPEGImageWriteParam extends ImageWriteParam {
+    
+    /** The Constant COMP_QUALITY_VALUES. */
+    private static final float[] COMP_QUALITY_VALUES = {0.05f, 0.75f, 0.95f};
+    
+    /** The Constant COMP_QUALITY_DESCRIPTIONS. */
+    private static final String[] COMP_QUALITY_DESCRIPTIONS = {
+            "Minimum useful",
+            "Visually lossless",
+            "Maximum useful"
+    };
+
+    /** The q tables. */
+    private JPEGQTable[] qTables;
+    
+    /** The dc huffman tables. */
+    private JPEGHuffmanTable[] dcHuffmanTables;
+    
+    /** The ac huffman tables. */
+    private JPEGHuffmanTable[] acHuffmanTables;
+
+    /** The optimize huffman tables. */
+    private boolean optimizeHuffmanTables;
+
+    /**
+     * Instantiates a new JPEGImageWriteParam object with 
+     * the specified Locale.
+     * 
+     * @param locale the Locale.
+     */
+    public JPEGImageWriteParam(Locale locale) {
+        super(locale);
+
+        canWriteProgressive = true;
+        progressiveMode = ImageWriteParam.MODE_DISABLED;
+
+        canWriteCompressed = true;
+        compressionTypes = new String[]{"JPEG"};
+        compressionType = compressionTypes[0]; 
+        compressionQuality = JPEGConsts.DEFAULT_JPEG_COMPRESSION_QUALITY;
+    }
+
+    /**
+     * Returns true if tables are set, false otherwise.
+     * 
+     * @return true if tables are set, false otherwise.
+     */
+    public boolean areTablesSet() {
+        return qTables != null;
+    }
+
+    /**
+     * Sets the quantization and Huffman tables for using in 
+     * encoding streams.
+     * 
+     * @param qTables the quantization tables.
+     * @param DCHuffmanTables the standart DC Huffman tables.
+     * @param ACHuffmanTables the standart AC huffman tables.
+     */
+    public void setEncodeTables(
+            JPEGQTable[] qTables,
+            JPEGHuffmanTable[] DCHuffmanTables,
+            JPEGHuffmanTable[] ACHuffmanTables
+    ) {
+        if (qTables == null || DCHuffmanTables == null || ACHuffmanTables == null) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+        if(DCHuffmanTables.length != ACHuffmanTables.length) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+        if (qTables.length > 4 || DCHuffmanTables.length > 4) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+
+        // Do the shallow copy, it should be enough
+        this.qTables = qTables.clone();
+        dcHuffmanTables = DCHuffmanTables.clone();
+        acHuffmanTables = ACHuffmanTables.clone();
+    }
+
+    /**
+     * Unset all encoded tables.
+     */
+    public void unsetEncodeTables() {
+        qTables = null;
+        dcHuffmanTables = null;
+        acHuffmanTables = null;
+    }
+
+    /**
+     * Gets the DC Huffman tables.
+     * 
+     * @return the DC Huffman tables which are set, or null.
+     */
+    public JPEGHuffmanTable[] getDCHuffmanTables() {
+        return dcHuffmanTables == null ? null : dcHuffmanTables.clone();
+    }
+
+    /**
+     * Gets the AC Huffman tables.
+     * 
+     * @return the AC Huffman tables which are set, or null.
+     */
+    public JPEGHuffmanTable[] getACHuffmanTables() {
+        return acHuffmanTables == null ? null : acHuffmanTables.clone();
+    }
+
+    /**
+     * Gets the quantization tables.
+     * 
+     * @return the quantization tables, or null.
+     */
+    public JPEGQTable[] getQTables() {
+        return qTables == null ? null : qTables.clone();
+    }
+
+    @Override
+    public String[] getCompressionQualityDescriptions() {
+        super.getCompressionQualityDescriptions();
+        return COMP_QUALITY_DESCRIPTIONS.clone();
+    }
+
+    @Override
+    public float[] getCompressionQualityValues() {
+        super.getCompressionQualityValues();
+        return COMP_QUALITY_VALUES.clone();
+    }
+
+    /**
+     * Sets the flag indicated that the writer will generate optimized 
+     * Huffman tables for the image as part of the writing process.
+     * 
+     * @param optimize the flag of optimizing huffman tables.
+     */
+    public void setOptimizeHuffmanTables(boolean optimize) {
+        optimizeHuffmanTables = optimize;
+    }
+
+    /**
+     * Returns true if the writer generates optimized Huffman tables,
+     * false otherwise.
+     * 
+     * @return the true if the writer generates optimized Huffman tables,
+     * false otherwise.
+     */
+    public boolean getOptimizeHuffmanTables() {
+        return optimizeHuffmanTables;
+    }
+
+    @Override
+    public boolean isCompressionLossless() {
+        if (getCompressionMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
+        }
+        return false;
+    }
+
+    @Override
+    public void unsetCompression() {
+        if (getCompressionMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
+        }
+        compressionQuality = JPEGConsts.DEFAULT_JPEG_COMPRESSION_QUALITY;
+    }
+}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGQTable.java b/awt/javax/imageio/plugins/jpeg/JPEGQTable.java
new file mode 100644
index 0000000..0c5b37e
--- /dev/null
+++ b/awt/javax/imageio/plugins/jpeg/JPEGQTable.java
@@ -0,0 +1,162 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.plugins.jpeg;
+
+/**
+ * The JPEGQTable class represents a single JPEG quantization table 
+ * and provides for the standard tables taken from the JPEG specification.
+ */
+public class JPEGQTable {
+
+    /** The Constant SIZE. */
+    private final static int SIZE = 64;
+    
+    /** The Constant BASELINE_MAX. */
+    private final static int BASELINE_MAX = 255;
+    
+    /** The Constant MAX. */
+    private final static int MAX = 32767;
+
+
+    /** The table. */
+    private int[] theTable;
+
+    /*
+     * K1 & K2 tables can be found in the JPEG format specification 
+     * at http://www.w3.org/Graphics/JPEG/itu-t81.pdf
+     */
+
+    /** The Constant K1LumTable. */
+    private static final int[] K1LumTable = new int[] {
+        16,  11,  10,  16,  24,  40,  51,  61,
+        12,  12,  14,  19,  26,  58,  60,  55,
+        14,  13,  16,  24,  40,  57,  69,  56,
+        14,  17,  22,  29,  51,  87,  80,  62,
+        18,  22,  37,  56,  68,  109, 103, 77,
+        24,  35,  55,  64,  81,  104, 113, 92,
+        49,  64,  78,  87,  103, 121, 120, 101,
+        72,  92,  95,  98,  112, 100, 103, 99
+    };
+
+    /** The Constant K2ChrTable. */
+    private static final int[] K2ChrTable = new int[] {
+        17,  18,  24,  47,  99,  99,  99,  99,
+        18,  21,  26,  66,  99,  99,  99,  99,
+        24,  26,  56,  99,  99,  99,  99,  99,
+        47,  66,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99
+    };
+
+    /** 
+     * The K1Luminance indicates standart table K.1 from JPEG
+     * specification and produces "good" quality output. 
+     */
+    public static final JPEGQTable K1Luminance = new JPEGQTable(K1LumTable);
+    
+    /** 
+     * The K1Div2Luminance indicates K.1 table from JPEG
+     * specification with all elements divided by 2 and produces
+     * "very good" quality output. 
+     */
+    public static final JPEGQTable K1Div2Luminance = K1Luminance.getScaledInstance(0.5f, true);
+    
+    /** 
+     * The K2Chrominance indicates K.2 table from JPEG
+     * specification and produces "good" quality output. 
+     */
+    public static final JPEGQTable K2Chrominance = new JPEGQTable(K2ChrTable);
+    
+    /** 
+     * The Constant K2Div2Chrominance indicates K.2 table from JPEG
+     * specification with all elements divided by 2 and produces
+     * "very good" quality output. 
+     */
+    public static final JPEGQTable K2Div2Chrominance = K2Chrominance.getScaledInstance(0.5f, true);;
+
+
+    /**
+     * Instantiates a new JPEGQTable from the array, which 
+     * should contain 64 elements in natural order.
+     * 
+     * @param table the quantization table.
+     */
+    public JPEGQTable(int[] table) {
+        if (table == null) {
+            throw new IllegalArgumentException("table should not be NULL");
+        }
+        if (table.length != SIZE) {
+            throw new IllegalArgumentException("illegal table size: " + table.length);
+        }
+        theTable = table.clone();
+    }
+
+    /**
+     * Gets the current quantization table as an array of int values.
+     * 
+     * @return the current quantization table as an array of int values.
+     */
+    public int[] getTable() {
+        return theTable.clone();
+    }
+
+    /**
+     * Gets the scaled instance as quantization table where 
+     * the values are multiplied by the scaleFactor and then clamped 
+     * if forceBaseline is true.
+     * 
+     * @param scaleFactor the scale factor of table.
+     * @param forceBaseline the force baseline flag, the values 
+     * should be clamped if true.
+     * 
+     * @return the new quantization table.
+     */
+    public JPEGQTable getScaledInstance(float scaleFactor, boolean forceBaseline) {
+        int table[] = new int[SIZE];
+
+        int maxValue = forceBaseline ? BASELINE_MAX : MAX;
+
+        for (int i = 0; i < theTable.length; i++) {
+            int rounded = Math.round(theTable[i] * scaleFactor);
+            if (rounded < 1) {
+                rounded = 1;
+            }
+            if (rounded > maxValue) {
+                rounded = maxValue;
+            }
+            table[i] = rounded;
+        }
+        return new JPEGQTable(table);
+    }
+
+    /**
+     * Returns the string representation of this JPEGQTable object.
+     * 
+     * @return the string representation of this JPEGQTable object.
+     */
+    @Override
+    public String toString() {
+        //-- TODO more informative info
+        return "JPEGQTable";
+    }
+}
diff --git a/awt/javax/imageio/spi/IIORegistry.java b/awt/javax/imageio/spi/IIORegistry.java
new file mode 100644
index 0000000..3c1c989
--- /dev/null
+++ b/awt/javax/imageio/spi/IIORegistry.java
@@ -0,0 +1,110 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+import java.util.Arrays;
+
+import org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReaderSpi;
+import org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriterSpi;
+import org.apache.harmony.x.imageio.plugins.png.PNGImageReaderSpi;
+import org.apache.harmony.x.imageio.plugins.png.PNGImageWriterSpi;
+import org.apache.harmony.x.imageio.spi.FileIISSpi;
+import org.apache.harmony.x.imageio.spi.FileIOSSpi;
+import org.apache.harmony.x.imageio.spi.InputStreamIISSpi;
+import org.apache.harmony.x.imageio.spi.OutputStreamIOSSpi;
+import org.apache.harmony.x.imageio.spi.RAFIISSpi;
+import org.apache.harmony.x.imageio.spi.RAFIOSSpi;
+
+/*
+ * @author Rustem V. Rafikov, Viskov Nikolay
+ * @version $Revision: 1.3 $
+ */
+
+/**
+ * The IIORegistry class registers service provider instances 
+ * (SPI). Service provider instances are recognized by specific 
+ * meta-information in the JAR files containing them. The JAR
+ * files with SPI classes are loaded from the application class 
+ * path. 
+ */
+public final class IIORegistry extends ServiceRegistry {
+
+    /** The instance. */
+    private static IIORegistry instance;
+
+    /** The Constant CATEGORIES. */
+    private static final Class[] CATEGORIES = new Class[] {
+        javax.imageio.spi.ImageWriterSpi.class,
+        javax.imageio.spi.ImageReaderSpi.class,
+        javax.imageio.spi.ImageInputStreamSpi.class,
+        //javax.imageio.spi.ImageTranscoderSpi.class,
+        javax.imageio.spi.ImageOutputStreamSpi.class
+    };
+
+    /**
+     * Instantiates a new iIO registry.
+     */
+    private IIORegistry() {
+        super(Arrays.<Class<?>>asList(CATEGORIES).iterator());
+        registerBuiltinSpis();
+        registerApplicationClasspathSpis();
+    }
+
+    /**
+     * Register builtin spis.
+     */
+    private void registerBuiltinSpis() {
+        registerServiceProvider(new JPEGImageWriterSpi());
+        registerServiceProvider(new JPEGImageReaderSpi());
+        registerServiceProvider(new PNGImageReaderSpi());
+        registerServiceProvider(new PNGImageWriterSpi());
+        registerServiceProvider(new FileIOSSpi());
+        registerServiceProvider(new FileIISSpi());
+        registerServiceProvider(new RAFIOSSpi());
+        registerServiceProvider(new RAFIISSpi());
+        registerServiceProvider(new OutputStreamIOSSpi());        
+        registerServiceProvider(new InputStreamIISSpi());
+        //-- TODO implement
+    }
+
+    /**
+     * Gets the default IIORegistry instance.
+     * 
+     * @return the default IIORegistry instance.
+     */
+    public static IIORegistry getDefaultInstance() {
+        // TODO implement own instance for each ThreadGroup (see also ThreadLocal)
+        synchronized (IIORegistry.class) {
+            if (instance == null) {
+                instance = new IIORegistry();
+            }
+            return instance;
+        }
+    }
+
+    /**
+     * Registers all service providers from the application class 
+     * path.
+     */
+    public void registerApplicationClasspathSpis() {
+        //-- TODO implement for non-builtin plugins
+    }
+}
diff --git a/awt/javax/imageio/spi/IIOServiceProvider.java b/awt/javax/imageio/spi/IIOServiceProvider.java
new file mode 100644
index 0000000..f5873bf
--- /dev/null
+++ b/awt/javax/imageio/spi/IIOServiceProvider.java
@@ -0,0 +1,97 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+import java.util.Locale;
+
+/**
+ * The IIOServiceProvider abstract class provides base functionality 
+ * for imageio service provider interfaces (SPIs). 
+ */
+public abstract class IIOServiceProvider implements RegisterableService {
+
+    /** The vendor name of this service provider. */
+    protected String vendorName;
+    
+    /** The version of this service provider. */
+    protected String version;
+
+    /**
+     * Instantiates a new IIOServiceProvider.
+     * 
+     * @param vendorName the vendor name of service provider.
+     * @param version the version of service provider.
+     */
+    public IIOServiceProvider(String vendorName, String version) {
+        if (vendorName == null) {
+            throw new NullPointerException("vendor name cannot be NULL");
+        }
+        if (version == null) {
+            throw new NullPointerException("version name cannot be NULL");
+        }
+        this.vendorName = vendorName;
+        this.version = version;
+    }
+
+    /**
+     * Instantiates a new IIOServiceProvider.
+     */
+    public IIOServiceProvider() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    public void onRegistration(ServiceRegistry registry, Class<?> category) {
+        // the default impl. does nothing
+    }
+
+    public void onDeregistration(ServiceRegistry registry, Class<?> category) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the vendor name of this service provider.
+     * 
+     * @return the vendor name of this service provider.
+     */
+    public String getVendorName() {
+        return vendorName;
+    }
+
+    /**
+     * Gets the version of this service provider.
+     * 
+     * @return the version of this service provider.
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    /**
+     * Gets a description of this service provider.   
+     * The result string should be localized for the specified 
+     * Locale.
+     * 
+     * @param locale the specified Locale.
+     * 
+     * @return the description of this service provider.
+     */
+    public abstract String getDescription(Locale locale);
+}
diff --git a/awt/javax/imageio/spi/ImageInputStreamSpi.java b/awt/javax/imageio/spi/ImageInputStreamSpi.java
new file mode 100644
index 0000000..47d210a
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageInputStreamSpi.java
@@ -0,0 +1,126 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+import java.io.File;
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+
+/**
+ * The ImageInputStreamSpi abstract class is a service provider 
+ * interface (SPI) for ImageInputStreams.  
+ */
+public abstract class ImageInputStreamSpi extends IIOServiceProvider implements
+        RegisterableService {
+    
+    /** The input class. */
+    protected Class<?> inputClass;
+
+    /**
+     * Instantiates a new ImageInputStreamSpi.
+     */
+    protected ImageInputStreamSpi() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Instantiates a new ImageInputStreamSpi.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param inputClass the input class.
+     */
+    public ImageInputStreamSpi(String vendorName, String version, Class<?> inputClass) {
+        super(vendorName, version);
+        this.inputClass = inputClass;
+    }
+
+    /**
+     * Gets an input Class object that represents class or 
+     * interface that must be implemented by an input source.
+     * 
+     * @return the input class.
+     */
+    public Class<?> getInputClass() {
+        return inputClass;
+    }
+
+    /**
+     * Returns true if the ImageInputStream can use a cache 
+     * file. If this method returns false, the value of the 
+     * useCache parameter of createInputStreamInstance will 
+     * be ignored. The default implementation returns false.
+     * 
+     * @return true if the ImageInputStream can use a cache 
+     * file, false otherwise.
+     */
+    public boolean canUseCacheFile() {
+        return false; //-- def
+    }
+
+    /**
+     * Returns true if the ImageInputStream implementation 
+     * requires the use of a cache file. The default implementation 
+     * returns false.
+     * 
+     * @return true if the ImageInputStream implementation 
+     * requires the use of a cache file, false otherwise.
+     */
+    public boolean needsCacheFile() {
+        return false; // def
+    }
+
+    /**
+     * Creates the ImageInputStream associated with this 
+     * service provider. The input object should
+     * be an instance of the class returned by th getInputClass 
+     * method. This method uses the specified directory
+     * for the cache file if the useCache parameter is true. 
+     * 
+     * @param input the input Object.
+     * @param useCache the flag indicating if a cache file 
+     * is needed or not.
+     * @param cacheDir the cache directory.
+     * 
+     * @return the ImageInputStream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract ImageInputStream createInputStreamInstance(Object input, boolean useCache,
+            File cacheDir) throws IOException;
+
+    /**
+     * Creates the ImageInputStream associated with this 
+     * service provider. The input object should
+     * be an instance of the class returned by getInputClass 
+     * method. This method uses the default system directory
+     * for the cache file, if it is needed. 
+     * 
+     * @param input the input Object.
+     * 
+     * @return the ImageInputStream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageInputStream createInputStreamInstance(Object input) throws IOException {
+        return createInputStreamInstance(input, true, null);
+    }
+}
diff --git a/awt/javax/imageio/spi/ImageOutputStreamSpi.java b/awt/javax/imageio/spi/ImageOutputStreamSpi.java
new file mode 100644
index 0000000..d45e24c
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageOutputStreamSpi.java
@@ -0,0 +1,126 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+import javax.imageio.stream.ImageOutputStream;
+import java.io.IOException;
+import java.io.File;
+
+/**
+ * The ImageOutputStreamSpi abstract class is a service provider 
+ * interface (SPI) for ImageOutputStreams. 
+ */
+public abstract class ImageOutputStreamSpi extends IIOServiceProvider implements
+        RegisterableService {
+    
+    /** The output class. */
+    protected Class<?> outputClass;
+
+    /**
+     * Instantiates a new ImageOutputStreamSpi.
+     */
+    protected ImageOutputStreamSpi() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Instantiates a new ImageOutputStreamSpi.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param outputClass the output class.
+     */
+    public ImageOutputStreamSpi(String vendorName, String version, Class<?> outputClass) {
+        super(vendorName, version);
+        this.outputClass = outputClass;
+    }
+
+    /**
+     * Gets an output Class object that represents the class or 
+     * interface that must be implemented by an output source.
+     * 
+     * @return the output class.
+     */
+    public Class<?> getOutputClass() {
+        return outputClass;
+    }
+
+    /**
+     * Returns true if the ImageOutputStream can use a cache 
+     * file. If this method returns false, the value of the 
+     * useCache parameter of createOutputStreamInstance will 
+     * be ignored. The default implementation returns false.
+     * 
+     * @return true if the ImageOutputStream can use a cache 
+     * file, false otherwise.
+     */
+    public boolean canUseCacheFile() {
+        return false; // def
+    }
+
+    /**
+     * Returns true if the ImageOutputStream  implementation 
+     * requires the use of a cache file. The default implementation 
+     * returns false.
+     * 
+     * @return true if the ImageOutputStream  implementation 
+     * requires the use of a cache file, false otherwise.
+     */
+    public boolean needsCacheFile() {
+        return false; // def
+    }
+
+    /**
+     * Creates the ImageOutputStream associated with this 
+     * service provider. The output object should
+     * be an instance of the class returned by getOutputClass 
+     * method. This method uses the default system directory
+     * for the cache file, if it is needed. 
+     * 
+     * @param output the output Object.
+     * 
+     * @return the ImageOutputStream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageOutputStream createOutputStreamInstance(Object output) throws IOException {
+        return createOutputStreamInstance(output, true, null);
+    }
+
+    /**
+     * Creates the ImageOutputStream associated with this 
+     * service provider. The output object should
+     * be an instance of the class returned by getInputClass 
+     * method. This method uses the specified directory
+     * for the cache file, if the useCache parameter is true. 
+     * 
+     * @param output the output Object.
+     * @param useCache the flag indicating if cache file 
+     * is needed or not.
+     * @param cacheDir the cache directory.
+     * 
+     * @return the ImageOutputStream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract ImageOutputStream createOutputStreamInstance(Object output,
+            boolean useCache, File cacheDir) throws IOException;
+}
diff --git a/awt/javax/imageio/spi/ImageReaderSpi.java b/awt/javax/imageio/spi/ImageReaderSpi.java
new file mode 100644
index 0000000..2e2484c
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageReaderSpi.java
@@ -0,0 +1,186 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.ImageReader;
+import java.io.IOException;
+
+/**
+ * The ImageReaderSpi abstract class is a service provider 
+ * interface (SPI) for ImageReaders.
+ */
+public abstract class ImageReaderSpi extends ImageReaderWriterSpi {
+
+    /** 
+     * The STANDARD_INPUT_TYPE contains ImageInputStream.class. 
+     */
+    public static final Class[] STANDARD_INPUT_TYPE = new Class[] {ImageInputStream.class};
+
+    /** The input types. */
+    protected Class[] inputTypes;
+    
+    /** The writer SPI names. */
+    protected String[] writerSpiNames;
+
+    /**
+     * Instantiates a new ImageReaderSpi.
+     */
+    protected ImageReaderSpi() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Instantiates a new ImageReaderSpi.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param names the format names.
+     * @param suffixes the array of strings representing the file suffixes. 
+     * @param MIMETypes the an array of strings representing MIME types.
+     * @param pluginClassName the plugin class name.
+     * @param inputTypes the input types.
+     * @param writerSpiNames the array of strings with class names of all 
+     * associated ImageWriters.
+     * @param supportsStandardStreamMetadataFormat the value indicating
+     * if stream metadata can be described by standart metadata format.
+     * @param nativeStreamMetadataFormatName the native stream metadata 
+     * format name, returned by getNativeStreamMetadataFormatName.
+     * @param nativeStreamMetadataFormatClassName the native stream 
+     * metadata format class name, returned by getNativeStreamMetadataFormat.
+     * @param extraStreamMetadataFormatNames the extra stream metadata 
+     * format names, returned by getExtraStreamMetadataFormatNames.
+     * @param extraStreamMetadataFormatClassNames the extra stream metadata 
+     * format class names, returned by getStreamMetadataFormat.
+     * @param supportsStandardImageMetadataFormat the value indicating
+     * if image metadata can be described by standart metadata format.
+     * @param nativeImageMetadataFormatName the native image metadata 
+     * format name, returned by getNativeImageMetadataFormatName.
+     * @param nativeImageMetadataFormatClassName the native image
+     * metadata format class name, returned by getNativeImageMetadataFormat.
+     * @param extraImageMetadataFormatNames the extra image metadata 
+     * format names, returned by getExtraImageMetadataFormatNames.
+     * @param extraImageMetadataFormatClassNames the extra image metadata 
+     * format class names, returned by getImageMetadataFormat.
+     */
+    public ImageReaderSpi(String vendorName, String version, String[] names, String[] suffixes,
+                             String[] MIMETypes, String pluginClassName,
+                             Class[] inputTypes, String[] writerSpiNames,
+                             boolean supportsStandardStreamMetadataFormat,
+                             String nativeStreamMetadataFormatName,
+                             String nativeStreamMetadataFormatClassName,
+                             String[] extraStreamMetadataFormatNames,
+                             String[] extraStreamMetadataFormatClassNames,
+                             boolean supportsStandardImageMetadataFormat,
+                             String nativeImageMetadataFormatName,
+                             String nativeImageMetadataFormatClassName,
+                             String[] extraImageMetadataFormatNames,
+                             String[] extraImageMetadataFormatClassNames) {
+        super(vendorName, version, names, suffixes, MIMETypes, pluginClassName,
+                supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName,
+                nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames,
+                extraStreamMetadataFormatClassNames, supportsStandardImageMetadataFormat,
+                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
+                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames);
+
+        if (inputTypes == null || inputTypes.length == 0) {
+            throw new NullPointerException("input types array cannot be NULL or empty");
+        }
+        this.inputTypes = inputTypes;
+        this.writerSpiNames = writerSpiNames;
+    }
+
+    /**
+     * Gets an array of Class objects whose types can be used 
+     * as input for this reader.
+     * 
+     * @return the input types.
+     */
+    public Class[] getInputTypes() {
+        return inputTypes;
+    }
+
+    /**
+     * Returns true if the format of source object is
+     * supported by this reader.
+     * 
+     * @param source the source object to be decoded 
+     * (for example an ImageInputStream).
+     * 
+     * @return true if the format of source object is
+     * supported by this reader, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract boolean canDecodeInput(Object source) throws IOException;
+
+    /**
+     * Returns an instance of the ImageReader implementation for
+     * this service provider.
+     * 
+     * @return the ImageReader.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageReader createReaderInstance() throws IOException {
+        return createReaderInstance(null);
+    }
+
+    /**
+     * Returns an instance of the ImageReader implementation for
+     * this service provider.
+     * 
+     * @param extension the a plugin specific extension object, or null.
+     * 
+     * @return the ImageReader.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract ImageReader createReaderInstance(Object extension) throws IOException;
+
+    /**
+     * Checks whether or not the specified ImageReader object 
+     * is an instance of the ImageReader associated with this 
+     * service provider or not.
+     * 
+     * @param reader the ImageReader.
+     * 
+     * @return true, if the specified ImageReader object 
+     * is an instance of the ImageReader associated with this 
+     * service provider, false otherwise.
+     */
+    public boolean isOwnReader(ImageReader reader) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an array of strings with names of the ImageWriterSpi 
+     * classes that support the internal metadata representation 
+     * used by the ImageReader of this service provider, or null if 
+     * there are no such ImageWriters.
+     * 
+     * @return an array of strings with names of the ImageWriterSpi 
+     * classes.
+     */
+    public String[] getImageWriterSpiNames() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+}
diff --git a/awt/javax/imageio/spi/ImageReaderWriterSpi.java b/awt/javax/imageio/spi/ImageReaderWriterSpi.java
new file mode 100644
index 0000000..b3c0f92
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageReaderWriterSpi.java
@@ -0,0 +1,315 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+import org.apache.harmony.x.imageio.metadata.IIOMetadataUtils;
+
+import javax.imageio.metadata.IIOMetadataFormat;
+
+/**
+ * The ImageReaderWriterSpi class is a superclass for the 
+ * ImageReaderSpi and ImageWriterSpi SPIs.
+ */
+public abstract class ImageReaderWriterSpi extends IIOServiceProvider
+        implements RegisterableService {
+
+    /** The names. */
+    protected String[] names;
+    
+    /** The suffixes. */
+    protected String[] suffixes;
+    
+    /** The MIME types. */
+    protected String[] MIMETypes;
+    
+    /** The plugin class name. */
+    protected String pluginClassName;
+    
+    /** Whether the reader/writer supports standard stream metadata format. */
+    protected boolean supportsStandardStreamMetadataFormat;
+    
+    /** The native stream metadata format name. */
+    protected String nativeStreamMetadataFormatName;
+    
+    /** The native stream metadata format class name. */
+    protected String nativeStreamMetadataFormatClassName;
+    
+    /** The extra stream metadata format names. */
+    protected String[] extraStreamMetadataFormatNames;
+    
+    /** The extra stream metadata format class names. */
+    protected String[] extraStreamMetadataFormatClassNames;
+    
+    /** Whether the reader/writer supports standard image metadata format. */
+    protected boolean supportsStandardImageMetadataFormat;
+    
+    /** The native image metadata format name. */
+    protected String nativeImageMetadataFormatName;
+    
+    /** The native image metadata format class name. */
+    protected String nativeImageMetadataFormatClassName;
+    
+    /** The extra image metadata format names. */
+    protected String[] extraImageMetadataFormatNames;
+    
+    /** The extra image metadata format class names. */
+    protected String[] extraImageMetadataFormatClassNames;
+
+    /**
+     * Instantiates a new ImageReaderWriterSpi.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param names the format names.
+     * @param suffixes the array of strings representing the file suffixes. 
+     * @param MIMETypes the an array of strings representing MIME types.
+     * @param pluginClassName the plugin class name.
+     * @param supportsStandardStreamMetadataFormat the value indicating
+     * if stream metadata can be described by standart metadata format.
+     * @param nativeStreamMetadataFormatName the native stream metadata 
+     * format name, returned by getNativeStreamMetadataFormatName.
+     * @param nativeStreamMetadataFormatClassName the native stream 
+     * metadata format class name, returned by getNativeStreamMetadataFormat.
+     * @param extraStreamMetadataFormatNames the extra stream metadata 
+     * format names, returned by getExtraStreamMetadataFormatNames.
+     * @param extraStreamMetadataFormatClassNames the extra stream metadata 
+     * format class names, returned by getStreamMetadataFormat.
+     * @param supportsStandardImageMetadataFormat the value indicating
+     * if image metadata can be described by standard metadata format.
+     * @param nativeImageMetadataFormatName the native image metadata 
+     * format name, returned by getNativeImageMetadataFormatName.
+     * @param nativeImageMetadataFormatClassName the native image
+     * metadata format class name, returned by getNativeImageMetadataFormat.
+     * @param extraImageMetadataFormatNames the extra image metadata 
+     * format names, returned by getExtraImageMetadataFormatNames.
+     * @param extraImageMetadataFormatClassNames the extra image metadata 
+     * format class names, returned by getImageMetadataFormat.
+     */
+    public ImageReaderWriterSpi(String vendorName, String version, String[] names,
+                                String[] suffixes, String[] MIMETypes,
+                                String pluginClassName,
+                                boolean supportsStandardStreamMetadataFormat,
+                                String nativeStreamMetadataFormatName,
+                                String nativeStreamMetadataFormatClassName,
+                                String[] extraStreamMetadataFormatNames,
+                                String[] extraStreamMetadataFormatClassNames,
+                                boolean supportsStandardImageMetadataFormat,
+                                String nativeImageMetadataFormatName,
+                                String nativeImageMetadataFormatClassName,
+                                String[] extraImageMetadataFormatNames,
+                                String[] extraImageMetadataFormatClassNames) {
+        super(vendorName, version);
+
+        if (names == null || names.length == 0) {
+            throw new NullPointerException("format names array cannot be NULL or empty");
+        }
+
+        if (pluginClassName == null) {
+            throw new NullPointerException("Plugin class name cannot be NULL");
+        }
+
+        // We clone all the arrays to be consistent with the fact that
+        // some methods of this class must return clones of the arrays
+        // as it is stated in the spec.
+        this.names = names.clone();
+        this.suffixes = suffixes == null ? null : suffixes.clone();
+        this.MIMETypes = MIMETypes == null ? null : MIMETypes.clone();
+        this.pluginClassName = pluginClassName;
+        this.supportsStandardStreamMetadataFormat = supportsStandardStreamMetadataFormat;
+        this.nativeStreamMetadataFormatName = nativeStreamMetadataFormatName;
+        this.nativeStreamMetadataFormatClassName = nativeStreamMetadataFormatClassName;
+
+        this.extraStreamMetadataFormatNames =
+                extraStreamMetadataFormatNames == null ?
+                null : extraStreamMetadataFormatNames.clone();
+
+        this.extraStreamMetadataFormatClassNames =
+                extraStreamMetadataFormatClassNames == null ?
+                null : extraStreamMetadataFormatClassNames.clone();
+
+        this.supportsStandardImageMetadataFormat = supportsStandardImageMetadataFormat;
+        this.nativeImageMetadataFormatName = nativeImageMetadataFormatName;
+        this.nativeImageMetadataFormatClassName = nativeImageMetadataFormatClassName;
+
+        this.extraImageMetadataFormatNames =
+                extraImageMetadataFormatNames == null ?
+                null : extraImageMetadataFormatNames.clone();
+
+        this.extraImageMetadataFormatClassNames =
+                extraImageMetadataFormatClassNames == null ?
+                null : extraImageMetadataFormatClassNames.clone();
+    }
+
+    /**
+     * Instantiates a new ImageReaderWriterSpi.
+     */
+    public ImageReaderWriterSpi() {}
+
+    /**
+     * Gets an array of strings representing names of the formats 
+     * that can be used by the ImageReader 
+     * or ImageWriter implementation associated with this service 
+     * provider. 
+     * 
+     * @return an array of supported format names.
+     */
+    public String[] getFormatNames() {
+        return names.clone();
+    }
+
+    /**
+     * Gets an array of strings representing file suffixes 
+     * associated with the formats that can be used by the 
+     * ImageReader or ImageWriter implementation of this
+     * service provider.
+     * 
+     * @return an array of file suffixes.
+     */
+    public String[] getFileSuffixes() {
+        return suffixes == null ? null : suffixes.clone();
+    }
+
+    /**
+     * Gets an array of strings with the names of 
+     * additional formats of the image metadata objects 
+     * produced or consumed by this plug-in.
+     * 
+     * @return the array of extra image metadata format names.
+     */
+    public String[] getExtraImageMetadataFormatNames() {
+        return extraImageMetadataFormatNames == null ? null : extraImageMetadataFormatNames.clone();
+    }
+
+    /**
+     * Gets an array of strings with the names of 
+     * additional formats of the stream metadata objects 
+     * produced or consumed by this plug-in.
+     * 
+     * @return the array of extra stream metadata format names.
+     */
+    public String[] getExtraStreamMetadataFormatNames() {
+        return extraStreamMetadataFormatNames == null ? null : extraStreamMetadataFormatNames.clone();
+    }
+
+    /**
+     * Gets an IIOMetadataFormat object for the specified image 
+     * metadata format name. 
+     * 
+     * @param formatName the format name.
+     * 
+     * @return the IIOMetadataFormat, or null.
+     */
+    public IIOMetadataFormat getImageMetadataFormat(String formatName) {
+        return IIOMetadataUtils.instantiateMetadataFormat(
+                formatName, supportsStandardImageMetadataFormat,
+                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
+                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames
+        );
+    }
+
+    /**
+     * Gets an IIOMetadataFormat object for the specified stream 
+     * metadata format name. 
+     * 
+     * @param formatName the format name.
+     * 
+     * @return the IIOMetadataFormat, or null.
+     */
+    public IIOMetadataFormat getStreamMetadataFormat(String formatName) {
+        return IIOMetadataUtils.instantiateMetadataFormat(
+                formatName, supportsStandardStreamMetadataFormat,
+                nativeStreamMetadataFormatName, nativeStreamMetadataFormatClassName,
+                extraStreamMetadataFormatNames, extraStreamMetadataFormatClassNames
+        );
+    }
+
+    /**
+     * Gets an array of strings representing the MIME types 
+     * of the formats that are supported by the 
+     * ImageReader or ImageWriter implementation of this 
+     * service provider.
+     * 
+     * @return the array MIME types.
+     */
+    public String[] getMIMETypes() {
+        return MIMETypes == null ? null : MIMETypes.clone();
+    }
+
+    /**
+     * Gets the name of the native image metadata format for 
+     * this reader/writer, which allows for lossless encoding
+     * or decoding of the image metadata with the format.
+     * 
+     * @return the string with native image metadata format name, 
+     * or null.
+     */
+    public String getNativeImageMetadataFormatName() {
+        return nativeImageMetadataFormatName;
+    }
+
+    /**
+     * Gets the name of the native stream metadata format for 
+     * this reader/writer, which allows for lossless encoding
+     * or decoding of the stream metadata with the format.
+     * 
+     * @return the string with native stream metadata format name, 
+     * or null.
+     */
+    public String getNativeStreamMetadataFormatName() {
+        return nativeStreamMetadataFormatName;
+    }
+
+    /**
+     * Gets the class name of the ImageReader 
+     * or ImageWriter associated with this service provider.
+     * 
+     * @return the class name.
+     */
+    public String getPluginClassName() {
+        return pluginClassName;
+    }
+
+    /**
+     * Checks if the standard metadata format is supported 
+     * by the getAsTree and setFromTree methods for the 
+     * image metadata objects produced or consumed by this 
+     * reader or writer.
+     * 
+     * @return true, if standard image metadata format is 
+     * supported, false otherwise.
+     */
+    public boolean isStandardImageMetadataFormatSupported() {
+        return supportsStandardImageMetadataFormat;
+    }
+
+    /**
+     * Checks if the standard metadata format is supported 
+     * by the getAsTree and setFromTree methods for the 
+     * stream metadata objects produced or consumed by this 
+     * reader or writer.
+     * 
+     * @return true, if standard stream metadata format is 
+     * supported, false otherwise.
+     */
+    public boolean isStandardStreamMetadataFormatSupported() {
+        return supportsStandardStreamMetadataFormat;
+    }
+}
diff --git a/awt/javax/imageio/spi/ImageTranscoderSpi.java b/awt/javax/imageio/spi/ImageTranscoderSpi.java
new file mode 100644
index 0000000..68c4024
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageTranscoderSpi.java
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+import javax.imageio.ImageTranscoder;
+
+/**
+ * The ImageTranscoderSpi class is a service provider interface (SPI) 
+ * for ImageTranscoders.
+ */
+public abstract class ImageTranscoderSpi extends IIOServiceProvider
+        implements RegisterableService {
+
+    /**
+     * Instantiates a new ImageTranscoderSpi.
+     */
+    protected ImageTranscoderSpi() {
+    }
+
+    /**
+     * Instantiates a new ImageTranscoderSpi with the specified
+     * vendor name and version.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     */
+    public ImageTranscoderSpi(String vendorName, String version) {
+        super(vendorName, version);
+    }
+
+    /**
+     * Gets the class name of an ImageReaderSpi that 
+     * produces IIOMetadata objects that can be used as 
+     * input to this transcoder.
+     * 
+     * @return the class name of an ImageReaderSpi.
+     */
+    public abstract String getReaderServiceProviderName();
+
+    /**
+     * Gets the class name of an ImageWriterSpi that 
+     * produces IIOMetadata objects that can be used as 
+     * input to this transcoder.
+     * 
+     * @return the class name of an ImageWriterSpi.
+     */
+    public abstract String getWriterServiceProviderName();
+
+    /**
+     * Creates an instance of the ImageTranscoder associated 
+     * with this service provider.
+     * 
+     * @return the ImageTranscoder instance.
+     */
+    public abstract ImageTranscoder createTranscoderInstance();
+}
diff --git a/awt/javax/imageio/spi/ImageWriterSpi.java b/awt/javax/imageio/spi/ImageWriterSpi.java
new file mode 100644
index 0000000..979ef77
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageWriterSpi.java
@@ -0,0 +1,209 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+
+/**
+ * The ImageWriterSpi abstract class is a service provider 
+ * interface (SPI) for ImageWriters.
+ */
+public abstract class ImageWriterSpi extends ImageReaderWriterSpi {
+
+    /** The STANDARD_OUTPUT_TYPE contains ImageInputStream.class. */
+    public static final Class[] STANDARD_OUTPUT_TYPE = new Class[] {ImageInputStream.class};
+
+    /** The output types. */
+    protected Class[] outputTypes;
+    
+    /** The reader spi names. */
+    protected String[] readerSpiNames;
+
+    /**
+     * Instantiates a new ImageWriterSpi.
+     */
+    protected ImageWriterSpi() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Instantiates a new ImageWriterSpi with the specified parameters.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param names the format names.
+     * @param suffixes the array of strings representing the file suffixes. 
+     * @param MIMETypes the an array of strings representing MIME types.
+     * @param pluginClassName the plugin class name.
+     * @param outputTypes the output types.
+     * @param readerSpiNames the array of strings with class names of all 
+     * associated ImageReaders.
+     * @param supportsStandardStreamMetadataFormat the value indicating
+     * if stream metadata can be described by standard metadata format.
+     * @param nativeStreamMetadataFormatName the native stream metadata 
+     * format name, returned by getNativeStreamMetadataFormatName.
+     * @param nativeStreamMetadataFormatClassName the native stream 
+     * metadata format class name, returned by getNativeStreamMetadataFormat.
+     * @param extraStreamMetadataFormatNames the extra stream metadata 
+     * format names, returned by getExtraStreamMetadataFormatNames.
+     * @param extraStreamMetadataFormatClassNames the extra stream metadata 
+     * format class names, returned by getStreamMetadataFormat.
+     * @param supportsStandardImageMetadataFormat the value indicating
+     * if image metadata can be described by standard metadata format.
+     * @param nativeImageMetadataFormatName the native image metadata 
+     * format name, returned by getNativeImageMetadataFormatName.
+     * @param nativeImageMetadataFormatClassName the native image
+     * metadata format class name, returned by getNativeImageMetadataFormat.
+     * @param extraImageMetadataFormatNames the extra image metadata 
+     * format names, returned by getExtraImageMetadataFormatNames.
+     * @param extraImageMetadataFormatClassNames the extra image metadata 
+     * format class names, returned by getImageMetadataFormat.
+     */
+    public ImageWriterSpi(String vendorName, String version, String[] names,
+                             String[] suffixes, String[] MIMETypes,
+                             String pluginClassName,
+                             Class[] outputTypes, String[] readerSpiNames,
+                             boolean supportsStandardStreamMetadataFormat,
+                             String nativeStreamMetadataFormatName,
+                             String nativeStreamMetadataFormatClassName,
+                             String[] extraStreamMetadataFormatNames,
+                             String[] extraStreamMetadataFormatClassNames,
+                             boolean supportsStandardImageMetadataFormat,
+                             String nativeImageMetadataFormatName,
+                             String nativeImageMetadataFormatClassName,
+                             String[] extraImageMetadataFormatNames,
+                             String[] extraImageMetadataFormatClassNames) {
+        super(vendorName, version, names, suffixes, MIMETypes, pluginClassName,
+                supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName,
+                nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames,
+                extraStreamMetadataFormatClassNames, supportsStandardImageMetadataFormat,
+                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
+                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames);
+
+        if (outputTypes == null || outputTypes.length == 0) {
+            throw new NullPointerException("output types array cannot be NULL or empty");
+        }
+
+        this.outputTypes = outputTypes;
+        this.readerSpiNames = readerSpiNames;
+    }
+
+    /**
+     * Returns true if the format of the writer's output is lossless. 
+     * The default implementation returns true.
+     * 
+     * @return true, if a format is lossless, false otherwise.
+     */
+    public boolean isFormatLossless() {
+        return true;
+    }
+
+    /**
+     * Gets an array of Class objects whose types 
+     * can be used as output for this writer.
+     * 
+     * @return the output types.
+     */
+    public Class[] getOutputTypes() {
+        return outputTypes;
+    }
+
+    /**
+     * Checks whether or not the ImageWriter implementation associated 
+     * with this service provider can encode an image with 
+     * the specified type.
+     * 
+     * @param type the ImageTypeSpecifier.
+     * 
+     * @return true, if an image with the specified type can be
+     * encoded, false otherwise. 
+     */
+    public abstract boolean canEncodeImage(ImageTypeSpecifier type);
+
+    /**
+     * Checks whether or not the ImageWriter implementation associated 
+     * with this service provider can encode the specified RenderedImage.
+     * 
+     * @param im the RenderedImage.
+     * 
+     * @return true, if RenderedImage can be encoded, 
+     * false otherwise. 
+     */
+    public boolean canEncodeImage(RenderedImage im) {
+        return canEncodeImage(ImageTypeSpecifier.createFromRenderedImage(im));
+    }
+
+    /**
+     * Returns an instance of the ImageWriter implementation for
+     * this service provider.
+     * 
+     * @return the ImageWriter.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageWriter createWriterInstance() throws IOException {
+        return createWriterInstance(null);
+    }
+
+    /**
+     * Returns an instance of the ImageWriter implementation for
+     * this service provider.
+     * 
+     * @param extension the a plugin specific extension object, or null.
+     * 
+     * @return the ImageWriter.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract ImageWriter createWriterInstance(Object extension) throws IOException;
+
+    /**
+     * Checks whether or not the specified ImageWriter object 
+     * is an instance of the ImageWriter associated with this 
+     * service provider or not.
+     * 
+     * @param writer the ImageWriter.
+     * 
+     * @return true, if the specified ImageWriter object 
+     * is an instance of the ImageWriter associated with this 
+     * service provider, false otherwise.
+     */
+    public boolean isOwnWriter(ImageWriter writer) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an array of strings with names of the ImageReaderSpi 
+     * classes that support the internal metadata representation 
+     * used by the ImageWriter of this service provider, or null if 
+     * there are no such ImageReaders.
+     * 
+     * @return an array of strings with names of the ImageWriterSpi 
+     * classes.
+     */
+    public String[] getImageReaderSpiNames() {
+        return readerSpiNames;
+    }
+}
diff --git a/awt/javax/imageio/spi/RegisterableService.java b/awt/javax/imageio/spi/RegisterableService.java
new file mode 100644
index 0000000..b50754e
--- /dev/null
+++ b/awt/javax/imageio/spi/RegisterableService.java
@@ -0,0 +1,50 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+/**
+ * The RegisterableService interface provides service provider 
+ * objects that can be registered by a ServiceRegistry, and 
+ * notifications that registration and deregistration have been
+ * performed.
+ */
+public interface RegisterableService {
+    
+    /**
+     * This method is called when the object which implements this
+     * interface is registered to the specified category of the 
+     * specified registry.
+     * 
+     * @param registry the ServiceRegistry to be registered.
+     * @param category the class representing a category.
+     */
+    void onRegistration(ServiceRegistry registry, Class<?> category);
+    
+    /**
+     * This method is called when the object which implements this
+     * interface is deregistered to the specified category of the 
+     * specified registry.
+     * 
+     * @param registry the ServiceRegistry to be registered.
+     * @param category the class representing a category.
+     */
+    void onDeregistration(ServiceRegistry registry, Class<?> category);
+}
diff --git a/awt/javax/imageio/spi/ServiceRegistry.java b/awt/javax/imageio/spi/ServiceRegistry.java
new file mode 100644
index 0000000..1a18b02
--- /dev/null
+++ b/awt/javax/imageio/spi/ServiceRegistry.java
@@ -0,0 +1,516 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.spi;
+
+import java.util.*;
+import java.util.Map.Entry;
+
+/**
+ * The ServiceRegistry class provides ability to register, 
+ * deregister, look up and obtain service provider instances (SPIs).
+ * A service means a set of interfaces and classes, and a service 
+ * provider is an implementation of a service. Service providers can 
+ * be associated with one or more categories. Each category is defined 
+ * by a class or interface. Only a single instance of a each class is 
+ * allowed to be registered as a category. 
+ */
+public class ServiceRegistry {
+
+    /** The categories. */
+    CategoriesMap categories = new CategoriesMap(this);
+
+    /**
+     * Instantiates a new ServiceRegistry with the specified categories.
+     * 
+     * @param categoriesIterator an Iterator of Class objects 
+     * for defining of categories.
+     */
+    public ServiceRegistry(Iterator<Class<?>> categoriesIterator) {
+        if (null == categoriesIterator) {
+            throw new IllegalArgumentException("categories iterator should not be NULL");
+        }
+        while(categoriesIterator.hasNext()) {
+            Class<?> c =  categoriesIterator.next();
+            categories.addCategory(c);
+        }
+    }
+
+    /**
+     * Looks up and instantiates the available providers of this service using 
+     * the specified class loader.
+     * 
+     * @param providerClass the Class object of the provider to be looked up.
+     * @param loader the class loader to be used.
+     * 
+     * @return the iterator of providers objects for this service.
+     */
+    public static <T> Iterator<T> lookupProviders(Class<T> providerClass, ClassLoader loader) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Looks up and instantiates the available providers of this service using 
+     * the context class loader.
+     * 
+     * @param providerClass the Class object of the provider to be looked up.
+     * 
+     * @return the iterator of providers objects for this service.
+     */
+    public static <T> Iterator<T> lookupProviders(Class<T> providerClass) {
+        return lookupProviders(providerClass, Thread.currentThread().getContextClassLoader());
+    }
+
+    /**
+     * Registers the specified service provider object in the
+     * specified categories.
+     * 
+     * @param provider the specified provider to be registered.
+     * @param category the category.
+     * 
+     * @return true if no provider of the same class is registered 
+     * in this category, false otherwise.
+     */
+    public <T> boolean registerServiceProvider(T provider, Class<T> category) {
+        return categories.addProvider(provider, category);
+    }
+
+    /**
+     * Registers a list of service providers.
+     * 
+     * @param providers the list of service providers.
+     */
+    public void registerServiceProviders(Iterator<?> providers) {
+        for (Iterator<?> iterator = providers; iterator.hasNext();) {
+            categories.addProvider(iterator.next(), null);
+        }
+    }
+
+    /**
+     * Registers the specified service provider object in all
+     * categories.
+     * 
+     * @param provider the service provider.
+     */
+    public void registerServiceProvider(Object provider) {
+        categories.addProvider(provider, null);
+    }
+
+    /**
+     * Deregisters the specifies service provider from the
+     * specified category.
+     * 
+     * @param provider the service provider to be deregistered.
+     * @param category the specified category.
+     * 
+     * @return true if the provider was already registered 
+     * in the specified category, false otherwise.
+     */
+    public <T> boolean deregisterServiceProvider(T provider, Class<T> category) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Deregisters the specified service provider from all
+     * categories.
+     * 
+     * @param provider the specified service provider.
+     */
+    public void deregisterServiceProvider(Object provider) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an Iterator of registered service providers
+     * in the specified category which satisfy the specified Filter. 
+     * The useOrdering parameter indicates whether the iterator will 
+     * return all of the server provider objects in a set order. 
+     * 
+     * @param category the specified category.
+     * @param filter the specified filter.
+     * @param useOrdering the flag indicating that providers are ordered
+     * in the returned Iterator.
+     * 
+     * @return the iterator of registered service providers.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> Iterator<T> getServiceProviders(Class<T> category, Filter filter, boolean useOrdering) {
+        return new FilteredIterator<T>(filter, (Iterator<T>)categories.getProviders(category, useOrdering));
+    }
+
+    /**
+     * Gets an Iterator of all registered service providers
+     * in the specified category. The useOrdering parameter
+     * indicates whether the iterator will return all of the server 
+     * provider objects in a set order. 
+     * 
+     * @param category the specified category.
+     * @param useOrdering the flag indicating that providers are ordered
+     * in the returned Iterator.
+     * 
+     * @return the Iterator of service providers.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> Iterator<T> getServiceProviders(Class<T> category, boolean useOrdering) {
+        return (Iterator<T>)categories.getProviders(category, useOrdering);
+    }
+
+    /**
+     * Gets the registered service provider object that has the 
+     * specified class type.
+     * 
+     * @param providerClass the specified provider class.
+     * 
+     * @return the service provider object.
+     */
+    public <T> T getServiceProviderByClass(Class<T> providerClass) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Sets an ordering between two service provider objects 
+     * within the specified category. 
+     * 
+     * @param category the specified category.
+     * @param firstProvider the first provider.
+     * @param secondProvider the second provider.
+     * 
+     * @return true if a previously unset order was set.
+     */
+    public <T> boolean setOrdering(Class<T> category, T firstProvider, T secondProvider) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Unsets an ordering between two service provider objects 
+     * within the specified category.
+     * 
+     * @param category the specified category.
+     * @param firstProvider the first provider.
+     * @param secondProvider the second provider.
+     * 
+     * @return true if a previously unset order was removed.
+     */
+    public <T> boolean unsetOrdering(Class<T> category, T firstProvider, T secondProvider) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Deregisters all providers from the specified category.
+     * 
+     * @param category the specified category.
+     */
+    public void deregisterAll(Class<?> category) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Deregister all providers from all categories.
+     */
+    public void deregisterAll() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Finalizes this object. 
+     * 
+     * @throws Throwable throws if an error occurs during 
+     * finalization.
+     */
+    @Override
+    public void finalize() throws Throwable {
+        //TODO uncomment when deregisterAll is implemented
+        //deregisterAll();
+    }
+
+    /**
+     * Checks whether the specified provider has been already registered.
+     * 
+     * @param provider the provider to be checked.
+     * 
+     * @return true, if the specified provider has been already registered,
+     * false otherwise.
+     */
+    public boolean contains(Object provider) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an iterator of Class objects representing the current 
+     * categories.
+     * 
+     * @return the Iterator of Class objects.
+     */
+    public Iterator<Class<?>> getCategories() {
+        return categories.list();
+    }
+
+    /**
+     * The ServiceRegistry.Filter interface is used by 
+     * ServiceRegistry.getServiceProviders to filter providers according
+     * to the specified criterion. 
+     */
+    public static interface Filter {
+        
+        /**
+         * Returns true if the specified provider satisfies the 
+         * criterion of this Filter.
+         * 
+         * @param provider the provider.
+         * 
+         * @return true if the specified provider satisfies the 
+         * criterion of this Filter, false otherwise.
+         */
+        boolean filter(Object provider);
+    }
+
+    /**
+     * The Class CategoriesMap.
+     */
+    private static class CategoriesMap {
+        
+        /** The categories. */
+        Map<Class<?>, ProvidersMap> categories = new HashMap<Class<?>, ProvidersMap>();
+
+        /** The registry. */
+        ServiceRegistry registry;
+
+        /**
+         * Instantiates a new categories map.
+         * 
+         * @param registry the registry
+         */
+        public CategoriesMap(ServiceRegistry registry) {
+            this.registry = registry;
+        }
+
+        //-- TODO: useOrdering
+        /**
+         * Gets the providers.
+         * 
+         * @param category the category
+         * @param useOrdering the use ordering
+         * 
+         * @return the providers
+         */
+        Iterator<?> getProviders(Class<?> category, boolean useOrdering) {
+            ProvidersMap providers = categories.get(category);
+            if (null == providers) {
+                throw new IllegalArgumentException("Unknown category: " + category);
+            }
+            return providers.getProviders(useOrdering);
+        }
+
+        /**
+         * List.
+         * 
+         * @return the iterator< class<?>>
+         */
+        Iterator<Class<?>> list() {
+            return categories.keySet().iterator();
+        }
+
+        /**
+         * Adds the category.
+         * 
+         * @param category the category
+         */
+        void addCategory(Class<?> category) {
+            categories.put(category, new ProvidersMap());
+        }
+
+        /**
+         * Adds a provider to the category. If <code>category</code> is
+         * <code>null</code> then the provider will be added to all categories
+         * which the provider is assignable from.
+         * 
+         * @param provider provider to add
+         * @param category category to add provider to
+         * 
+         * @return if there were such provider in some category
+         */
+        boolean addProvider(Object provider, Class<?> category) {
+            if (provider == null) {
+                throw new IllegalArgumentException("provider should be != NULL");
+            }
+
+            boolean rt;
+            if (category == null) {
+                rt = findAndAdd(provider);
+            } else {
+                rt  = addToNamed(provider, category);
+            }
+
+            if (provider instanceof RegisterableService) {
+                ((RegisterableService) provider).onRegistration(registry, category);
+            }
+
+            return rt;
+        }
+
+        /**
+         * Adds the to named.
+         * 
+         * @param provider the provider
+         * @param category the category
+         * 
+         * @return true, if successful
+         */
+        private boolean addToNamed(Object provider, Class<?> category) {
+            Object obj = categories.get(category);
+
+            if (null == obj) {
+                throw new IllegalArgumentException("Unknown category: " + category);
+            }
+
+            return ((ProvidersMap) obj).addProvider(provider);
+        }
+
+        /**
+         * Find and add.
+         * 
+         * @param provider the provider
+         * 
+         * @return true, if successful
+         */
+        private boolean findAndAdd(Object provider) {
+            boolean rt = false;
+            for (Entry<Class<?>, ProvidersMap> e : categories.entrySet()) {
+                if (e.getKey().isAssignableFrom(provider.getClass())) {
+                    rt |= e.getValue().addProvider(provider);
+                }
+            }
+            return rt;
+        }
+    }
+
+    /**
+     * The Class ProvidersMap.
+     */
+    private static class ProvidersMap {
+        //-- TODO: providers ordering support
+
+        /** The providers. */
+        Map<Class<?>, Object> providers = new HashMap<Class<?>, Object>();
+
+        /**
+         * Adds the provider.
+         * 
+         * @param provider the provider
+         * 
+         * @return true, if successful
+         */
+        boolean addProvider(Object provider) {
+            return providers.put(provider.getClass(), provider) != null;
+        }
+
+        /**
+         * Gets the provider classes.
+         * 
+         * @return the provider classes
+         */
+        Iterator<Class<?>> getProviderClasses() {
+            return providers.keySet().iterator();
+        }
+
+        //-- TODO ordering
+        /**
+         * Gets the providers.
+         * 
+         * @param userOrdering the user ordering
+         * 
+         * @return the providers
+         */
+        Iterator<?> getProviders(boolean userOrdering) {
+            return providers.values().iterator();
+        }
+    }
+
+    /**
+     * The Class FilteredIterator.
+     */
+    private static class FilteredIterator<E> implements Iterator<E> {
+
+        /** The filter. */
+        private Filter filter;
+        
+        /** The backend. */
+        private Iterator<E> backend;
+        
+        /** The next obj. */
+        private E nextObj;
+
+        /**
+         * Instantiates a new filtered iterator.
+         * 
+         * @param filter the filter
+         * @param backend the backend
+         */
+        public FilteredIterator(Filter filter, Iterator<E> backend) {
+            this.filter = filter;
+            this.backend = backend;
+            findNext();
+        }
+
+        /**
+         * Next.
+         * 
+         * @return the e
+         */
+        public E next() {
+            if (nextObj == null) {
+                throw new NoSuchElementException();
+            }
+            E tmp = nextObj;
+            findNext();
+            return tmp;
+        }
+
+        /**
+         * Checks for next.
+         * 
+         * @return true, if successful
+         */
+        public boolean hasNext() {
+            return nextObj != null;
+        }
+
+        /**
+         * Removes the.
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Sets nextObj to a next provider matching the criterion given by the filter.
+         */
+        private void findNext() {
+            nextObj = null;
+            while (backend.hasNext()) {
+                E o = backend.next();
+                if (filter.filter(o)) {
+                    nextObj = o;
+                    return;
+                }
+            }
+        }
+    }
+}
diff --git a/awt/javax/imageio/stream/FileCacheImageInputStream.java b/awt/javax/imageio/stream/FileCacheImageInputStream.java
new file mode 100644
index 0000000..47bc189
--- /dev/null
+++ b/awt/javax/imageio/stream/FileCacheImageInputStream.java
@@ -0,0 +1,131 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import java.io.*;
+
+/**
+ * The FileCacheImageInputStream class is an implementation of
+ * ImageInputStream which reads from its InputStream
+ * and uses a temporary file as a cache. 
+ */
+public class FileCacheImageInputStream extends ImageInputStreamImpl {
+    
+    /** The is. */
+    private InputStream is;
+    
+    /** The file. */
+    private File file;
+    
+    /** The raf. */
+    private RandomAccessFile raf;
+
+
+    /**
+     * Instantiates a new FileCacheImageInputStream from
+     * the specified InputStream and using the specified 
+     * File as its cache directory.
+     * 
+     * @param stream the InputStream for reading.
+     * @param cacheDir the cache directory where the chache file
+     * will be created.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public FileCacheImageInputStream(InputStream stream, File cacheDir) throws IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+        is = stream;
+
+        if (cacheDir == null || cacheDir.isDirectory()) {
+            file = File.createTempFile(FileCacheImageOutputStream.IIO_TEMP_FILE_PREFIX, null, cacheDir);
+            file.deleteOnExit();
+        } else {
+            throw new IllegalArgumentException("Not a directory!");
+        }
+
+        raf = new RandomAccessFile(file, "rw");
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0;
+
+        if (streamPos >= raf.length()) {
+            int b = is.read();
+
+            if (b < 0) {
+                return -1;
+            }
+
+            raf.seek(streamPos++);
+            raf.write(b);
+            return b;
+        }
+
+        raf.seek(streamPos++);
+        return raf.read();
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        if (streamPos >= raf.length()) {
+            int nBytes = is.read(b, off, len);
+
+            if (nBytes < 0) {
+                return -1;
+            }
+
+            raf.seek(streamPos);
+            raf.write(b, off, nBytes);
+            streamPos += nBytes;
+            return nBytes;
+        }
+
+        raf.seek(streamPos);
+        int nBytes = raf.read(b, off, len);
+        streamPos += nBytes;
+        return nBytes;
+    }
+
+    @Override
+    public boolean isCached() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedFile() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedMemory() {
+        return false;
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+        raf.close();
+        file.delete();
+    }
+}
diff --git a/awt/javax/imageio/stream/FileCacheImageOutputStream.java b/awt/javax/imageio/stream/FileCacheImageOutputStream.java
new file mode 100644
index 0000000..ae48585
--- /dev/null
+++ b/awt/javax/imageio/stream/FileCacheImageOutputStream.java
@@ -0,0 +1,184 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+
+/**
+ * The FileCacheImageOutputStream class is an implementation of 
+ * ImageOutputStream that writes to its OutputStream
+ * using a temporary file as a cache. 
+ */
+public class FileCacheImageOutputStream extends ImageOutputStreamImpl {
+    
+    /** The Constant IIO_TEMP_FILE_PREFIX. */
+    static final String IIO_TEMP_FILE_PREFIX = "iioCache";
+    
+    /** The Constant MAX_BUFFER_LEN. */
+    static final int MAX_BUFFER_LEN = 1048575; // 1 MB - is it not too much?
+
+    /** The os. */
+    private OutputStream os;
+    
+    /** The file. */
+    private File file;
+    
+    /** The raf. */
+    private RandomAccessFile raf;
+
+    /**
+     * Instantiates a FileCacheImageOutputStream.
+     * 
+     * @param stream the OutputStream for writing.
+     * @param cacheDir the cache directory where the chache file
+     * will be created.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public FileCacheImageOutputStream(OutputStream stream, File cacheDir) throws IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+        os = stream;
+
+        if (cacheDir == null || cacheDir.isDirectory()) {
+            file = File.createTempFile(IIO_TEMP_FILE_PREFIX, null, cacheDir);
+            file.deleteOnExit();
+        } else {
+            throw new IllegalArgumentException("Not a directory!");
+        }
+
+        raf = new RandomAccessFile(file, "rw");
+    }
+
+    @Override
+    public void close() throws IOException {
+        flushBefore(raf.length());
+        super.close();
+        raf.close();
+        file.delete();
+    }
+
+    @Override
+    public boolean isCached() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedFile() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedMemory() {
+        return false;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        flushBits(); // See the flushBits method description
+        
+        raf.write(b);
+        streamPos++;
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        flushBits(); // See the flushBits method description
+
+        raf.write(b, off, len);
+        streamPos += len;
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0; // Should reset
+
+        int res = raf.read();
+        if (res >= 0) {
+            streamPos++;
+        }
+
+        return res;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        int numRead = raf.read(b, off, len);
+        if (numRead > 0) {
+            streamPos += numRead;
+        }
+
+        return numRead;
+    }
+
+    @Override
+    public void flushBefore(long pos) throws IOException {
+        long readFromPos = flushedPos;
+        super.flushBefore(pos);
+
+        long bytesToRead = pos - readFromPos;
+        raf.seek(readFromPos);
+
+        if (bytesToRead < MAX_BUFFER_LEN) {
+            byte buffer[] = new byte[(int)bytesToRead];
+            raf.readFully(buffer);
+            os.write(buffer);
+        } else {
+            byte buffer[] = new byte[MAX_BUFFER_LEN];
+            while (bytesToRead > 0) {
+                int count = (int) Math.min(MAX_BUFFER_LEN, bytesToRead);
+                raf.readFully(buffer, 0, count);
+                os.write(buffer, 0, count);
+                bytesToRead -= count;
+            }
+        }
+
+        os.flush();
+
+        if (pos != streamPos) {
+            raf.seek(streamPos); // Reset the position
+        }
+    }
+
+    @Override
+    public void seek(long pos) throws IOException {
+        if (pos < flushedPos) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        raf.seek(pos);
+        streamPos = raf.getFilePointer();        
+        bitOffset = 0;
+    }
+
+    @Override
+    public long length() {
+        try {
+            return raf.length();
+        } catch(IOException e) {
+            return -1L;
+        }
+    }
+}
diff --git a/awt/javax/imageio/stream/FileImageInputStream.java b/awt/javax/imageio/stream/FileImageInputStream.java
new file mode 100644
index 0000000..6680ae0
--- /dev/null
+++ b/awt/javax/imageio/stream/FileImageInputStream.java
@@ -0,0 +1,115 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * The FileImageInputStream class implements ImageInputStream 
+ * and obtains its input data from a File or RandomAccessFile. 
+ */
+public class FileImageInputStream extends ImageInputStreamImpl {
+    
+    /** The raf. */
+    RandomAccessFile raf;
+
+    /**
+     * Instantiates a new FileImageInputStream from the specified File.
+     * 
+     * @param f the File of input data.
+     * 
+     * @throws FileNotFoundException if the specified file 
+     * doesn't exist.
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    @SuppressWarnings({"DuplicateThrows"})
+    public FileImageInputStream(File f) throws FileNotFoundException, IOException {
+        if (f == null) {
+            throw new IllegalArgumentException("f == null!");
+        }
+
+        raf = new RandomAccessFile(f, "r");
+    }
+
+    /**
+     * Instantiates a new FileImageInputStream from the specified 
+     * RandomAccessFile.
+     * 
+     * @param raf the RandomAccessFile of input data.
+     */
+    public FileImageInputStream(RandomAccessFile raf) {
+        if (raf == null) {
+            throw new IllegalArgumentException("raf == null!");
+        }
+
+        this.raf = raf;
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0;
+
+        int res = raf.read();
+        if (res != -1) {
+            streamPos++;
+        }
+        return res;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        int numRead = raf.read(b, off, len);
+        if (numRead >= 0) {
+            streamPos += numRead;
+        }
+
+        return numRead;
+    }
+
+    @Override
+    public long length() {
+        try {
+            return raf.length();
+        } catch(IOException e) {
+            return -1L;
+        }
+    }
+
+    @Override
+    public void seek(long pos) throws IOException {
+        if (pos < getFlushedPosition()) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        raf.seek(pos);
+        streamPos = raf.getFilePointer();
+        bitOffset = 0;
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+        raf.close();
+    }
+}
diff --git a/awt/javax/imageio/stream/FileImageOutputStream.java b/awt/javax/imageio/stream/FileImageOutputStream.java
new file mode 100644
index 0000000..eaafe14
--- /dev/null
+++ b/awt/javax/imageio/stream/FileImageOutputStream.java
@@ -0,0 +1,123 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.stream;
+
+import java.io.*;
+
+/**
+ * The FileImageOutputStream class implements ImageOutputStream 
+ * and writes the output data to a File or RandomAccessFile. 
+ */
+public class FileImageOutputStream extends ImageOutputStreamImpl {
+
+    /** The file. */
+    RandomAccessFile file;
+
+    /**
+     * Instantiates a new FileImageOutputStream with the specified
+     * File.
+     * 
+     * @param f the output File.
+     * 
+     * @throws FileNotFoundException if the file not found.
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public FileImageOutputStream(File f) throws FileNotFoundException, IOException {
+        this(f != null
+                ? new RandomAccessFile(f, "rw")
+                : null);
+    }
+
+    /**
+     * Instantiates a new FileImageOutputStream with the specified
+     * RandomAccessFile.
+     * 
+     * @param raf the output RandomAccessFile.
+     */
+    public FileImageOutputStream(RandomAccessFile raf) {
+        if (raf == null) {
+            throw new IllegalArgumentException("file should not be NULL");
+        }
+        file = raf;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        checkClosed();
+        // according to the spec for ImageOutputStreamImpl#flushBits()
+        flushBits();
+        file.write(b);
+        streamPos++;
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        checkClosed();
+        // according to the spec for ImageOutputStreamImpl#flushBits()
+        flushBits();
+        file.write(b, off, len);
+        streamPos += len;
+    }
+
+    @Override
+    public int read() throws IOException {
+        checkClosed();
+        int rt = file.read();
+        if (rt != -1) {
+            streamPos++;
+        }
+        return rt;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        checkClosed();
+        int rt = file.read(b, off, len);
+        if (rt != -1) {
+            streamPos += rt;
+        }
+        return rt;
+    }
+
+    @Override
+    public long length() {
+        try {
+            checkClosed();
+            return file.length();
+        } catch(IOException e) {
+            return super.length(); // -1L
+        }
+    }
+
+    @Override
+    public void seek(long pos) throws IOException {
+        //-- checkClosed() is performed in super.seek()
+        super.seek(pos);
+        file.seek(pos);
+        streamPos = file.getFilePointer();
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+        file.close();
+    }
+}
diff --git a/awt/javax/imageio/stream/IIOByteBuffer.java b/awt/javax/imageio/stream/IIOByteBuffer.java
new file mode 100644
index 0000000..961a7b3
--- /dev/null
+++ b/awt/javax/imageio/stream/IIOByteBuffer.java
@@ -0,0 +1,111 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.stream;
+
+/** 
+* @author Sergey I. Salishev
+* @version $Revision: 1.2 $
+*/
+
+/**
+ * The IIOByteBuffer class represents a byte array with offset and 
+ * length that is used by ImageInputStream for obtaining a sequence 
+ * of bytes.
+ */
+public class IIOByteBuffer {
+    
+    /** The data. */
+    private byte[] data;
+    
+    /** The offset. */
+    private int offset;
+    
+    /** The length. */
+    private int length;
+
+    /**
+     * Instantiates a new IIOByteBuffer.
+     * 
+     * @param data the byte array.
+     * @param offset the offset in the array.
+     * @param length the length of array.
+     */
+    public IIOByteBuffer(byte[] data, int offset, int length) {
+        this.data = data;
+        this.offset = offset;
+        this.length = length;
+    }
+
+    /**
+     * Gets the byte array of this IIOByteBuffer.
+     * 
+     * @return the byte array.
+     */
+    public byte[] getData() {
+        return data;
+    }
+
+    /**
+     * Gets the length in the array which will be used.
+     * 
+     * @return the length of the data.
+     */
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * Gets the offset of this IIOByteBuffer.
+     * 
+     * @return the offset of this IIOByteBuffer.
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Sets the new data array to this IIOByteBuffer object.
+     * 
+     * @param data the new data array.
+     */
+    public void setData(byte[] data) {
+        this.data = data;
+    }
+
+    /**
+     * Sets the length of data which will be used.
+     * 
+     * @param length the new length.
+     */
+    public void setLength(int length) {
+        this.length = length;
+    }
+
+    /**
+     * Sets the offset in the data array of this IIOByteBuffer.
+     * 
+     * @param offset the new offset.
+     */
+    public void setOffset(int offset) {
+        this.offset = offset;
+    }
+}
+
diff --git a/awt/javax/imageio/stream/ImageInputStream.java b/awt/javax/imageio/stream/ImageInputStream.java
new file mode 100644
index 0000000..771e9ff
--- /dev/null
+++ b/awt/javax/imageio/stream/ImageInputStream.java
@@ -0,0 +1,485 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.stream;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.nio.ByteOrder;
+
+/**
+ * The ImageInputStream represents input stream interface that is 
+ * used by ImageReaders.
+ */
+public interface ImageInputStream extends DataInput {
+
+    /**
+     * Sets the specified byte order for reading of data values 
+     * from this stream. 
+     * 
+     * @param byteOrder the byte order.
+     */
+    void setByteOrder(ByteOrder byteOrder);
+
+    /**
+     * Gets the byte order. 
+     * 
+     * @return the byte order.
+     */
+    ByteOrder getByteOrder();
+
+    /**
+     * Reads a byte from the stream.
+     * 
+     * @return the byte of the stream, or -1 for EOF indicating. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int read() throws IOException;
+
+    /**
+     * Reads number of bytes which is equal to the specified array's length
+     * and stores a result to this array.
+     * 
+     * @param b the byte array.
+     * 
+     * @return the number of read bytes, or -1 indicated EOF.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int read(byte[] b) throws IOException;
+
+    /**
+     * Reads the number of bytes specified by len parameter from 
+     * the stream and stores a result to the specified array
+     * with the specified offset.
+     * 
+     * @param b the byte array.
+     * @param off the offset.
+     * @param len the number of bytes to be read.
+     * 
+     * @return the number of read bytes, or -1 indicated EOF.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int read(byte[] b, int off, int len) throws IOException;
+
+    /**
+     * Reads the number of bytes specified by len parameter 
+     * from the stream, and modifies the specified IIOByteBuffer 
+     * with the byte array, offset, and length.
+     * 
+     * @param buf the IIOByteBuffer.
+     * @param len the number of bytes to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readBytes(IIOByteBuffer buf, int len) throws IOException;
+
+    /**
+     * Reads a byte from the stream and returns a boolean true value 
+     * if it is non zero, false if it is zero.
+     * 
+     * @return a boolean value for read byte. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    boolean readBoolean() throws IOException;
+
+    /**
+     * Reads a byte from the stream and returns its value
+     * as signed byte.
+     * 
+     * @return a signed byte value for read byte. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    byte readByte() throws IOException;
+
+    /**
+     * Reads a byte from the stream and returns its value
+     * as int.
+     * 
+     * @return a unsigned byte value for read byte as int. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int readUnsignedByte() throws IOException;
+
+    /**
+     * Reads 2 bytes from the stream, and returns the result 
+     * as a short.
+     * 
+     * @return the signed short value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    short readShort() throws IOException;
+
+    /**
+     * Reads 2 bytes from the stream and returns its value
+     * as an unsigned short.
+     * 
+     * @return a unsigned short value coded in an int. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int readUnsignedShort() throws IOException;
+
+    /**
+     * Reads 2 bytes from the stream and returns their 
+     * unsigned char value.
+     * 
+     * @return the unsigned char value.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    char readChar() throws IOException;
+
+    /**
+     * Reads 4 bytes from the stream, and returns the result 
+     * as an int.
+     * 
+     * @return the signed int value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int readInt() throws IOException;
+
+    /**
+     * Reads 4 bytes from the stream and returns its value
+     * as long.
+     * 
+     * @return a unsigned int value as long. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long readUnsignedInt() throws IOException;
+
+    /**
+     * Reads 8 bytes from the stream, and returns the result 
+     * as a long.
+     * 
+     * @return the long value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long readLong() throws IOException;
+
+    /**
+     * Reads 4 bytes from the stream, and returns the result 
+     * as a float.
+     * 
+     * @return the float value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    float readFloat() throws IOException;
+
+    /**
+     * Reads 8 bytes from the stream, and returns the result 
+     * as a double.
+     * 
+     * @return the double value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    double readDouble() throws IOException;
+
+    /**
+     * Reads a line from the stream.
+     * 
+     * @return the string contained the line from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    String readLine() throws IOException;
+
+    /**
+     * Reads bytes from the stream in a string that has been encoded 
+     * in a modified UTF-8 format.
+     * 
+     * @return the string read from stream and modified UTF-8 format.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    String readUTF() throws IOException;
+
+    /**
+     * Reads the specified number of bytes from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param b the byte array.
+     * @param off the offset.
+     * @param len the number of bytes to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(byte[] b, int off, int len) throws IOException;
+
+    /**
+     * Reads number of bytes from the stream which is equal to 
+     * the specified array's length, and stores them into 
+     * this array.
+     * 
+     * @param b the byte array.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(byte[] b) throws IOException;
+
+    /**
+     * Reads the specified number of shorts from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param s the short array.
+     * @param off the offset.
+     * @param len the number of shorts to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(short[] s, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of chars from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param c the char array.
+     * @param off the offset.
+     * @param len the number of chars to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(char[] c, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of ints from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param i the int array.
+     * @param off the offset.
+     * @param len the number of ints to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(int[] i, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of longs from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param l the long array.
+     * @param off the offset.
+     * @param len the number of longs to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(long[] l, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of floats from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param f the float array.
+     * @param off the offset.
+     * @param len the number of floats to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(float[] f, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of doubles from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param d the double array.
+     * @param off the offset.
+     * @param len the number of doubles to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(double[] d, int off, int len) throws IOException;
+
+    /**
+     * Gets the stream position.
+     * 
+     * @return the stream position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long getStreamPosition() throws IOException;
+
+    /**
+     * Gets the bit offset.
+     * 
+     * @return the bit offset.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int getBitOffset() throws IOException;
+
+    /**
+     * Sets the bit offset to an integer between 0 and 7. 
+     * 
+     * @param bitOffset the bit offset.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void setBitOffset(int bitOffset) throws IOException;
+
+    /**
+     * Reads a bit from the stream and returns the value 0 or 1.
+     * 
+     * @return the value of single bit: 0 or 1.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int readBit() throws IOException;
+
+    /**
+     * Read the specified number of bits and returns their values as long.
+     * 
+     * @param numBits the number of bits to be read.
+     * 
+     * @return the bit string as a long.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long readBits(int numBits) throws IOException;
+
+    /**
+     * Returns the length of the stream. 
+     *  
+     * @return the length of the stream, or -1 if unknown. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long length() throws IOException;
+
+    /**
+     * Skipes the specified number of bytes by moving stream position. 
+     * 
+     * @param n the number of bytes.
+     * 
+     * @return the actual skipped number of bytes.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int skipBytes(int n) throws IOException;
+
+    /**
+     * Skipes the specified number of bytes by moving stream position. 
+     * 
+     * @param n the number of bytes.
+     * 
+     * @return the actual skipped number of bytes.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long skipBytes(long n) throws IOException;
+
+    /**
+     * Sets the current stream position to the specified location. 
+     * 
+     * @param pos a file pointer position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void seek(long pos) throws IOException;
+
+    /**
+     * Marks a position in the stream to be returned to by a subsequent 
+     * call to reset. 
+     */
+    void mark();
+
+    /**
+     * Returns the file pointer to its previous position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void reset() throws IOException;
+
+    /**
+     * Flushes the initial position in this stream prior to the
+     * specified stream position.
+     * 
+     * @param pos the position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void flushBefore(long pos) throws IOException;
+
+    /**
+     * Flushes the initial position in this stream prior to the
+     * current stream position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void flush() throws IOException;
+
+    /**
+     * Gets the flushed position.
+     * 
+     * @return the flushed position.
+     */
+    long getFlushedPosition();
+
+    /**
+     * Returns true if this ImageInputStream caches data in order 
+     * to allow seeking backwards.
+     * 
+     * @return true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, false otherwise.
+     */
+    boolean isCached();
+
+    /**
+     * Returns true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, and keeps it in memory.
+     * 
+     * @return true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, and keeps it in memory.
+     */
+    boolean isCachedMemory();
+
+    /**
+     * Returns true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, and keeps it in a temporary file.
+     * 
+     * @return true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, and keeps it in a temporary file.
+     */
+    boolean isCachedFile();
+
+    /**
+     * Closes this stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void close() throws IOException;
+}
diff --git a/awt/javax/imageio/stream/ImageInputStreamImpl.java b/awt/javax/imageio/stream/ImageInputStreamImpl.java
new file mode 100644
index 0000000..83ac13a
--- /dev/null
+++ b/awt/javax/imageio/stream/ImageInputStreamImpl.java
@@ -0,0 +1,394 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.stream;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteOrder;
+
+/**
+ * The ImageInputStreamImpl abstract class implements
+ * the ImageInputStream interface.
+ */
+public abstract class ImageInputStreamImpl implements ImageInputStream {
+
+    /** The byte order. */
+    protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
+
+    /** The stream position. */
+    protected long streamPos = 0;
+    
+    /** The flushed position. */
+    protected long flushedPos = 0;
+    
+    /** The bit offset. */
+    protected int bitOffset = 0;
+
+    /** The closed. */
+    private boolean closed = false;
+
+    /** The position stack. */
+    private final PositionStack posStack = new PositionStack();
+
+    /**
+     * Instantiates a new ImageInputStreamImpl.
+     */
+    public ImageInputStreamImpl() {}
+
+    /**
+     * Check if the stream is closed and if true, throws an IOException.
+     * 
+     * @throws IOException Signals that the stream is closed.
+     */
+    protected final void checkClosed() throws IOException {
+        if (closed) {
+            throw new IOException("stream is closed");
+        }
+    }
+
+    public void setByteOrder(ByteOrder byteOrder) {
+        this.byteOrder = byteOrder;
+    }
+
+    public ByteOrder getByteOrder() {
+        return byteOrder;
+    }
+
+    public abstract int read() throws IOException;
+
+    public int read(byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    public abstract int read(byte[] b, int off, int len) throws IOException;
+
+    public void readBytes(IIOByteBuffer buf, int len) throws IOException {
+        if (buf == null) {
+            throw new NullPointerException("buffer is NULL");
+        }
+
+        byte[] b = new byte[len];
+        len = read(b, 0, b.length);
+
+        buf.setData(b);
+        buf.setOffset(0);
+        buf.setLength(len);
+    }
+
+    public boolean readBoolean() throws IOException {
+        int b = read();
+        if (b < 0) {
+            throw new EOFException("EOF reached");
+        }
+        return b != 0;
+    }
+
+    public byte readByte() throws IOException {
+        int b = read();
+        if (b < 0) {
+            throw new EOFException("EOF reached");
+        }
+        return (byte) b;
+    }
+
+    public int readUnsignedByte() throws IOException {
+        int b = read();
+        if (b < 0) {
+            throw new EOFException("EOF reached");
+        }
+        return b;
+    }
+
+    public short readShort() throws IOException {
+        int b1 = read();
+        int b2 = read();
+
+        if (b1 < 0 || b2 < 0) {
+            throw new EOFException("EOF reached");
+        }
+
+        return byteOrder == ByteOrder.BIG_ENDIAN ?
+                (short) ((b1 << 8) | (b2 & 0xff)) :
+                (short) ((b2 << 8) | (b1 & 0xff));
+    }
+
+    public int readUnsignedShort() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public char readChar() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public int readInt() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long readUnsignedInt() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long readLong() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public float readFloat() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public double readDouble() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public String readLine() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public String readUTF() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(byte[] b, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(byte[] b) throws IOException {
+        readFully(b, 0, b.length);
+    }
+
+    public void readFully(short[] s, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(char[] c, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(int[] i, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(long[] l, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(float[] f, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(double[] d, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long getStreamPosition() throws IOException {
+        checkClosed();
+        return streamPos;
+    }
+
+    public int getBitOffset() throws IOException {
+        checkClosed();
+        return bitOffset;
+    }
+
+    public void setBitOffset(int bitOffset) throws IOException {
+        checkClosed();
+        this.bitOffset = bitOffset;
+    }
+
+    public int readBit() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long readBits(int numBits) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long length() {
+        return -1L;
+    }
+
+    public int skipBytes(int n) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long skipBytes(long n) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void seek(long pos) throws IOException {
+        checkClosed();
+        if (pos < getFlushedPosition()) {
+            throw new IllegalArgumentException("trying to seek before flushed pos");
+        }
+        bitOffset = 0;
+        streamPos = pos;
+    }
+
+    public void mark() {
+        try {
+            posStack.push(getStreamPosition());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Stream marking error");
+        }
+    }
+
+    public void reset() throws IOException {
+        //-- TODO bit pos
+        if (!posStack.isEmpty()) {
+            long p = posStack.pop();
+            if (p < flushedPos) {
+                throw new IOException("marked position lies in the flushed portion of the stream");
+            }
+            seek(p);
+        }
+    }
+
+    public void flushBefore(long pos) throws IOException {
+        if (pos > getStreamPosition()) {
+            throw new IndexOutOfBoundsException("Trying to flush outside of current position");
+        }
+        if (pos < flushedPos) {
+            throw new IndexOutOfBoundsException("Trying to flush within already flushed portion");
+        }
+        flushedPos = pos;
+        //-- TODO implement
+    }
+
+    public void flush() throws IOException {
+        flushBefore(getStreamPosition());
+    }
+
+    public long getFlushedPosition() {
+        return flushedPos;
+    }
+
+    public boolean isCached() {
+        return false; //def
+    }
+
+    public boolean isCachedMemory() {
+        return false; //def
+    }
+
+    public boolean isCachedFile() {
+        return false; //def
+    }
+
+    public void close() throws IOException {
+        checkClosed();
+        closed = true;
+
+    }
+
+    /**
+     * Finalizes this object.
+     * 
+     * @throws Throwable if an error occurs.
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        if (!closed) {
+            try {
+                close();
+            } finally {
+                super.finalize();
+            }
+        }
+    }
+
+    /**
+     * The Class PositionStack.
+     */
+    private static class PositionStack {
+        
+        /** The Constant SIZE. */
+        private static final int SIZE = 10;
+
+        /** The values. */
+        private long[] values = new long[SIZE];
+        
+        /** The pos. */
+        private int pos = 0;
+
+
+        /**
+         * Push.
+         * 
+         * @param v the v
+         */
+        void push(long v) {
+            if (pos >= values.length) {
+                ensure(pos+1);
+            }
+            values[pos++] = v;
+        }
+
+        /**
+         * Pop.
+         * 
+         * @return the long
+         */
+        long pop() {
+            return values[--pos];
+        }
+
+        /**
+         * Checks if is empty.
+         * 
+         * @return true, if is empty
+         */
+        boolean isEmpty() {
+            return pos == 0;
+        }
+
+        /**
+         * Ensure.
+         * 
+         * @param size the size
+         */
+        private void ensure(int size) {
+            long[] arr = new long[Math.max(2 * values.length, size)];
+            System.arraycopy(values, 0, arr, 0, values.length);
+            values = arr;
+        }
+    }
+}
diff --git a/awt/javax/imageio/stream/ImageOutputStream.java b/awt/javax/imageio/stream/ImageOutputStream.java
new file mode 100644
index 0000000..e59b69d
--- /dev/null
+++ b/awt/javax/imageio/stream/ImageOutputStream.java
@@ -0,0 +1,270 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.stream;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * The ImageOutputStream represents output stream interface that is 
+ * used by ImageWriters.
+ */
+public interface ImageOutputStream extends DataOutput, ImageInputStream {
+
+    /**
+     * Writes a single byte to the stream at the current position. 
+     * 
+     * @param b the int value, of which the 8 lowest bits 
+     * will be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void write(int b) throws IOException;
+
+    /**
+     * Writes the bytes array to the stream.
+     * 
+     * @param b the byte array to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void write(byte[] b) throws IOException;
+
+    /**
+     * Writes a number of bytes from the specified byte array
+     * beggining from the specified offset.
+     * 
+     * @param b the byte array.
+     * @param off the offset.
+     * @param len the number of bytes to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void write(byte[] b, int off, int len) throws IOException;
+
+    /**
+     * Writes the specified boolean value to the stream, 1 if it is true,
+     * 0 if it is false.
+     * 
+     * @param b the boolean value to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeBoolean(boolean b) throws IOException;
+
+    /**
+     * Writes the 8 lowest bits of the specified int value to the stream. 
+     * 
+     * @param b the specified int value.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeByte(int b) throws IOException;
+
+    /**
+     * Writes a short value to the output stream. 
+     * 
+     * @param v the short value to be written. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeShort(int v) throws IOException;
+
+    /**
+     * Writes the 16 lowest bits of the specified int value to the stream.
+     * 
+     * @param v the specified int value.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeChar(int v) throws IOException;
+
+    /**
+     * Writes an integer value to the output stream. 
+     * 
+     * @param v the integer value to be written. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeInt(int v) throws IOException;
+
+    /**
+     * Write long.
+     * 
+     * @param v the long value
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeLong(long v) throws IOException;
+
+    /**
+     * Writes a float value to the output stream. 
+     * 
+     * @param v the float which contains value to be written. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeFloat(float v) throws IOException;
+
+    /**
+     * Writes a double value to the output stream. 
+     * 
+     * @param v the double which contains value to be written. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeDouble(double v) throws IOException;
+
+    /**
+     * Writes the specified string to the stream.
+     * 
+     * @param s the string to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeBytes(String s) throws IOException;
+
+    /**
+     * Writes the specified String to the output stream.
+     * 
+     * @param s the String to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeChars(String s) throws IOException;
+
+    /**
+     * Writes 2 bytes to the output stream in 
+     * the modified UTF-8  representation of every character of
+     * the specified string.      
+     * 
+     * @param s the specified string to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeUTF(String s) throws IOException;
+
+    /**
+     * Flushes the initial position in this stream prior to the
+     * specified stream position.
+     * 
+     * @param pos the position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void flushBefore(long pos) throws IOException;
+
+
+    /**
+     * Writes a len number of short values from the specified array
+     * to the stream.
+     * 
+     * @param s the shorts array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeShorts(short[] s, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of chars to the stream.
+     * 
+     * @param c the char array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeChars(char[] c, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of int values from the specified array
+     * to the stream.
+     * 
+     * @param i the int array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeInts(int[] i, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of long values from the specified array
+     * to the stream.
+     * 
+     * @param l the long array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeLongs(long[] l, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of float values from the specified array
+     * to the stream.
+     * 
+     * @param f the float array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeFloats(float[] f, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of double values from the specified array
+     * to the stream.
+     * 
+     * @param d the double array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeDoubles(double[] d, int off, int len) throws IOException;
+
+    /**
+     * Writes a single bit at the current position.
+     * 
+     * @param bit the an int whose least significant bit is to be 
+     * written to the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeBit(int bit) throws IOException;
+
+    /**
+     * Writes a sequence of bits beggining from the current position.
+     * 
+     * @param bits a long value containing the bits to be written,
+     * starting with the bit in position numBits - 1 down to the 
+     * least significant bit.
+     * @param numBits the number of significant bit , 
+     * it can be between 0 and 64. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeBits(long bits, int numBits) throws IOException;
+
+}
diff --git a/awt/javax/imageio/stream/ImageOutputStreamImpl.java b/awt/javax/imageio/stream/ImageOutputStreamImpl.java
new file mode 100644
index 0000000..c3d80fa
--- /dev/null
+++ b/awt/javax/imageio/stream/ImageOutputStreamImpl.java
@@ -0,0 +1,169 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio.stream;
+
+import java.io.IOException;
+import java.nio.ByteOrder;
+
+/* 
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+
+/**
+ * The ImageOutputStreamImpl abstract class implements
+ * the ImageOutputStream interface.
+ */
+public abstract class ImageOutputStreamImpl extends ImageInputStreamImpl
+        implements ImageOutputStream {
+
+    /**
+     * Instantiates a new ImageOutputStreamImpl.
+     */
+    public ImageOutputStreamImpl() {}
+
+    public abstract void write(int b) throws IOException;
+
+    public void write(byte[] b) throws IOException {
+        write(b, 0, b.length);
+    }
+
+    public abstract void write(byte[] b, int off, int len) throws IOException;
+
+    public void writeBoolean(boolean v) throws IOException {
+        write(v ? 1 : 0);
+    }
+
+    public void writeByte(int v) throws IOException {
+        write(v);
+    }
+
+    public void writeShort(int v) throws IOException {
+        if (byteOrder == ByteOrder.BIG_ENDIAN) {
+
+        } else {
+
+        }
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeChar(int v) throws IOException {
+        writeShort(v);
+    }
+
+    public void writeInt(int v) throws IOException {
+        if (byteOrder == ByteOrder.BIG_ENDIAN) {
+
+        } else {
+
+        }
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeLong(long v) throws IOException {
+        if (byteOrder == ByteOrder.BIG_ENDIAN) {
+
+        } else {
+
+        }
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeFloat(float v) throws IOException {
+        writeInt(Float.floatToIntBits(v));
+    }
+
+    public void writeDouble(double v) throws IOException {
+        writeLong(Double.doubleToLongBits(v));
+    }
+
+    public void writeBytes(String s) throws IOException {
+        write(s.getBytes());
+    }
+
+    public void writeChars(String s) throws IOException {
+        char[] chs = s.toCharArray();
+        writeChars(chs, 0, chs.length);
+    }
+
+    public void writeUTF(String s) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeShorts(short[] s, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeChars(char[] c, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeInts(int[] i, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeLongs(long[] l, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeFloats(float[] f, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeDoubles(double[] d, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeBit(int bit) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeBits(long bits, int numBits) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Flushes the bits. This method should be called in the write
+     * methods by subclasses.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    protected final void flushBits() throws IOException {
+        if (bitOffset == 0) {
+            return;
+        }
+        
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+}
diff --git a/awt/javax/imageio/stream/MemoryCacheImageInputStream.java b/awt/javax/imageio/stream/MemoryCacheImageInputStream.java
new file mode 100644
index 0000000..a3d470b
--- /dev/null
+++ b/awt/javax/imageio/stream/MemoryCacheImageInputStream.java
@@ -0,0 +1,113 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import org.apache.harmony.x.imageio.stream.RandomAccessMemoryCache;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * The MemoryCacheImageInputStream class implements ImageInputStream
+ * using a memory buffer for caching the data.
+ */
+public class MemoryCacheImageInputStream  extends ImageInputStreamImpl {
+    
+    /** The is. */
+    private InputStream is;
+    
+    /** The ramc. */
+    private RandomAccessMemoryCache ramc = new RandomAccessMemoryCache();
+
+    /**
+     * Instantiates a new MemoryCacheImageInputStream
+     * which reads from the specified InputStream.
+     * 
+     * @param stream the InputStream to be read.
+     */
+    public MemoryCacheImageInputStream(InputStream stream) {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+        is = stream;
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0;
+
+        if (streamPos >= ramc.length()) {
+            int count = (int)(streamPos - ramc.length() + 1);
+            int bytesAppended = ramc.appendData(is, count);
+
+            if (bytesAppended < count) {
+                return -1;
+            }
+        }
+
+        int res = ramc.getData(streamPos);
+        if (res >= 0) {
+            streamPos++;
+        }
+        return res;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        if (streamPos >= ramc.length()) {
+            int count = (int)(streamPos - ramc.length() + len);
+            ramc.appendData(is, count);
+        }
+
+        int res = ramc.getData(b, off, len, streamPos);
+        if (res > 0) {
+            streamPos += res;
+        }
+        return res;
+    }
+
+    @Override
+    public boolean isCached() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedFile() {
+        return false;
+    }
+
+    @Override
+    public boolean isCachedMemory() {
+        return true;
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+        ramc.close();
+    }
+
+    @Override
+    public void flushBefore(long pos) throws IOException {
+        super.flushBefore(pos);
+        ramc.freeBefore(getFlushedPosition());
+    }
+}
diff --git a/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java b/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java
new file mode 100644
index 0000000..96ded43
--- /dev/null
+++ b/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java
@@ -0,0 +1,130 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import org.apache.harmony.x.imageio.stream.RandomAccessMemoryCache;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+
+/**
+ * The MemoryCacheImageOutputStream class implements ImageOutputStream
+ * using a memory buffer for caching the data.
+ */
+public class MemoryCacheImageOutputStream extends ImageOutputStreamImpl {
+    
+    /** The os. */
+    OutputStream os;
+    
+    /** The ramc. */
+    RandomAccessMemoryCache ramc = new RandomAccessMemoryCache();
+
+    /**
+     * Instantiates a new MemoryCacheImageOutputStream
+     * which writes to the specified OutputStream.
+     * 
+     * @param stream the OutputStream.
+     */
+    public MemoryCacheImageOutputStream(OutputStream stream) {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+        os = stream;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        flushBits(); // See the flushBits method description
+
+        ramc.putData(b, streamPos);
+        streamPos++;
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        flushBits(); // See the flushBits method description
+
+        ramc.putData(b, off, len, streamPos);
+        streamPos += len;
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0;
+
+        int res = ramc.getData(streamPos);
+        if (res >= 0) {
+            streamPos++;
+        }
+        return res;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        int res = ramc.getData(b, off, len, streamPos);
+        if (res > 0) {
+            streamPos += res;
+        }
+        return res;
+    }
+
+    @Override
+    public long length() {
+        return ramc.length();
+    }
+
+    @Override
+    public boolean isCached() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedMemory() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedFile() {
+        return false;
+    }
+
+    @Override
+    public void close() throws IOException {
+        flushBefore(length());
+        super.close();
+        ramc.close();
+    }
+
+    @Override
+    public void flushBefore(long pos) throws IOException {
+        long flushedPosition = getFlushedPosition();
+        super.flushBefore(pos);
+
+        long newFlushedPosition = getFlushedPosition();
+        int nBytes = (int)(newFlushedPosition - flushedPosition);
+
+        ramc.getData(os, nBytes, flushedPosition);
+        ramc.freeBefore(newFlushedPosition);
+
+        os.flush();        
+    }
+}
diff --git a/awt/org/apache/harmony/awt/ChoiceStyle.java b/awt/org/apache/harmony/awt/ChoiceStyle.java
new file mode 100644
index 0000000..93b7aad
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ChoiceStyle.java
@@ -0,0 +1,33 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+/**
+ * ChoiceStyle.
+ * Is used to define custom choice properties:
+ * width and x screen coordinate of the list popup window. 
+ */
+public interface ChoiceStyle {
+
+    int getPopupX(int x, int width, int choiceWidth, int screenWidth);
+    int getPopupWidth(int choiceWidth);
+
+}
diff --git a/awt/org/apache/harmony/awt/ClipRegion.java b/awt/org/apache/harmony/awt/ClipRegion.java
new file mode 100644
index 0000000..c89a81d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ClipRegion.java
@@ -0,0 +1,84 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov, Anton Avtamonov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+import java.awt.Component;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class ClipRegion extends Rectangle {
+    private final MultiRectArea clip;
+
+    public ClipRegion(final MultiRectArea clip) {
+        this.clip = new MultiRectArea(clip);
+        setBounds(clip.getBounds());
+    }
+
+    public MultiRectArea getClip() {
+        return clip;
+    }
+
+    @Override
+    public String toString() {
+        String str = clip.toString();
+        int i = str.indexOf('[');
+        str = str.substring(i);
+        if (clip.getRectCount() == 1) {
+            str = str.substring(1, str.length() - 1);
+        }
+        return getClass().getName() + str;
+    }
+
+
+    public void convertRegion(final Component child, final Component parent) {
+        convertRegion(child, clip, parent);
+    }
+
+    public void intersect(final Rectangle rect) {
+        clip.intersect(rect);
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return clip.isEmpty();
+    }
+
+    public static void convertRegion(final Component child,
+                                     final MultiRectArea region,
+                                     final Component parent) {
+        int x = 0, y = 0;
+        Component c = child;
+        //???AWT
+        /*
+        for (; c != null && c != parent; c = c.getParent()) {
+            x += c.getX();
+            y += c.getY();
+        }
+        */
+        if (c == null) {
+            // awt.51=Component expected to be a parent
+            throw new IllegalArgumentException(Messages.getString("awt.51")); //$NON-NLS-1$
+        }
+        region.translate(x, y);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/ComponentInternals.java b/awt/org/apache/harmony/awt/ComponentInternals.java
new file mode 100644
index 0000000..c359784
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ComponentInternals.java
@@ -0,0 +1,212 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+//???AWT
+//import java.awt.Component;
+//import java.awt.Container;
+//import java.awt.Dialog;
+import java.awt.Dimension;
+//import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+//import java.awt.Window;
+//import java.awt.Choice;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+//import org.apache.harmony.awt.text.TextFieldKit;
+//import org.apache.harmony.awt.text.TextKit;
+//import org.apache.harmony.awt.wtk.NativeWindow;
+
+import org.apache.harmony.luni.util.NotImplementedException;
+
+/**
+ *  The accessor to AWT private API
+ */
+public abstract class ComponentInternals {
+
+    /**
+     * @return the ComponentInternals instance to serve the requests
+     */
+    public static ComponentInternals getComponentInternals() {
+        return ContextStorage.getComponentInternals();
+    }
+
+    /**
+     * This method must be called by AWT to establish the connection
+     * @param internals - implementation of ComponentInternals created by AWT
+     */
+    public static void setComponentInternals(ComponentInternals internals) {
+        ContextStorage.setComponentInternals(internals);
+    }
+
+    /**
+     * The accessor to native resource connected to a component.
+     * It returns non-<code>null</code> value only if component
+     * already has the native resource
+     */
+    //public abstract NativeWindow getNativeWindow(Component component);
+
+    /**
+     * Connect Window object to existing native resource
+     * @param nativeWindowId - id of native window to attach
+     * @return Window object with special behaviour that
+     * restricts manupulation with that window
+     */
+    //public abstract Window attachNativeWindow(long nativeWindowId);
+
+    /**
+     * Start mouse grab in "client" mode.
+     * All mouse events in AWT components will be reported as usual,
+     * mouse events that occured outside of AWT components will be sent to
+     * the window passed as grabWindow parameter. When mouse grab is canceled
+     * (because of click in non-AWT window or by task switching)
+     * the whenCanceled callback is called
+     *
+     * @param grabWindow - window that will own the grab
+     * @param whenCanceled - callback called when grab is canceled by user's action
+     */
+    //public abstract void startMouseGrab(Window grabWindow, Runnable whenCanceled);
+
+    /**
+     * End mouse grab and resume normal processing of mouse events
+     */
+    //public abstract void endMouseGrab();
+
+    /**
+     * Set the <code>popup</code> flag of the window to true.
+     * This window won't be controlled by window manager on Linux.
+     * Call this method before the window is shown first time
+     * @param window - the window that should become popup one
+     */
+    //public abstract void makePopup(Window window);
+
+    /**
+     * This method must be called by Graphics at the beginning of drawImage()
+     * to store image drawing parameters (defined by application developer) in component
+     *
+     * @param comp - component that draws the image
+     * @param image - image to be drawn
+     * @param destLocation - location of the image upon the component's surface. Never null.
+     * @param destSize - size of the component's area to be filled with the image.
+     *                  Equals to null if size parameters omitted in drawImage.
+     * @param source - area of the image to be drawn on the component.
+     *                  Equals to null if src parameters omitted in drawImage.
+     */
+    /*
+    public abstract void onDrawImage(Component comp, Image image, Point destLocation,
+            Dimension destSize, Rectangle source);
+*/
+    /**
+     * Sets system's caret position.
+     * This method should be called by text component to synchronize our caret position
+     * with system's caret position.
+     * @param x
+     * @param y
+     */
+    //public abstract void setCaretPos(Component c, int x, int y);
+
+    /**
+     * NEVER USE IT. FORGET IT. IT DOES NOT EXIST.
+     * See Toolkit.unsafeInvokeAndWait(Runnable).
+     *
+     * Accessor for Toolkit.unsafeInvokeAndWait(Runnable) method.
+     * For use in exceptional cases only.
+     * Read comments for Toolkit.unsafeInvokeAndWait(Runnable) before use.
+     */
+    /*
+    public abstract void unsafeInvokeAndWait(Runnable runnable)
+            throws InterruptedException, InvocationTargetException;
+
+    public abstract TextKit getTextKit(Component comp);
+
+    public abstract void setTextKit(Component comp, TextKit kit);
+
+    public abstract TextFieldKit getTextFieldKit(Component comp);
+
+    public abstract void setTextFieldKit(Component comp, TextFieldKit kit);
+*/
+    /**
+     * Terminate event dispatch thread, completely destroy AWT context.<br>
+     * Intended for multi-context mode, in single-context mode does nothing.
+     *
+     */
+    public abstract void shutdown();
+
+    /**
+     * Sets mouse events preprocessor for event queue
+     */
+    //public abstract void setMouseEventPreprocessor(MouseEventPreprocessor preprocessor);
+
+    /**
+     * Create customized Choice using style
+     */
+    //public abstract Choice createCustomChoice(ChoiceStyle style);
+
+    //public abstract Insets getNativeInsets(Window w);
+
+    /**
+     * Region to be repainted (could be null). Use this in overridden repaint()
+     */
+    //public abstract MultiRectArea getRepaintRegion(Component c);
+
+    //public abstract MultiRectArea subtractPendingRepaintRegion(Component c, MultiRectArea mra);
+
+    /**
+     * Returns true if the window was at least once painted due to native paint events
+     */
+    //public abstract boolean wasPainted(Window w);
+
+    /**
+     * The component's region hidden behind top-level windows
+     * (belonging to both this Java app and all other apps), and behind
+     * heavyweight components overlapping with passed component
+     */
+    //public abstract MultiRectArea getObscuredRegion(Component c);
+    
+    /**
+     * An accessor to Container.addObscuredRegions() method
+     * @see java.awt.Container#addObscuredRegions(MultiRectArea, Component)
+     */
+    //public abstract void addObscuredRegions(MultiRectArea mra, Component c, Container container);
+    
+    /**
+     * Makes it possible to call protected Toolkit.setDesktopProperty()
+     * method from any class outside of java.awt package
+     */
+    public abstract void setDesktopProperty(String name, Object value);
+    
+    /**
+     * Makes it possible to start/stop dialog modal loop
+     * from anywhere outside of java.awt package
+     */
+    //public abstract void runModalLoop(Dialog dlg);
+    //public abstract void endModalLoop(Dialog dlg);
+    
+    /**
+     * Sets component's visible flag only
+     * (the component is not actually shown/hidden)
+     */
+    //public abstract void setVisibleFlag(Component comp, boolean visible);
+    
+}
diff --git a/awt/org/apache/harmony/awt/ContextStorage.java b/awt/org/apache/harmony/awt/ContextStorage.java
new file mode 100644
index 0000000..d44648a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ContextStorage.java
@@ -0,0 +1,154 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+import java.awt.*;
+
+//???AWT
+//import org.apache.harmony.awt.datatransfer.*;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.*;
+
+
+public final class ContextStorage {
+
+    private static volatile boolean multiContextMode = false;
+    private volatile boolean shutdownPending = false;
+
+    private static final ContextStorage globalContext = new ContextStorage();
+
+    private Toolkit toolkit;
+    private ComponentInternals componentInternals;
+    //???AWT: private DTK dtk;
+    private WTK wtk;
+    private GraphicsEnvironment graphicsEnvironment;
+
+    private class ContextLock {}
+    private final Object contextLock = new ContextLock();
+    private final Synchronizer synchronizer = new Synchronizer();
+
+    public static void activateMultiContextMode() {
+        // TODO: checkPermission
+        multiContextMode = true;
+    }
+
+    public static void setDefaultToolkit(Toolkit newToolkit) {
+        // TODO: checkPermission
+        getCurrentContext().toolkit = newToolkit;
+    }
+
+    public static Toolkit getDefaultToolkit() {
+        return getCurrentContext().toolkit;
+    }
+
+    //???AWT
+    /*
+    public static void setDTK(DTK dtk) {
+        // TODO: checkPermission
+        getCurrentContext().dtk = dtk;
+    }
+
+    public static DTK getDTK() {
+        return getCurrentContext().dtk;
+    }
+    */
+
+    public static Synchronizer getSynchronizer() {
+        return getCurrentContext().synchronizer;
+    }
+
+    public static ComponentInternals getComponentInternals() {
+        return getCurrentContext().componentInternals;
+    }
+
+    static void setComponentInternals(ComponentInternals internals) {
+        // TODO: checkPermission
+        getCurrentContext().componentInternals = internals;
+    }
+
+    public static Object getContextLock() {
+        return getCurrentContext().contextLock;
+    }
+
+    public static WindowFactory getWindowFactory() {
+        return getCurrentContext().wtk.getWindowFactory();
+    }
+
+    public static void setWTK(WTK wtk) {
+        getCurrentContext().wtk = wtk;
+    }
+
+    public static NativeIM getNativeIM() {
+        return getCurrentContext().wtk.getNativeIM();
+    }
+
+    public static NativeEventQueue getNativeEventQueue() {
+        return getCurrentContext().wtk.getNativeEventQueue();
+    }
+
+    public static GraphicsEnvironment getGraphicsEnvironment() {
+        return getCurrentContext().graphicsEnvironment;
+    }
+
+    public static void setGraphicsEnvironment(GraphicsEnvironment environment) {
+        getCurrentContext().graphicsEnvironment = environment;
+    }
+
+    private static ContextStorage getCurrentContext() {
+        return multiContextMode ? getContextThreadGroup().context : globalContext;
+    }
+
+    private static ContextThreadGroup getContextThreadGroup() {
+
+        Thread thread = Thread.currentThread();
+        ThreadGroup group = thread.getThreadGroup();
+        while (group != null) {
+            if (group instanceof ContextThreadGroup) {
+                return (ContextThreadGroup)group;
+            }
+            group = group.getParent();
+        }
+        // awt.59=Application has run out of context thread group
+        throw new RuntimeException(Messages.getString("awt.59")); //$NON-NLS-1$
+    }
+    
+    public static boolean shutdownPending() {
+        return getCurrentContext().shutdownPending;
+    }
+
+    void shutdown() {
+        if (!multiContextMode) {
+            return;
+        }
+        shutdownPending = true;
+
+        //???AWT: componentInternals.shutdown();
+
+        synchronized(contextLock) {
+            toolkit = null;
+            componentInternals = null;
+            //???AWT: dtk = null;
+            wtk = null;
+            graphicsEnvironment = null;
+        }
+    }
+    
+}
diff --git a/awt/org/apache/harmony/awt/ContextThreadGroup.java b/awt/org/apache/harmony/awt/ContextThreadGroup.java
new file mode 100644
index 0000000..4f0af52
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ContextThreadGroup.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+public class ContextThreadGroup extends ThreadGroup {
+
+    final ContextStorage context = new ContextStorage();
+
+    public ContextThreadGroup(String name) {
+        super(name);
+    }
+
+    public void dispose() {
+        context.shutdown();
+    }
+}
diff --git a/awt/org/apache/harmony/awt/ListenerList.java b/awt/org/apache/harmony/awt/ListenerList.java
new file mode 100644
index 0000000..f5c55f1
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ListenerList.java
@@ -0,0 +1,194 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.harmony.awt;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * List of AWT listeners. It is for 3 purposes.
+ * 1. To support list modification from listeners
+ * 2. To ensure call for all listeners as atomic operation
+ * 3. To support system listeners that are needed for built-in AWT components
+ */
+public class ListenerList<T extends EventListener> implements Serializable {
+    private static final long serialVersionUID = 9180703263299648154L;
+
+    private transient ArrayList<T> systemList;
+    private transient ArrayList<T> userList;
+    
+    public ListenerList() {
+        super();
+    }
+
+    /**
+     * Adds system listener to this list.
+     *
+     * @param listener - listener to be added.
+     */
+    public void addSystemListener(T listener) {
+        if (systemList == null) {
+            systemList = new ArrayList<T>();
+        }
+        systemList.add(listener);
+    }
+
+    /**
+     * Adds user (public) listener to this list.
+     *
+     * @param listener - listener to be added.
+     */
+    public void addUserListener(T listener) {
+        if (listener == null) {
+            return;
+        }
+        // transactionally replace old list
+        synchronized (this) {
+            if (userList == null) {
+                userList = new ArrayList<T>();
+                userList.add(listener);
+                return;
+            }
+            ArrayList<T> newList = new ArrayList<T>(userList);
+            newList.add(listener);
+            userList = newList;
+        }
+    }
+
+    /**
+     * Removes user (public) listener to this list.
+     *
+     * @param listener - listener to be removed.
+     */
+    public void removeUserListener(Object listener) {
+        if (listener == null) {
+            return;
+        }
+        // transactionally replace old list
+        synchronized (this) {
+            if (userList == null || !userList.contains(listener)) {
+                return;
+            }
+            ArrayList<T> newList = new ArrayList<T>(userList);
+            newList.remove(listener);
+            userList = (newList.size() > 0 ? newList : null);
+        }
+    }
+
+    /**
+     * Gets all user (public) listeners in one array.
+     *
+     * @param emptyArray - empty array, it's for deriving particular listeners class.
+     * @return array of all user listeners.
+     */
+    public <AT> AT[] getUserListeners(AT[] emptyArray){
+        synchronized (this) {
+            return (userList != null ? userList.toArray(emptyArray) : emptyArray);
+
+        }
+    }
+
+    /**
+     * Gets all user (public) listeners in one list.
+     *
+     * @return list of all user listeners.
+     */
+    public List<T> getUserListeners() {
+        synchronized (this) {
+            if (userList == null || userList.isEmpty()) {
+                return Collections.emptyList();
+            }
+            return new ArrayList<T>(userList);
+        }
+    }
+    
+    public List<T> getSystemListeners() {
+        synchronized (this) {
+            if (systemList == null || systemList.isEmpty()) {
+                return Collections.emptyList();
+            }
+            return new ArrayList<T>(systemList);
+        }
+    }
+
+    /**
+     * Gets iterator for user listeners.
+     *
+     * @return iterator for user listeners.
+     */
+    public Iterator<T> getUserIterator() {
+        synchronized (this) {
+            if (userList == null) {
+                List<T> emptyList = Collections.emptyList();
+                return emptyList.iterator();
+            }
+            return new ReadOnlyIterator<T>(userList.iterator());
+        }
+    }
+
+    /**
+     * Gets iterator for system listeners.
+     *
+     * @return iterator for system listeners.
+     */
+    public Iterator<T> getSystemIterator() {
+        return systemList.iterator();
+    }
+
+    private static ArrayList<?> getOnlySerializable(ArrayList<?> list) {
+        if (list == null) {
+            return null;
+        }
+
+        ArrayList<Object> result = new ArrayList<Object>();
+        for (Iterator<?> it = list.iterator(); it.hasNext();) {
+            Object obj = it.next();
+            if (obj instanceof Serializable) {
+                result.add(obj);
+            }
+        }
+
+        return (result.size() != 0) ? result : null;
+    }
+
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+
+        stream.defaultWriteObject();
+
+        stream.writeObject(getOnlySerializable(systemList));
+        stream.writeObject(getOnlySerializable(userList));
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream stream)
+            throws IOException, ClassNotFoundException {
+
+        stream.defaultReadObject();
+
+        systemList = (ArrayList<T>)stream.readObject();
+        userList = (ArrayList<T>)stream.readObject();
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/ReadOnlyIterator.java b/awt/org/apache/harmony/awt/ReadOnlyIterator.java
new file mode 100644
index 0000000..671653f
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ReadOnlyIterator.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+import java.util.Iterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * ReadOnlyIterator
+ */
+public final class ReadOnlyIterator<E> implements Iterator<E> {
+
+    private final Iterator<E> it;
+
+    public ReadOnlyIterator(Iterator<E> it) {
+        if (it == null) {
+            throw new NullPointerException();
+        }
+        this.it = it;
+    }
+
+    public void remove() {
+        // awt.50=Iterator is read-only
+        throw new UnsupportedOperationException(Messages.getString("awt.50")); //$NON-NLS-1$
+    }
+
+    public boolean hasNext() {
+        return it.hasNext();
+    }
+
+    public E next() {
+        return it.next();
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java b/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java
new file mode 100644
index 0000000..bd5f6c6
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java
@@ -0,0 +1,65 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 23.11.2005
+ *
+ */
+
+
+package org.apache.harmony.awt.gl;
+
+import java.awt.Image;
+import java.awt.image.DataBuffer;
+import java.awt.image.IndexColorModel;
+import java.awt.image.DataBufferInt;
+
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+
+/**
+ * This class give an opportunity to get access to private data of 
+ * some java.awt.image classes 
+ * Implementation of this class placed in java.awt.image package
+ */
+
+public abstract class AwtImageBackdoorAccessor {
+
+    static protected AwtImageBackdoorAccessor inst;
+
+    public static AwtImageBackdoorAccessor getInstance(){
+        // First we need to run the static initializer in the DataBuffer class to resolve inst.
+        new DataBufferInt(0);
+        return inst;
+    }
+
+    public abstract Surface getImageSurface(Image image);
+    public abstract boolean isGrayPallete(IndexColorModel icm);
+
+    public abstract Object getData(DataBuffer db);
+    public abstract int[] getDataInt(DataBuffer db);
+    public abstract byte[] getDataByte(DataBuffer db);
+    public abstract short[] getDataShort(DataBuffer db);
+    public abstract short[] getDataUShort(DataBuffer db);
+    public abstract double[] getDataDouble(DataBuffer db);
+    public abstract float[] getDataFloat(DataBuffer db);
+    public abstract void releaseData(DataBuffer db);
+    
+    public abstract void addDataBufferListener(DataBuffer db, DataBufferListener listener);
+    public abstract void removeDataBufferListener(DataBuffer db);
+    public abstract void validate(DataBuffer db);
+}
diff --git a/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java b/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java
new file mode 100644
index 0000000..a33c38b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java
@@ -0,0 +1,1132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.PaintContext;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.WritableRaster;
+import java.awt.image.renderable.RenderableImage;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.RoundRectangle2D;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.OffscreenImage;
+import org.apache.harmony.awt.gl.render.Blitter;
+import org.apache.harmony.awt.gl.render.JavaArcRasterizer;
+import org.apache.harmony.awt.gl.render.JavaLineRasterizer;
+import org.apache.harmony.awt.gl.render.JavaShapeRasterizer;
+import org.apache.harmony.awt.gl.render.JavaTextRenderer;
+import org.apache.harmony.awt.gl.render.NullBlitter;
+
+/*
+ * List of abstract methods to implement in subclusses
+ * Graphics.copyArea(int x, int y, int width, int height, int dx, int dy)
+ * Graphics.create()
+ * Graphics2D.getDeviceConfiguration()
+ * CommonGraphics2D.fillMultiRectAreaColor(MultiRectArea mra);
+ * CommonGraphics2D.fillMultiRectAreaPaint(MultiRectArea mra);
+ */
+
+/**
+ * CommonGraphics2D class is a super class for all system-dependent
+ * implementations. It implements major part of Graphics and Graphics2D
+ * abstract methods.
+ * <h2>CommonGraphics2D Class Internals</h2>
+ * <h3>Line and Shape Rasterizers</h3>
+ * <p>
+ * The CommonGraphics2D class splits all shapes into a set of rectangles 
+ * to unify the drawing process for different operating systems and architectures. 
+ * For this purpose Java 2D* uses the JavaShapeRasterizer and the JavaLineRasterizer 
+ * classes from the org.apache.harmony.awt.gl.render package. The JavaShapeRasterizer 
+ * class splits an object implementing a Shape interface into a set of rectangles and 
+ * produces a MultiRectArea object. The JavaLineRasterizer class makes line drawing 
+ * more accurate and processes lines with strokes, which are instances of the BasicStroke 
+ * class.
+ * </p>
+ * <p>
+ * To port the shape drawing to another platform you just need to override 
+ * rectangle-drawing methods. However, if your operating system has functions to draw 
+ * particular shapes, you can optimize your subclass of the CommonGraphics2D class by 
+ * using this functionality in overridden methods.
+ * </p>
+
+ * <h3>Blitters</h3>
+ * <p>
+ * Blitter classes draw images on the display or buffered images. All blitters inherit 
+ * the org.apache.harmony.awt.gl.render.Blitter interface.
+ * </p>
+ * <p>Blitters are divided into:
+ * <ul>
+ * <li>Native blitters for simple types of images, which the underlying native library 
+ * can draw.</li> 
+ * <li>Java* blitters for those types of images, which the underlying native library 
+ * cannot handle.</li>
+ * </ul></p>
+ * <p>
+ * DRL Java 2D* also uses blitters to fill the shapes and the user-defined subclasses 
+ * of the java.awt.Paint class with paints, which the system does not support.
+ * </p>
+ *
+ *<h3>Text Renderers</h3>
+ *<p>
+ *Text renderers draw strings and glyph vectors. All text renderers are subclasses 
+ *of the org.apache.harmony.awt.gl.TextRenderer class.
+ *</p>
+ *
+ */
+public abstract class CommonGraphics2D extends Graphics2D {
+    protected Surface dstSurf = null;
+    protected Blitter blitter = NullBlitter.getInstance();
+    protected RenderingHints hints = new RenderingHints(null);
+
+    // Clipping things
+    protected MultiRectArea clip = null;
+
+    protected Paint paint = Color.WHITE;
+    protected Color fgColor = Color.WHITE;
+    protected Color bgColor = Color.BLACK;
+
+    protected Composite composite = AlphaComposite.SrcOver;
+
+    protected Stroke stroke = new BasicStroke();
+
+    //TODO: Think more about FontRenderContext
+    protected FontRenderContext frc = new FontRenderContext(null, false, false);
+
+    protected JavaShapeRasterizer jsr = new JavaShapeRasterizer();
+
+    protected Font font = new Font("Dialog", Font.PLAIN, 12);; //$NON-NLS-1$
+
+    protected TextRenderer jtr = JavaTextRenderer.inst;
+
+    // Current graphics transform
+    protected AffineTransform transform = new AffineTransform();
+    protected double[] matrix = new double[6];
+
+    // Original user->device translation as transform and point
+    //public AffineTransform origTransform = new AffineTransform();
+    public Point origPoint = new Point(0, 0);
+
+
+    // Print debug output or not
+    protected static final boolean debugOutput = "1".equals(System.getProperty("g2d.debug")); //$NON-NLS-1$ //$NON-NLS-2$
+
+    // Constructors
+    protected CommonGraphics2D() {
+    }
+
+    protected CommonGraphics2D(int tx, int ty) {
+        this(tx, ty, null);
+    }
+
+    protected CommonGraphics2D(int tx, int ty, MultiRectArea clip) {
+        setTransform(AffineTransform.getTranslateInstance(tx, ty));
+        //origTransform = AffineTransform.getTranslateInstance(tx, ty);
+        origPoint = new Point(tx, ty);
+        setClip(clip);
+    }
+
+    // Public methods
+    @Override
+    public void addRenderingHints(Map<?,?> hints) {
+        this.hints.putAll(hints);
+    }
+
+    @Override
+    public void clearRect(int x, int y, int width, int height) {
+        Color c = getColor();
+        Paint p = getPaint();
+        setColor(getBackground());
+        fillRect(x, y, width, height);
+        setColor(c);
+        setPaint(p);
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.clearRect("+x+", "+y+", "+width+", "+height+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    @Override
+    public void clipRect(int x, int y, int width, int height) {
+        clip(new Rectangle(x, y, width, height));
+    }
+
+
+    @Override
+    public void clip(Shape s) {
+        if (s == null) {
+            clip = null;
+            return;
+        }
+
+        MultiRectArea mra = null;
+        if (s instanceof MultiRectArea) {
+            mra = new MultiRectArea((MultiRectArea)s);
+            mra.translate((int)transform.getTranslateX(), (int)transform.getTranslateY());
+        } else {
+            int type = transform.getType();
+            if(s instanceof Rectangle && (type & (AffineTransform.TYPE_IDENTITY |
+                AffineTransform.TYPE_TRANSLATION)) != 0){
+                    mra = new MultiRectArea((Rectangle)s);
+                    if(type == AffineTransform.TYPE_TRANSLATION){
+                        mra.translate((int)transform.getTranslateX(), (int)transform.getTranslateY());
+                    }
+            } else {
+                s = transform.createTransformedShape(s);
+                mra = jsr.rasterize(s, 0.5);
+            }
+        }
+
+        if (clip == null) {
+            setTransformedClip(mra);
+        } else {
+            clip.intersect(mra);
+            setTransformedClip(clip);
+        }
+    }
+
+    @Override
+    public void dispose() {
+        // Do nothing for Java only classes
+    }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Draw methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void draw(Shape s) {
+        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1) {
+            //TODO: Think about drawing the shape in one fillMultiRectArea call
+            BasicStroke bstroke = (BasicStroke)stroke;
+            JavaLineRasterizer.LineDasher ld = (bstroke.getDashArray() == null)?null:new JavaLineRasterizer.LineDasher(bstroke.getDashArray(), bstroke.getDashPhase());
+            PathIterator pi = s.getPathIterator(transform, 0.5);
+            float []points = new float[6];
+            int x1 = Integer.MIN_VALUE;
+            int y1 = Integer.MIN_VALUE;
+            int cx1 = Integer.MIN_VALUE;
+            int cy1 = Integer.MIN_VALUE;
+            while (!pi.isDone()) {
+                switch (pi.currentSegment(points)) {
+                    case PathIterator.SEG_MOVETO:
+                        x1 = (int)Math.floor(points[0]);
+                        y1 = (int)Math.floor(points[1]);
+                        cx1 = x1;
+                        cy1 = y1;
+                        break;
+                    case PathIterator.SEG_LINETO:
+                        int x2 = (int)Math.floor(points[0]);
+                        int y2 = (int)Math.floor(points[1]);
+                        fillMultiRectArea(JavaLineRasterizer.rasterize(x1, y1, x2, y2, null, ld, false));
+                        x1 = x2;
+                        y1 = y2;
+                        break;
+                    case PathIterator.SEG_CLOSE:
+                        x2 = cx1;
+                        y2 = cy1;
+                        fillMultiRectArea(JavaLineRasterizer.rasterize(x1, y1, x2, y2, null, ld, false));
+                        x1 = x2;
+                        y1 = y2;
+                        break;
+                }
+                pi.next();
+            }
+        } else {
+            s = stroke.createStrokedShape(s);
+            s = transform.createTransformedShape(s);
+            fillMultiRectArea(jsr.rasterize(s, 0.5));
+        }
+    }
+
+    @Override
+    public void drawArc(int x, int y, int width, int height, int sa, int ea) {
+        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1 &&
+                ((BasicStroke)stroke).getDashArray() == null && 
+                (transform.isIdentity() || transform.getType() == AffineTransform.TYPE_TRANSLATION)) {
+            Point p = new Point(x, y);
+            transform.transform(p, p);
+            MultiRectArea mra = JavaArcRasterizer.rasterize(x, y, width, height, sa, ea, clip);
+            fillMultiRectArea(mra);
+            return;
+        }
+        draw(new Arc2D.Float(x, y, width, height, sa, ea, Arc2D.OPEN));
+    }
+
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, Color bgcolor,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, (AffineTransform) transform.clone(),
+                    composite, bgcolor, clip);
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, ImageObserver imageObserver) {
+        return drawImage(image, x, y, null, imageObserver);
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, int width, int height,
+            Color bgcolor, ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(width == 0 || height == 0) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            if(w == width && h == height){
+                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                        (AffineTransform) transform.clone(),
+                        composite, bgcolor, clip);
+            }else{
+                AffineTransform xform = new AffineTransform();
+                xform.setToScale((float)width / w, (float)height / h);
+                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                        (AffineTransform) transform.clone(),
+                        xform, composite, bgcolor, clip);
+            }
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, int width, int height,
+            ImageObserver imageObserver) {
+        return drawImage(image, x, y, width, height, null, imageObserver);
+    }
+
+    @Override
+    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+            int sx1, int sy1, int sx2, int sy2, Color bgcolor,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(dx1 == dx2 || dy1 == dy2 || sx1 == sx2 || sy1 == sy2) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+
+            int dstX = dx1;
+            int dstY = dy1;
+            int srcX = sx1;
+            int srcY = sy1;
+
+            int dstW = dx2 - dx1;
+            int dstH = dy2 - dy1;
+            int srcW = sx2 - sx1;
+            int srcH = sy2 - sy1;
+
+            if(srcW == dstW && srcH == dstH){
+                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
+                        (AffineTransform) transform.clone(),
+                        composite, bgcolor, clip);
+            }else{
+                AffineTransform xform = new AffineTransform();
+                xform.setToScale((float)dstW / srcW, (float)dstH / srcH);
+                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
+                        (AffineTransform) transform.clone(),
+                        xform, composite, bgcolor, clip);
+            }
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+            int sx1, int sy1, int sx2, int sy2, ImageObserver imageObserver) {
+
+        return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
+                imageObserver);
+     }
+
+    @Override
+    public void drawImage(BufferedImage bufImage, BufferedImageOp op,
+            int x, int y) {
+
+        if(bufImage == null) {
+            return;
+        }
+
+        if(op == null) {
+            drawImage(bufImage, x, y, null);
+        } else if(op instanceof AffineTransformOp){
+            AffineTransformOp atop = (AffineTransformOp) op;
+            AffineTransform xform = atop.getTransform();
+            Surface srcSurf = Surface.getImageSurface(bufImage);
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                    (AffineTransform) transform.clone(), xform,
+                    composite, null, clip);
+        } else {
+            bufImage = op.filter(bufImage, null);
+            Surface srcSurf = Surface.getImageSurface(bufImage);
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                    (AffineTransform) transform.clone(),
+                    composite, null, clip);
+        }
+    }
+
+    @Override
+    public boolean drawImage(Image image, AffineTransform trans,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(trans == null || trans.isIdentity()) {
+            return drawImage(image, 0, 0, imageObserver);
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            AffineTransform xform = (AffineTransform) transform.clone();
+            xform.concatenate(trans);
+            blitter.blit(0, 0, srcSurf, 0, 0, dstSurf, w, h, xform, composite,
+                    null, clip);
+        }
+        return done;
+    }
+
+    @Override
+    public void drawLine(int x1, int y1, int x2, int y2) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.drawLine("+x1+", "+y1+", "+x2+", "+y2+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+
+        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1) {
+            BasicStroke bstroke = (BasicStroke)stroke;
+            Point p1 = new Point(x1, y1);
+            Point p2 = new Point(x2, y2);
+            transform.transform(p1, p1);
+            transform.transform(p2, p2);
+            JavaLineRasterizer.LineDasher ld = (bstroke.getDashArray() == null)?null:new JavaLineRasterizer.LineDasher(bstroke.getDashArray(), bstroke.getDashPhase());
+            MultiRectArea mra = JavaLineRasterizer.rasterize(p1.x, p1.y, p2.x, p2.y, null, ld, false);
+            fillMultiRectArea(mra);
+            return;
+        }
+        draw(new Line2D.Float(x1, y1, x2, y2));
+    }
+
+    @Override
+    public void drawOval(int x, int y, int width, int height) {
+        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1 &&
+                ((BasicStroke)stroke).getDashArray() == null && 
+                (transform.isIdentity() || transform.getType() == AffineTransform.TYPE_TRANSLATION)) {
+            Point p = new Point(x, y);
+            transform.transform(p, p);
+            MultiRectArea mra = JavaArcRasterizer.rasterize(x, y, width, height, 0, 360, clip);
+            fillMultiRectArea(mra);
+            return;
+        }
+        draw(new Ellipse2D.Float(x, y, width, height));
+    }
+
+    @Override
+    public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) {
+        draw(new Polygon(xpoints, ypoints, npoints));
+    }
+
+    @Override
+    public void drawPolygon(Polygon polygon) {
+        draw(polygon);
+    }
+
+    @Override
+    public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) {
+        for (int i = 0; i < npoints-1; i++) {
+            drawLine(xpoints[i], ypoints[i], xpoints[i+1], ypoints[i+1]);
+        }
+    }
+
+    @Override
+    public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
+        if (img == null) {
+            return;
+        }
+
+        double scaleX = xform.getScaleX();
+        double scaleY = xform.getScaleY();
+        if (scaleX == 1 && scaleY == 1) {
+            drawRenderedImage(img.createDefaultRendering(), xform);
+        } else {
+            int width = (int)Math.round(img.getWidth()*scaleX);
+            int height = (int)Math.round(img.getHeight()*scaleY);
+            xform = (AffineTransform)xform.clone();
+            xform.scale(1, 1);
+            drawRenderedImage(img.createScaledRendering(width, height, null), xform);
+        }
+    }
+
+    @Override
+    public void drawRenderedImage(RenderedImage rimg, AffineTransform xform) {
+        if (rimg == null) {
+            return;
+        }
+
+        Image img = null;
+
+        if (rimg instanceof Image) {
+            img = (Image)rimg;
+        } else {
+            //TODO: Create new class to provide Image interface for RenderedImage or rewrite this method
+            img = new BufferedImage(rimg.getColorModel(), rimg.copyData(null), false, null);
+        }
+
+        drawImage(img, xform, null);
+    }
+
+    @Override
+    public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.drawRoundRect("+x+", "+y+", "+width+", "+height+","+arcWidth+", "+arcHeight+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+        }
+
+        draw(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
+    }
+
+
+
+
+
+    /***************************************************************************
+     *
+     *  String methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void drawString(AttributedCharacterIterator iterator, float x, float y) {
+        GlyphVector gv = font.createGlyphVector(frc, iterator);
+        drawGlyphVector(gv, x, y);
+    }
+
+    @Override
+    public void drawString(AttributedCharacterIterator iterator, int x, int y) {
+        drawString(iterator, (float)x, (float)y);
+    }
+
+    @Override
+    public void drawString(String str, int x, int y) {
+        drawString(str, (float)x, (float)y);
+    }
+
+    @Override
+    public void drawString(String str, float x, float y) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.drawString("+str+", "+x+", "+y+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+        }
+
+        AffineTransform at = (AffineTransform)this.getTransform().clone();
+        AffineTransform fontTransform = font.getTransform();
+        at.concatenate(fontTransform);
+
+        double[] matrix = new double[6];
+        if (!at.isIdentity()){
+
+            int atType = at.getType();
+            at.getMatrix(matrix);
+
+            // TYPE_TRANSLATION
+            if (atType == AffineTransform.TYPE_TRANSLATION){
+                jtr.drawString(this, str,
+                        (float)(x+fontTransform.getTranslateX()),
+                        (float)(y+fontTransform.getTranslateY()));
+                return;
+            }
+            // TODO: we use slow type of drawing strings when Font object
+            // in Graphics has transforms, we just fill outlines. New textrenderer
+            // is to be implemented.
+            Shape sh = font.createGlyphVector(this.getFontRenderContext(), str).getOutline(x, y);
+            this.fill(sh);
+
+        } else {
+            jtr.drawString(this, str, x, y);
+        }
+
+    }
+
+    @Override
+    public void drawGlyphVector(GlyphVector gv, float x, float y) {
+
+        AffineTransform at = gv.getFont().getTransform();
+
+        double[] matrix = new double[6];
+        if ((at != null) && (!at.isIdentity())){
+
+            int atType = at.getType();
+            at.getMatrix(matrix);
+
+            // TYPE_TRANSLATION
+            if ((atType == AffineTransform.TYPE_TRANSLATION) &&
+                ((gv.getLayoutFlags() & GlyphVector.FLAG_HAS_TRANSFORMS) == 0)){
+                jtr.drawGlyphVector(this, gv, (int)(x+matrix[4]), (int)(y+matrix[5]));
+                return;
+            }
+        } else {
+            if (((gv.getLayoutFlags() & GlyphVector.FLAG_HAS_TRANSFORMS) == 0)){
+                jtr.drawGlyphVector(this, gv, x, y);
+                return;
+            }
+        }
+
+        // TODO: we use slow type of drawing strings when Font object
+        // in Graphics has transforms, we just fill outlines. New textrenderer
+        // is to be implemented.
+
+        Shape sh = gv.getOutline(x, y);
+        this.fill(sh);
+
+        }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Fill methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void fill(Shape s) {
+        s = transform.createTransformedShape(s);
+        MultiRectArea mra = jsr.rasterize(s, 0.5);
+        fillMultiRectArea(mra);
+    }
+
+    @Override
+    public void fillArc(int x, int y, int width, int height, int sa, int ea) {
+        fill(new Arc2D.Float(x, y, width, height, sa, ea, Arc2D.PIE));
+    }
+
+    @Override
+    public void fillOval(int x, int y, int width, int height) {
+        fill(new Ellipse2D.Float(x, y, width, height));
+    }
+
+    @Override
+    public void fillPolygon(int[] xpoints, int[] ypoints, int npoints) {
+        fill(new Polygon(xpoints, ypoints, npoints));
+    }
+
+    @Override
+    public void fillPolygon(Polygon polygon) {
+        fill(polygon);
+    }
+
+    @Override
+    public void fillRect(int x, int y, int width, int height) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.fillRect("+x+", "+y+", "+width+", "+height+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+
+        fill(new Rectangle(x, y, width, height));
+    }
+
+    @Override
+    public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.fillRoundRect("+x+", "+y+", "+width+", "+height+","+arcWidth+", "+arcHeight+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+        }
+
+        fill(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
+    }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Get methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public Color getBackground() {
+        return bgColor;
+    }
+
+    @Override
+    public Shape getClip() {
+        if (clip == null) {
+            return null;
+        }
+
+        MultiRectArea res = new MultiRectArea(clip);
+        res.translate(-Math.round((float)transform.getTranslateX()), -Math.round((float)transform.getTranslateY()));
+        return res;
+    }
+
+    @Override
+    public Rectangle getClipBounds() {
+        if (clip == null) {
+            return null;
+        }
+
+        Rectangle res = (Rectangle) clip.getBounds().clone();
+        res.translate(-Math.round((float)transform.getTranslateX()), -Math.round((float)transform.getTranslateY()));
+        return res;
+    }
+
+    @Override
+    public Color getColor() {
+        return fgColor;
+    }
+
+    @Override
+    public Composite getComposite() {
+        return composite;
+    }
+
+    @Override
+    public Font getFont() {
+        return font;
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public FontMetrics getFontMetrics(Font font) {
+        return Toolkit.getDefaultToolkit().getFontMetrics(font);
+    }
+
+    @Override
+    public FontRenderContext getFontRenderContext() {
+        return frc;
+    }
+
+    @Override
+    public Paint getPaint() {
+        return paint;
+    }
+
+    @Override
+    public Object getRenderingHint(RenderingHints.Key key) {
+        return hints.get(key);
+    }
+
+    @Override
+    public RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    @Override
+    public Stroke getStroke() {
+        return stroke;
+    }
+
+    @Override
+    public AffineTransform getTransform() {
+        return (AffineTransform)transform.clone();
+    }
+
+    @Override
+    public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
+        //TODO: Implement method....
+        return false;
+    }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Transformation methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void rotate(double theta) {
+        transform.rotate(theta);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void rotate(double theta, double x, double y) {
+        transform.rotate(theta, x, y);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void scale(double sx, double sy) {
+        transform.scale(sx, sy);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void shear(double shx, double shy) {
+        transform.shear(shx, shy);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void transform(AffineTransform at) {
+        transform.concatenate(at);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void translate(double tx, double ty) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.translate("+tx+", "+ty+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        transform.translate(tx, ty);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void translate(int tx, int ty) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.translate("+tx+", "+ty+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        transform.translate(tx, ty);
+        transform.getMatrix(matrix);
+    }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Set methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void setBackground(Color color) {
+        bgColor = color;
+    }
+
+    @Override
+    public void setClip(int x, int y, int width, int height) {
+        setClip(new Rectangle(x, y, width, height));
+    }
+
+    @Override
+    public void setClip(Shape s) {
+        if (s == null) {
+            setTransformedClip(null);
+            if (debugOutput) {
+                System.err.println("CommonGraphics2D.setClip(null)"); //$NON-NLS-1$
+            }
+            return;
+        }
+
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.setClip("+s.getBounds()+")"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (s instanceof MultiRectArea) {
+            MultiRectArea nclip = new MultiRectArea((MultiRectArea)s);
+            nclip.translate(Math.round((float)transform.getTranslateX()), Math.round((float)transform.getTranslateY()));
+            setTransformedClip(nclip);
+        } else {
+            int type = transform.getType();
+            if(s instanceof Rectangle && (type & (AffineTransform.TYPE_IDENTITY |
+                AffineTransform.TYPE_TRANSLATION)) != 0){
+                    MultiRectArea nclip = new MultiRectArea((Rectangle)s);
+                    if(type == AffineTransform.TYPE_TRANSLATION){
+                        nclip.translate((int)transform.getTranslateX(), (int)transform.getTranslateY());
+                    }
+                    setTransformedClip(nclip);
+            } else {
+                s = transform.createTransformedShape(s);
+                setTransformedClip(jsr.rasterize(s, 0.5));
+            }
+        }
+    }
+
+    @Override
+    public void setColor(Color color) {
+        if (color != null) {
+            fgColor = color;
+            paint = color;
+        }
+    }
+
+    @Override
+    public void setComposite(Composite composite) {
+        this.composite = composite;
+    }
+
+    @Override
+    public void setFont(Font font) {
+        this.font = font;
+    }
+
+    @Override
+    public void setPaint(Paint paint) {
+        if (paint == null)
+            return;
+            
+        this.paint = paint;
+        if (paint instanceof Color) {
+            fgColor = (Color)paint;
+        }
+    }
+
+    @Override
+    public void setPaintMode() {
+        composite = AlphaComposite.SrcOver;
+    }
+
+    @Override
+    public void setRenderingHint(RenderingHints.Key key, Object value) {
+        hints.put(key, value);
+    }
+
+    @Override
+    public void setRenderingHints(Map<?,?> hints) {
+        this.hints.clear();
+        this.hints.putAll(hints);
+    }
+
+    @Override
+    public void setStroke(Stroke stroke) {
+        this.stroke = stroke;
+    }
+
+    @Override
+    public void setTransform(AffineTransform transform) {
+        this.transform = transform;
+
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void setXORMode(Color color) {
+        composite = new XORComposite(color);
+    }
+
+
+    // Protected methods
+    protected void setTransformedClip(MultiRectArea clip) {
+        this.clip = clip;
+    }
+
+    /**
+     * This method fills the given MultiRectArea with current paint.
+     * It calls fillMultiRectAreaColor and fillMultiRectAreaPaint 
+     * methods depending on the type of current paint.
+     * @param mra MultiRectArea to fill
+     */
+    protected void fillMultiRectArea(MultiRectArea mra) {
+        if (clip != null) {
+            mra.intersect(clip);
+        }
+
+        // Return if all stuff is clipped
+        if (mra.rect[0] < 5) {
+            return;
+        }
+
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.fillMultiRectArea("+mra+")"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (paint instanceof Color){
+            fillMultiRectAreaColor(mra);
+        }else{
+            fillMultiRectAreaPaint(mra);
+        }
+    }
+
+    /**
+     * This method fills the given MultiRectArea with solid color.
+     * @param mra MultiRectArea to fill
+     */
+    protected void fillMultiRectAreaColor(MultiRectArea mra) {
+        fillMultiRectAreaPaint(mra);
+    }
+
+    /**
+     * This method fills the given MultiRectArea with any paint.
+     * @param mra MultiRectArea to fill
+     */
+    protected void fillMultiRectAreaPaint(MultiRectArea mra) {
+        Rectangle rec = mra.getBounds();
+        int x = rec.x;
+        int y = rec.y;
+        int w = rec.width;
+        int h = rec.height;
+        if(w <= 0 || h <= 0) {
+            return;
+        }
+        PaintContext pc = paint.createContext(null, rec, rec, transform, hints);
+        Raster r = pc.getRaster(x, y, w, h);
+        WritableRaster wr;
+        if(r instanceof WritableRaster){
+            wr = (WritableRaster) r;
+        }else{
+            wr = r.createCompatibleWritableRaster();
+            wr.setRect(r);
+        }
+        Surface srcSurf = new ImageSurface(pc.getColorModel(), wr);
+        blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                composite, null, mra);
+        srcSurf.dispose();
+    }
+
+    /**
+     * Copies graphics class fields. 
+     * Used in create method
+     * 
+     * @param copy Graphics class to copy
+     */
+    protected void copyInternalFields(CommonGraphics2D copy) {
+        if (clip == null) {
+            copy.setTransformedClip(null);
+        } else {
+            copy.setTransformedClip(new MultiRectArea(clip));
+        }
+        copy.setBackground(bgColor);
+        copy.setColor(fgColor);
+        copy.setPaint(paint);
+        copy.setComposite(composite);
+        copy.setStroke(stroke);
+        copy.setFont(font);
+        copy.setTransform(new AffineTransform(transform));
+        //copy.origTransform = new AffineTransform(origTransform);
+        copy.origPoint = new Point(origPoint);
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java b/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java
new file mode 100644
index 0000000..27e3ef0
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java
@@ -0,0 +1,78 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko, Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.peer.FontPeer;
+
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+
+/**
+ * Common GraphicsFactory implementation
+ *
+ */
+public abstract class CommonGraphics2DFactory implements GraphicsFactory {
+    
+    // static instance of CommonGraphics2DFactory
+    public static CommonGraphics2DFactory inst;
+
+    /**
+     * Returns FontMetrics object that keeps metrics of the specified font.
+     * 
+     * @param font specified Font
+     * @return FontMetrics object corresponding to the specified Font object
+     */
+    public FontMetrics getFontMetrics(Font font) {
+        FontMetrics fm;
+        for (FontMetrics element : cacheFM) {
+            fm = element;
+            if (fm == null){
+                break;
+            }
+
+            if (fm.getFont().equals(font)){
+                return fm;
+            }
+        }
+        fm = new FontMetricsImpl(font);
+
+        System.arraycopy(cacheFM, 0, cacheFM, 1, cacheFM.length -1);
+        cacheFM[0] = fm;
+
+        return fm;
+    }
+    // Font methods
+
+    public FontPeer getFontPeer(Font font) {
+        return getFontManager().getFontPeer(font.getName(), font.getStyle(), font.getSize());
+    }
+    
+    /**
+     * Embeds font from gile with specified path into the system. 
+     * 
+     * @param fontFilePath path to the font file 
+     * @return Font object that was created from the file.
+     */
+    public abstract Font embedFont(String fontFilePath);
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java b/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java
new file mode 100644
index 0000000..5c78e50
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java
@@ -0,0 +1,67 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko, Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import org.apache.harmony.awt.gl.image.BufferedImageGraphics2D;
+
+/**
+ * Common GraphicsEnvironment implementation
+ *
+ */
+public abstract class CommonGraphicsEnvironment extends GraphicsEnvironment {
+
+    @Override
+    public Graphics2D createGraphics(BufferedImage bufferedImage) {
+        return new BufferedImageGraphics2D(bufferedImage);
+    }
+
+    @Override
+    public String[] getAvailableFontFamilyNames(Locale locale) {
+        Font[] fonts = getAllFonts();
+        ArrayList<String> familyNames = new ArrayList<String>();
+
+        for (Font element : fonts) {
+            String name = element.getFamily(locale);
+            if (!familyNames.contains(name)) {
+                familyNames.add(name);
+            }
+        }
+
+        return familyNames.toArray(new String[familyNames.size()]);
+    }
+
+    @Override
+    public Font[] getAllFonts() {
+        return CommonGraphics2DFactory.inst.getFontManager().getAllFonts();
+    }
+
+    @Override
+    public String[] getAvailableFontFamilyNames() {
+        return CommonGraphics2DFactory.inst.getFontManager().getAllFamilies();
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/Crossing.java b/awt/org/apache/harmony/awt/gl/Crossing.java
new file mode 100644
index 0000000..ae7fb0e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/Crossing.java
@@ -0,0 +1,889 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Shape;
+import java.awt.geom.PathIterator;
+
+public class Crossing {
+
+    /**
+     * Allowable tolerance for bounds comparison
+     */
+    static final double DELTA = 1E-5;
+    
+    /**
+     * If roots have distance less then <code>ROOT_DELTA</code> they are double
+     */
+    static final double ROOT_DELTA = 1E-10;
+    
+    /**
+     * Rectangle cross segment
+     */
+    public static final int CROSSING = 255;
+    
+    /**
+     * Unknown crossing result
+     */
+    static final int UNKNOWN = 254;
+
+    /**
+     * Solves quadratic equation
+     * @param eqn - the coefficients of the equation
+     * @param res - the roots of the equation
+     * @return a number of roots
+     */
+    public static int solveQuad(double eqn[], double res[]) {
+        double a = eqn[2];
+        double b = eqn[1];
+        double c = eqn[0];
+        int rc = 0;
+        if (a == 0.0) {
+            if (b == 0.0) {
+                return -1;
+            }
+            res[rc++] = -c / b;
+        } else {
+            double d = b * b - 4.0 * a * c;
+            // d < 0.0
+            if (d < 0.0) {
+                return 0;
+            }
+            d = Math.sqrt(d);
+            res[rc++] = (- b + d) / (a * 2.0);
+            // d != 0.0
+            if (d != 0.0) {
+                res[rc++] = (- b - d) / (a * 2.0);
+            }
+        }
+        return fixRoots(res, rc);
+    }
+
+    /**
+     * Solves cubic equation
+     * @param eqn - the coefficients of the equation
+     * @param res - the roots of the equation
+     * @return a number of roots
+     */
+    public static int solveCubic(double eqn[], double res[]) {
+        double d = eqn[3];
+        if (d == 0) {
+            return solveQuad(eqn, res);
+        }
+        double a = eqn[2] / d;
+        double b = eqn[1] / d;
+        double c = eqn[0] / d;
+        int rc = 0;
+
+        double Q = (a * a - 3.0 * b) / 9.0;
+        double R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
+        double Q3 = Q * Q * Q;
+        double R2 = R * R;
+        double n = - a / 3.0;
+
+        if (R2 < Q3) {
+            double t = Math.acos(R / Math.sqrt(Q3)) / 3.0;
+            double p = 2.0 * Math.PI / 3.0;
+            double m = -2.0 * Math.sqrt(Q);
+            res[rc++] = m * Math.cos(t) + n;
+            res[rc++] = m * Math.cos(t + p) + n;
+            res[rc++] = m * Math.cos(t - p) + n;
+        } else {
+//          Debug.println("R2 >= Q3 (" + R2 + "/" + Q3 + ")");
+            double A = Math.pow(Math.abs(R) + Math.sqrt(R2 - Q3), 1.0 / 3.0);
+            if (R > 0.0) {
+                A = -A;
+            }
+//          if (A == 0.0) {
+            if (-ROOT_DELTA < A && A < ROOT_DELTA) {
+                res[rc++] = n;
+            } else {
+                double B = Q / A;
+                res[rc++] = A + B + n;
+//              if (R2 == Q3) {
+                double delta = R2 - Q3;
+                if (-ROOT_DELTA < delta && delta < ROOT_DELTA) {
+                    res[rc++] = - (A + B) / 2.0 + n;
+                }
+            }
+
+        }
+        return fixRoots(res, rc);
+    }
+
+    /**
+     * Excludes double roots. Roots are double if they lies enough close with each other. 
+     * @param res - the roots 
+     * @param rc - the roots count
+     * @return new roots count
+     */
+    static int fixRoots(double res[], int rc) {
+        int tc = 0;
+        for(int i = 0; i < rc; i++) {
+            out: {
+                for(int j = i + 1; j < rc; j++) {
+                    if (isZero(res[i] - res[j])) {
+                        break out;
+                    }
+                }
+                res[tc++] = res[i];
+            }
+        }
+        return tc;
+    }
+
+    /**
+     * QuadCurve class provides basic functionality to find curve crossing and calculating bounds
+     */
+    public static class QuadCurve {
+
+        double ax, ay, bx, by;
+        double Ax, Ay, Bx, By;
+
+        public QuadCurve(double x1, double y1, double cx, double cy, double x2, double y2) {
+            ax = x2 - x1;
+            ay = y2 - y1;
+            bx = cx - x1;
+            by = cy - y1;
+
+            Bx = bx + bx;   // Bx = 2.0 * bx
+            Ax = ax - Bx;   // Ax = ax - 2.0 * bx
+
+            By = by + by;   // By = 2.0 * by
+            Ay = ay - By;   // Ay = ay - 2.0 * by
+        }
+
+        int cross(double res[], int rc, double py1, double py2) {
+            int cross = 0;
+
+            for (int i = 0; i < rc; i++) {
+                double t = res[i];
+
+                // CURVE-OUTSIDE
+                if (t < -DELTA || t > 1 + DELTA) {
+                    continue;
+                }
+                // CURVE-START
+                if (t < DELTA) {
+                    if (py1 < 0.0 && (bx != 0.0 ? bx : ax - bx) < 0.0) {
+                        cross--;
+                    }
+                    continue;
+                }
+                // CURVE-END
+                if (t > 1 - DELTA) {
+                    if (py1 < ay && (ax != bx ? ax - bx : bx) > 0.0) {
+                        cross++;
+                    }
+                    continue;
+                }
+                // CURVE-INSIDE
+                double ry = t * (t * Ay + By);
+                // ry = t * t * Ay + t * By
+                if (ry > py2) {
+                    double rxt = t * Ax + bx;
+                    // rxt = 2.0 * t * Ax + Bx = 2.0 * t * Ax + 2.0 * bx
+                    if (rxt > -DELTA && rxt < DELTA) {
+                        continue;
+                    }
+                    cross += rxt > 0.0 ? 1 : -1;
+                }
+            } // for
+
+            return cross;
+        }
+
+        int solvePoint(double res[], double px) {
+            double eqn[] = {-px, Bx, Ax};
+            return solveQuad(eqn, res);
+        }
+
+        int solveExtrem(double res[]) {
+            int rc = 0;
+            if (Ax != 0.0) {
+                res[rc++] = - Bx / (Ax + Ax);
+            }
+            if (Ay != 0.0) {
+                res[rc++] = - By / (Ay + Ay);
+            }
+            return rc;
+        }
+
+        int addBound(double bound[], int bc, double res[], int rc, double minX, double maxX, boolean changeId, int id) {
+            for(int i = 0; i < rc; i++) {
+                double t = res[i];
+                if (t > -DELTA && t < 1 + DELTA) {
+                    double rx = t * (t * Ax + Bx);
+                    if (minX <= rx && rx <= maxX) {
+                        bound[bc++] = t;
+                        bound[bc++] = rx;
+                        bound[bc++] = t * (t * Ay + By);
+                        bound[bc++] = id;
+                        if (changeId) {
+                            id++;
+                        }
+                    }
+                }
+            }
+            return bc;
+        }
+
+    }
+
+    /**
+     * CubicCurve class provides basic functionality to find curve crossing and calculating bounds
+     */
+    public static class CubicCurve {
+
+        double ax, ay, bx, by, cx, cy;
+        double Ax, Ay, Bx, By, Cx, Cy;
+        double Ax3, Bx2;
+
+        public CubicCurve(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2) {
+            ax = x2 - x1;
+            ay = y2 - y1;
+            bx = cx1 - x1;
+            by = cy1 - y1;
+            cx = cx2 - x1;
+            cy = cy2 - y1;
+
+            Cx = bx + bx + bx;           // Cx = 3.0 * bx
+            Bx = cx + cx + cx - Cx - Cx; // Bx = 3.0 * cx - 6.0 * bx
+            Ax = ax - Bx - Cx;           // Ax = ax - 3.0 * cx + 3.0 * bx
+
+            Cy = by + by + by;           // Cy = 3.0 * by
+            By = cy + cy + cy - Cy - Cy; // By = 3.0 * cy - 6.0 * by
+            Ay = ay - By - Cy;           // Ay = ay - 3.0 * cy + 3.0 * by
+
+            Ax3 = Ax + Ax + Ax;
+            Bx2 = Bx + Bx;
+        }
+
+        int cross(double res[], int rc, double py1, double py2) {
+            int cross = 0;
+            for (int i = 0; i < rc; i++) {
+                double t = res[i];
+
+                // CURVE-OUTSIDE
+                if (t < -DELTA || t > 1 + DELTA) {
+                    continue;
+                }
+                // CURVE-START
+                if (t < DELTA) {
+                    if (py1 < 0.0 && (bx != 0.0 ? bx : (cx != bx ? cx - bx : ax - cx)) < 0.0) {
+                        cross--;
+                    }
+                    continue;
+                }
+                // CURVE-END
+                if (t > 1 - DELTA) {
+                    if (py1 < ay && (ax != cx ? ax - cx : (cx != bx ? cx - bx : bx)) > 0.0) {
+                        cross++;
+                    }
+                    continue;
+                }
+                // CURVE-INSIDE
+                double ry = t * (t * (t * Ay + By) + Cy);
+                // ry = t * t * t * Ay + t * t * By + t * Cy
+                if (ry > py2) {
+                    double rxt = t * (t * Ax3 + Bx2) + Cx;
+                    // rxt = 3.0 * t * t * Ax + 2.0 * t * Bx + Cx
+                    if (rxt > -DELTA && rxt < DELTA) {
+                        rxt = t * (Ax3 + Ax3) + Bx2;
+                        // rxt = 6.0 * t * Ax + 2.0 * Bx
+                        if (rxt < -DELTA || rxt > DELTA) {
+                            // Inflection point
+                            continue;
+                        }
+                        rxt = ax;
+                    }
+                    cross += rxt > 0.0 ? 1 : -1;
+                }
+            } //for
+
+            return cross;
+        }
+
+        int solvePoint(double res[], double px) {
+            double eqn[] = {-px, Cx, Bx, Ax};
+            return solveCubic(eqn, res);
+        }
+
+        int solveExtremX(double res[]) {
+            double eqn[] = {Cx, Bx2, Ax3};
+            return solveQuad(eqn, res);
+        }
+
+        int solveExtremY(double res[]) {
+            double eqn[] = {Cy, By + By, Ay + Ay + Ay};
+            return solveQuad(eqn, res);
+        }
+
+        int addBound(double bound[], int bc, double res[], int rc, double minX, double maxX, boolean changeId, int id) {
+            for(int i = 0; i < rc; i++) {
+                double t = res[i];
+                if (t > -DELTA && t < 1 + DELTA) {
+                    double rx = t * (t * (t * Ax + Bx) + Cx);
+                    if (minX <= rx && rx <= maxX) {
+                        bound[bc++] = t;
+                        bound[bc++] = rx;
+                        bound[bc++] = t * (t * (t * Ay + By) + Cy);
+                        bound[bc++] = id;
+                        if (changeId) {
+                            id++;
+                        }
+                    }
+                }
+            }
+            return bc;
+        }
+
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross line.
+     */
+    public static int crossLine(double x1, double y1, double x2, double y2, double x, double y) {
+
+        // LEFT/RIGHT/UP/EMPTY
+        if ((x < x1 && x < x2) ||
+            (x > x1 && x > x2) ||
+            (y > y1 && y > y2) ||
+            (x1 == x2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (y < y1 && y < y2) {
+        } else {
+            // INSIDE
+            if ((y2 - y1) * (x - x1) / (x2 - x1) <= y - y1) {
+                // INSIDE-UP
+                return 0;
+            }
+        }
+
+        // START
+        if (x == x1) {
+            return x1 < x2 ? 0 : -1;
+        }
+
+        // END
+        if (x == x2) {
+            return x1 < x2 ? 1 : 0;
+        }
+
+        // INSIDE-DOWN
+        return x1 < x2 ? 1 : -1;
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross quard curve
+     */
+    public static int crossQuad(double x1, double y1, double cx, double cy, double x2, double y2, double x, double y) {
+
+        // LEFT/RIGHT/UP/EMPTY
+        if ((x < x1 && x < cx && x < x2) ||
+            (x > x1 && x > cx && x > x2) ||
+            (y > y1 && y > cy && y > y2) ||
+            (x1 == cx && cx == x2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (y < y1 && y < cy && y < y2 && x != x1 && x != x2) {
+            if (x1 < x2) {
+                return x1 < x && x < x2 ? 1 : 0;
+            }
+            return x2 < x && x < x1 ? -1 : 0;
+        }
+
+        // INSIDE
+        QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
+        double px = x - x1;
+        double py = y - y1;
+        double res[] = new double[3];
+        int rc = c.solvePoint(res, px);
+
+        return c.cross(res, rc, py, py);
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross cubic curve
+     */
+    public static int crossCubic(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2, double x, double y) {
+
+        // LEFT/RIGHT/UP/EMPTY
+        if ((x < x1 && x < cx1 && x < cx2 && x < x2) ||
+            (x > x1 && x > cx1 && x > cx2 && x > x2) ||
+            (y > y1 && y > cy1 && y > cy2 && y > y2) ||
+            (x1 == cx1 && cx1 == cx2 && cx2 == x2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (y < y1 && y < cy1 && y < cy2 && y < y2 && x != x1 && x != x2) {
+            if (x1 < x2) {
+                return x1 < x && x < x2 ? 1 : 0;
+            }
+            return x2 < x && x < x1 ? -1 : 0;
+        }
+
+        // INSIDE
+        CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
+        double px = x - x1;
+        double py = y - y1;
+        double res[] = new double[3];
+        int rc = c.solvePoint(res, px);
+        return c.cross(res, rc, py, py);
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross path
+     */
+    public static int crossPath(PathIterator p, double x, double y) {
+        int cross = 0;
+        double mx, my, cx, cy;
+        mx = my = cx = cy = 0.0;
+        double coords[] = new double[6];
+
+        while (!p.isDone()) {
+            switch (p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (cx != mx || cy != my) {
+                    cross += crossLine(cx, cy, mx, my, x, y);
+                }
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                break;
+            case PathIterator.SEG_LINETO:
+                cross += crossLine(cx, cy, cx = coords[0], cy = coords[1], x, y);
+                break;
+            case PathIterator.SEG_QUADTO:
+                cross += crossQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], x, y);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                cross += crossCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], x, y);
+                break;
+            case PathIterator.SEG_CLOSE:
+                if (cy != my || cx != mx) {
+                    cross += crossLine(cx, cy, cx = mx, cy = my, x, y);
+                }
+                break;
+            }
+            p.next();
+        }
+        if (cy != my) {
+            cross += crossLine(cx, cy, mx, my, x, y);
+        }
+        return cross;
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross shape
+     */
+    public static int crossShape(Shape s, double x, double y) {
+        if (!s.getBounds2D().contains(x, y)) {
+            return 0;
+        }
+        return crossPath(s.getPathIterator(null), x, y);
+    }
+
+    /**
+     * Returns true if value enough small
+     */
+    public static boolean isZero(double val) {
+        return -DELTA < val && val < DELTA;
+    }
+
+    /**
+     * Sort bound array
+     */
+    static void sortBound(double bound[], int bc) {
+        for(int i = 0; i < bc - 4; i += 4) {
+            int k = i;
+            for(int j = i + 4; j < bc; j += 4) {
+                if (bound[k] > bound[j]) {
+                    k = j;
+                }
+            }
+            if (k != i) {
+                double tmp = bound[i];
+                bound[i] = bound[k];
+                bound[k] = tmp;
+                tmp = bound[i + 1];
+                bound[i + 1] = bound[k + 1];
+                bound[k + 1] = tmp;
+                tmp = bound[i + 2];
+                bound[i + 2] = bound[k + 2];
+                bound[k + 2] = tmp;
+                tmp = bound[i + 3];
+                bound[i + 3] = bound[k + 3];
+                bound[k + 3] = tmp;
+            }
+        }
+    }
+    
+    /**
+     * Returns are bounds intersect or not intersect rectangle 
+     */
+    static int crossBound(double bound[], int bc, double py1, double py2) {
+
+        // LEFT/RIGHT
+        if (bc == 0) {
+            return 0;
+        }
+
+        // Check Y coordinate
+        int up = 0;
+        int down = 0;
+        for(int i = 2; i < bc; i += 4) {
+            if (bound[i] < py1) {
+                up++;
+                continue;
+            }
+            if (bound[i] > py2) {
+                down++;
+                continue;
+            }
+            return CROSSING;
+        }
+
+        // UP
+        if (down == 0) {
+            return 0;
+        }
+
+        if (up != 0) {
+            // bc >= 2
+            sortBound(bound, bc);
+            boolean sign = bound[2] > py2;
+            for(int i = 6; i < bc; i += 4) {
+                boolean sign2 = bound[i] > py2;
+                if (sign != sign2 && bound[i + 1] != bound[i - 3]) {
+                    return CROSSING;
+                }
+                sign = sign2;
+            }
+        }
+        return UNKNOWN;
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross line or the are intersect
+     */
+    public static int intersectLine(double x1, double y1, double x2, double y2, double rx1, double ry1, double rx2, double ry2) {
+
+        // LEFT/RIGHT/UP
+        if ((rx2 < x1 && rx2 < x2) ||
+            (rx1 > x1 && rx1 > x2) ||
+            (ry1 > y1 && ry1 > y2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (ry2 < y1 && ry2 < y2) {
+        } else {
+
+            // INSIDE
+            if (x1 == x2) {
+                return CROSSING;
+            }
+
+            // Build bound
+            double bx1, bx2;
+            if (x1 < x2) {
+                bx1 = x1 < rx1 ? rx1 : x1;
+                bx2 = x2 < rx2 ? x2 : rx2;
+            } else {
+                bx1 = x2 < rx1 ? rx1 : x2;
+                bx2 = x1 < rx2 ? x1 : rx2;
+            }
+            double k = (y2 - y1) / (x2 - x1);
+            double by1 = k * (bx1 - x1) + y1;
+            double by2 = k * (bx2 - x1) + y1;
+
+            // BOUND-UP
+            if (by1 < ry1 && by2 < ry1) {
+                return 0;
+            }
+
+            // BOUND-DOWN
+            if (by1 > ry2 && by2 > ry2) {
+            } else {
+                return CROSSING;
+            }
+        }
+
+        // EMPTY
+        if (x1 == x2) {
+            return 0;
+        }
+
+        // CURVE-START
+        if (rx1 == x1) {
+            return x1 < x2 ? 0 : -1;
+        }
+
+        // CURVE-END
+        if (rx1 == x2) {
+            return x1 < x2 ? 1 : 0;
+        }
+
+        if (x1 < x2) {
+            return x1 < rx1 && rx1 < x2 ? 1 : 0;
+        }
+        return x2 < rx1 && rx1 < x1 ? -1 : 0;
+
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross quad curve or the are intersect
+     */
+    public static int intersectQuad(double x1, double y1, double cx, double cy, double x2, double y2, double rx1, double ry1, double rx2, double ry2) {
+
+        // LEFT/RIGHT/UP ------------------------------------------------------
+        if ((rx2 < x1 && rx2 < cx && rx2 < x2) ||
+            (rx1 > x1 && rx1 > cx && rx1 > x2) ||
+            (ry1 > y1 && ry1 > cy && ry1 > y2))
+        {
+            return 0;
+        }
+
+        // DOWN ---------------------------------------------------------------
+        if (ry2 < y1 && ry2 < cy && ry2 < y2 && rx1 != x1 && rx1 != x2) {
+            if (x1 < x2) {
+                return x1 < rx1 && rx1 < x2 ? 1 : 0;
+            }
+            return x2 < rx1 && rx1 < x1 ? -1 : 0;
+        }
+
+        // INSIDE -------------------------------------------------------------
+        QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
+        double px1 = rx1 - x1;
+        double py1 = ry1 - y1;
+        double px2 = rx2 - x1;
+        double py2 = ry2 - y1;
+
+        double res1[] = new double[3];
+        double res2[] = new double[3];
+        int rc1 = c.solvePoint(res1, px1);
+        int rc2 = c.solvePoint(res2, px2);
+
+        // INSIDE-LEFT/RIGHT
+        if (rc1 == 0 && rc2 == 0) {
+            return 0;
+        }
+
+        // Build bound --------------------------------------------------------
+        double minX = px1 - DELTA;
+        double maxX = px2 + DELTA;
+        double bound[] = new double[28];
+        int bc = 0;
+        // Add roots
+        bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
+        // Add extremal points`
+        rc2 = c.solveExtrem(res2);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
+        // Add start and end
+        if (rx1 < x1 && x1 < rx2) {
+            bound[bc++] = 0.0;
+            bound[bc++] = 0.0;
+            bound[bc++] = 0.0;
+            bound[bc++] = 4;
+        }
+        if (rx1 < x2 && x2 < rx2) {
+            bound[bc++] = 1.0;
+            bound[bc++] = c.ax;
+            bound[bc++] = c.ay;
+            bound[bc++] = 5;
+        }
+        // End build bound ----------------------------------------------------
+
+        int cross = crossBound(bound, bc, py1, py2);
+        if (cross != UNKNOWN) {
+            return cross;
+        }
+        return c.cross(res1, rc1, py1, py2);
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross cubic curve or the are intersect
+     */
+    public static int intersectCubic(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2, double rx1, double ry1, double rx2, double ry2) {
+
+        // LEFT/RIGHT/UP
+        if ((rx2 < x1 && rx2 < cx1 && rx2 < cx2 && rx2 < x2) ||
+            (rx1 > x1 && rx1 > cx1 && rx1 > cx2 && rx1 > x2) ||
+            (ry1 > y1 && ry1 > cy1 && ry1 > cy2 && ry1 > y2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (ry2 < y1 && ry2 < cy1 && ry2 < cy2 && ry2 < y2 && rx1 != x1 && rx1 != x2) {
+            if (x1 < x2) {
+                return x1 < rx1 && rx1 < x2 ? 1 : 0;
+            }
+            return x2 < rx1 && rx1 < x1 ? -1 : 0;
+        }
+
+        // INSIDE
+        CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
+        double px1 = rx1 - x1;
+        double py1 = ry1 - y1;
+        double px2 = rx2 - x1;
+        double py2 = ry2 - y1;
+
+        double res1[] = new double[3];
+        double res2[] = new double[3];
+        int rc1 = c.solvePoint(res1, px1);
+        int rc2 = c.solvePoint(res2, px2);
+
+        // LEFT/RIGHT
+        if (rc1 == 0 && rc2 == 0) {
+            return 0;
+        }
+
+        double minX = px1 - DELTA;
+        double maxX = px2 + DELTA;
+
+        // Build bound --------------------------------------------------------
+        double bound[] = new double[40];
+        int bc = 0;
+        // Add roots
+        bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
+        // Add extrimal points
+        rc2 = c.solveExtremX(res2);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
+        rc2 = c.solveExtremY(res2);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 4);
+        // Add start and end
+        if (rx1 < x1 && x1 < rx2) {
+            bound[bc++] = 0.0;
+            bound[bc++] = 0.0;
+            bound[bc++] = 0.0;
+            bound[bc++] = 6;
+        }
+        if (rx1 < x2 && x2 < rx2) {
+            bound[bc++] = 1.0;
+            bound[bc++] = c.ax;
+            bound[bc++] = c.ay;
+            bound[bc++] = 7;
+        }
+        // End build bound ----------------------------------------------------
+
+        int cross = crossBound(bound, bc, py1, py2);
+        if (cross != UNKNOWN) {
+            return cross;
+        }
+        return c.cross(res1, rc1, py1, py2);
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross path or the are intersect
+     */
+    public static int intersectPath(PathIterator p, double x, double y, double w, double h) {
+
+        int cross = 0;
+        int count;
+        double mx, my, cx, cy;
+        mx = my = cx = cy = 0.0;
+        double coords[] = new double[6];
+
+        double rx1 = x;
+        double ry1 = y;
+        double rx2 = x + w;
+        double ry2 = y + h;
+
+        while (!p.isDone()) {
+            count = 0;
+            switch (p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (cx != mx || cy != my) {
+                    count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
+                }
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                break;
+            case PathIterator.SEG_LINETO:
+                count = intersectLine(cx, cy, cx = coords[0], cy = coords[1], rx1, ry1, rx2, ry2);
+                break;
+            case PathIterator.SEG_QUADTO:
+                count = intersectQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], rx1, ry1, rx2, ry2);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                count = intersectCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], rx1, ry1, rx2, ry2);
+                break;
+            case PathIterator.SEG_CLOSE:
+                if (cy != my || cx != mx) {
+                    count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
+                }
+                cx = mx;
+                cy = my;
+                break;
+            }
+            if (count == CROSSING) {
+                return CROSSING;
+            }
+            cross += count;
+            p.next();
+        }
+        if (cy != my) {
+            count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
+            if (count == CROSSING) {
+                return CROSSING;
+            }
+            cross += count;
+        }
+        return cross;
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross shape or the are intersect
+     */
+    public static int intersectShape(Shape s, double x, double y, double w, double h) {
+        if (!s.getBounds2D().intersects(x, y, w, h)) {
+            return 0;
+        }
+        return intersectPath(s.getPathIterator(null), x, y, w, h);
+    }
+
+    /**
+     * Returns true if cross count correspond inside location for non zero path rule
+     */
+    public static boolean isInsideNonZero(int cross) {
+        return cross != 0;
+    }
+
+    /**
+     * Returns true if cross count correspond inside location for even-odd path rule
+     */
+    public static boolean isInsideEvenOdd(int cross) {
+        return (cross & 1) != 0;
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/GLVolatileImage.java b/awt/org/apache/harmony/awt/gl/GLVolatileImage.java
new file mode 100644
index 0000000..177be23
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/GLVolatileImage.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.image.*;
+
+import org.apache.harmony.awt.gl.Surface;
+
+public abstract class GLVolatileImage extends VolatileImage {
+
+    public abstract Surface getImageSurface();
+}
diff --git a/awt/org/apache/harmony/awt/gl/ICompositeContext.java b/awt/org/apache/harmony/awt/gl/ICompositeContext.java
new file mode 100644
index 0000000..fc5631f
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/ICompositeContext.java
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.render.NativeImageBlitter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * This class represent implementation of the CompositeContext interface
+ */
+public class ICompositeContext implements CompositeContext {
+    Composite composite;
+    ColorModel srcCM, dstCM;
+    ImageSurface srcSurf, dstSurf;
+
+    public ICompositeContext(Composite comp, ColorModel src, ColorModel dst){
+        composite = comp;
+        srcCM = src;
+        dstCM = dst;
+    }
+
+    public void dispose() {
+        srcSurf.dispose();
+        dstSurf.dispose();
+    }
+
+    public void compose(Raster srcIn, Raster dstIn, WritableRaster dstOut) {
+
+        if(!srcCM.isCompatibleRaster(srcIn)) {
+            // awt.48=The srcIn raster is incompatible with src ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.48")); //$NON-NLS-1$
+        }
+
+        if(!dstCM.isCompatibleRaster(dstIn)) {
+            // awt.49=The dstIn raster is incompatible with dst ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.49")); //$NON-NLS-1$
+        }
+
+        if(dstIn != dstOut){
+            if(!dstCM.isCompatibleRaster(dstOut)) {
+                // awt.4A=The dstOut raster is incompatible with dst ColorModel
+                throw new IllegalArgumentException(Messages.getString("awt.4A")); //$NON-NLS-1$
+            }
+            dstOut.setDataElements(0, 0, dstIn);
+        }
+        WritableRaster src;
+        if(srcIn instanceof WritableRaster){
+            src = (WritableRaster) srcIn;
+        }else{
+            src = srcIn.createCompatibleWritableRaster();
+            src.setDataElements(0, 0, srcIn);
+        }
+        srcSurf = new ImageSurface(srcCM, src);
+        dstSurf = new ImageSurface(dstCM, dstOut);
+
+        int w = Math.min(srcIn.getWidth(), dstOut.getWidth());
+        int h = Math.min(srcIn.getHeight(), dstOut.getHeight());
+
+        NativeImageBlitter.getInstance().blit(0, 0, srcSurf, 0, 0, dstSurf,
+                w, h, composite, null, null);
+
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/ImageSurface.java b/awt/org/apache/harmony/awt/gl/ImageSurface.java
new file mode 100644
index 0000000..6368dd8
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/ImageSurface.java
@@ -0,0 +1,323 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 10.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.color.ColorSpace;
+import java.awt.image.BandedSampleModel;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * This class represent Surface for different types of Images (BufferedImage, 
+ * OffscreenImage and so on) 
+ */
+public class ImageSurface extends Surface implements DataBufferListener {
+
+    boolean nativeDrawable = true;
+    int surfaceType;
+    int csType;
+    ColorModel cm;
+    WritableRaster raster;
+    Object data;
+    
+    boolean needToRefresh = true;
+    boolean dataTaken = false;
+    
+    private long cachedDataPtr;       // Pointer for cached Image Data
+    private boolean alphaPre;         // Cached Image Data alpha premultiplied 
+
+    public ImageSurface(ColorModel cm, WritableRaster raster){
+        this(cm, raster, Surface.getType(cm, raster));
+    }
+
+    public ImageSurface(ColorModel cm, WritableRaster raster, int type){
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.4D=The raster is incompatible with this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+        }
+        this.cm = cm;
+        this.raster = raster;
+        surfaceType = type;
+
+        data = AwtImageBackdoorAccessor.getInstance().
+        getData(raster.getDataBuffer());
+        ColorSpace cs = cm.getColorSpace();
+        transparency = cm.getTransparency();
+        width = raster.getWidth();
+        height = raster.getHeight();
+
+        // For the moment we can build natively only images which have 
+        // sRGB, Linear_RGB, Linear_Gray Color Space and type different
+        // from BufferedImage.TYPE_CUSTOM
+        if(cs == LUTColorConverter.sRGB_CS){
+            csType = sRGB_CS;
+        }else if(cs == LUTColorConverter.LINEAR_RGB_CS){
+            csType = Linear_RGB_CS;
+        }else if(cs == LUTColorConverter.LINEAR_GRAY_CS){
+            csType = Linear_Gray_CS;
+        }else{
+            csType = Custom_CS;
+            nativeDrawable = false;
+        }
+
+        if(type == BufferedImage.TYPE_CUSTOM){
+            nativeDrawable = false;
+        }
+    }
+
+    @Override
+    public ColorModel getColorModel() {
+        return cm;
+    }
+
+    @Override
+    public WritableRaster getRaster() {
+        return raster;
+    }
+
+    @Override
+    public long getSurfaceDataPtr() {
+        if(surfaceDataPtr == 0L && nativeDrawable){
+            createSufaceStructure();
+        }
+        return surfaceDataPtr;
+    }
+
+    @Override
+    public Object getData(){
+        return data;
+    }
+
+    @Override
+    public boolean isNativeDrawable(){
+        return nativeDrawable;
+    }
+
+    @Override
+    public int getSurfaceType() {
+        return surfaceType;
+    }
+
+    /**
+     * Creates native Surface structure which used for native blitting
+     */
+    private void createSufaceStructure(){
+        int cmType = 0;
+        int numComponents = cm.getNumComponents();
+        boolean hasAlpha = cm.hasAlpha();
+        boolean isAlphaPre = cm.isAlphaPremultiplied();
+        int transparency = cm.getTransparency();
+        int bits[] = cm.getComponentSize();
+        int pixelStride = cm.getPixelSize();
+        int masks[] = null;
+        int colorMap[] = null;
+        int colorMapSize = 0;
+        int transpPixel = -1;
+        boolean isGrayPallete = false;
+        SampleModel sm = raster.getSampleModel();
+        int smType = 0;
+        int dataType = sm.getDataType();
+        int scanlineStride = 0;
+        int bankIndeces[] = null;
+        int bandOffsets[] = null;
+        int offset = raster.getDataBuffer().getOffset();
+
+        if(cm instanceof DirectColorModel){
+            cmType = DCM;
+            DirectColorModel dcm = (DirectColorModel) cm;
+            masks = dcm.getMasks();
+            smType = SPPSM;
+            SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+            scanlineStride = sppsm.getScanlineStride();
+
+        }else if(cm instanceof IndexColorModel){
+            cmType = ICM;
+            IndexColorModel icm = (IndexColorModel) cm;
+            colorMapSize = icm.getMapSize();
+            colorMap = new int[colorMapSize];
+            icm.getRGBs(colorMap);
+            transpPixel = icm.getTransparentPixel();
+            isGrayPallete = Surface.isGrayPallete(icm);
+
+            if(sm instanceof MultiPixelPackedSampleModel){
+                smType = MPPSM;
+                MultiPixelPackedSampleModel mppsm =
+                    (MultiPixelPackedSampleModel) sm;
+                scanlineStride = mppsm.getScanlineStride();
+            }else if(sm instanceof ComponentSampleModel){
+                smType = CSM;
+                ComponentSampleModel csm =
+                    (ComponentSampleModel) sm;
+                scanlineStride = csm.getScanlineStride();
+            }else{
+                // awt.4D=The raster is incompatible with this ColorModel
+                throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+            }
+
+        }else if(cm instanceof ComponentColorModel){
+            cmType = CCM;
+            if(sm instanceof ComponentSampleModel){
+                ComponentSampleModel csm = (ComponentSampleModel) sm;
+                scanlineStride = csm.getScanlineStride();
+                bankIndeces = csm.getBankIndices();
+                bandOffsets = csm.getBandOffsets();
+                if(sm instanceof PixelInterleavedSampleModel){
+                    smType = PISM;
+                }else if(sm instanceof BandedSampleModel){
+                    smType = BSM;
+                }else{
+                    smType = CSM;
+                }
+            }else{
+                // awt.4D=The raster is incompatible with this ColorModel
+                throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+            }
+
+        }else{
+            surfaceDataPtr = 0L;
+            return;
+        }
+        surfaceDataPtr = createSurfStruct(surfaceType, width, height, cmType, csType, smType, dataType,
+                numComponents, pixelStride, scanlineStride, bits, masks, colorMapSize,
+                colorMap, transpPixel, isGrayPallete, bankIndeces, bandOffsets,
+                offset, hasAlpha, isAlphaPre, transparency);
+    }
+
+    @Override
+    public void dispose() {
+        if(surfaceDataPtr != 0L){
+            dispose(surfaceDataPtr);
+            surfaceDataPtr = 0L;
+        }
+    }
+    
+    public long getCachedData(boolean alphaPre){
+        if(nativeDrawable){
+            if(cachedDataPtr == 0L || needToRefresh || this.alphaPre != alphaPre){
+                cachedDataPtr = updateCache(getSurfaceDataPtr(), data, alphaPre);
+                this.alphaPre = alphaPre;
+                validate(); 
+            }
+        }
+        return cachedDataPtr;
+    }
+
+    private native long createSurfStruct(int surfaceType, int width, int height, 
+            int cmType, int csType, int smType, int dataType,
+            int numComponents, int pixelStride, int scanlineStride,
+            int bits[], int masks[], int colorMapSize, int colorMap[],
+            int transpPixel, boolean isGrayPalette, int bankIndeces[], 
+            int bandOffsets[], int offset, boolean hasAlpha, boolean isAlphaPre,
+            int transparency);
+
+    private native void dispose(long structPtr);
+
+    private native void setImageSize(long structPtr, int width, int height);
+
+    private native long updateCache(long structPtr, Object data, boolean alphaPre);
+    
+    /**
+     * Supposes that new raster is compatible with an old one
+     * @param r
+     */
+    public void setRaster(WritableRaster r) {
+        raster = r;
+        data = AwtImageBackdoorAccessor.getInstance().getData(r.getDataBuffer());
+        if (surfaceDataPtr != 0) {
+            setImageSize(surfaceDataPtr, r.getWidth(), r.getHeight());
+        }
+        this.width = r.getWidth();
+        this.height = r.getHeight();
+    }
+
+    @Override
+    public long lock() {
+        // TODO
+        return 0;
+    }
+
+    @Override
+    public void unlock() {
+        //TODO
+    }
+
+    @Override
+    public Surface getImageSurface() {
+        return this;
+    }
+
+    public void dataChanged() {
+        needToRefresh = true;
+        clearValidCaches();
+    }
+
+    public void dataTaken() {
+        dataTaken = true;
+        needToRefresh = true;
+        clearValidCaches();
+    }
+    
+    public void dataReleased(){
+        dataTaken = false;
+        needToRefresh = true;
+        clearValidCaches();
+    }
+    
+    @Override
+    public void invalidate(){
+        needToRefresh = true;
+        clearValidCaches();
+    }
+    
+    @Override
+    public void validate(){
+        if(!needToRefresh) {
+            return;
+        }
+        if(!dataTaken){
+            needToRefresh = false;
+            AwtImageBackdoorAccessor ba = AwtImageBackdoorAccessor.getInstance();
+            ba.validate(raster.getDataBuffer());
+        }
+        
+    }
+    
+    @Override
+    public boolean invalidated(){
+        return needToRefresh;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/MultiRectArea.java b/awt/org/apache/harmony/awt/gl/MultiRectArea.java
new file mode 100644
index 0000000..c4267f3
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/MultiRectArea.java
@@ -0,0 +1,836 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class MultiRectArea implements Shape {
+
+    /**
+     * If CHECK is true validation check active
+     */
+    private static final boolean CHECK = false;
+
+    boolean sorted = true;
+    
+    /**
+     * Rectangle buffer
+     */
+    public int[] rect;
+    
+    /**
+     * Bounding box
+     */
+    Rectangle bounds;
+    
+    /**
+     * Result rectangle array
+     */
+    Rectangle[] rectangles;
+
+    /**
+     * LineCash provides creating MultiRectArea line by line. Used in JavaShapeRasterizer.
+     */
+    public static class LineCash extends MultiRectArea {
+
+        int lineY;
+        int bottomCount;
+        int[] bottom;
+
+        public LineCash(int size) {
+            super();
+            bottom = new int[size];
+            bottomCount = 0;
+        }
+
+        public void setLine(int y) {
+            lineY = y;
+        }
+
+        public void skipLine() {
+            lineY++;
+            bottomCount = 0;
+        }
+
+        public void addLine(int[] points, int pointCount) {
+            int bottomIndex = 0;
+            int pointIndex = 0;
+            int rectIndex = 0;
+            int pointX1 = 0;
+            int pointX2 = 0;
+            int bottomX1 = 0;
+            int bottomX2 = 0;
+            boolean appendRect = false;
+            boolean deleteRect = false;
+            int lastCount = bottomCount;
+
+            while (bottomIndex < lastCount || pointIndex < pointCount) {
+
+                appendRect = false;
+                deleteRect = false;
+
+                if (bottomIndex < lastCount) {
+                    rectIndex = bottom[bottomIndex];
+                    bottomX1 = rect[rectIndex];
+                    bottomX2 = rect[rectIndex + 2];
+                } else {
+                    appendRect = true;
+                }
+
+                if (pointIndex < pointCount) {
+                    pointX1 = points[pointIndex];
+                    pointX2 = points[pointIndex + 1];
+                } else {
+                    deleteRect = true;
+                }
+
+                if (!deleteRect && !appendRect) {
+                    if (pointX1 == bottomX1 && pointX2 == bottomX2) {
+                        rect[rectIndex + 3] = rect[rectIndex + 3] + 1;
+                        pointIndex += 2;
+                        bottomIndex++;
+                        continue;
+                    }
+                    deleteRect = pointX2 >= bottomX1;
+                    appendRect = pointX1 <= bottomX2;
+                }
+
+                if (deleteRect) {
+                    if (bottomIndex < bottomCount - 1) {
+                        System.arraycopy(bottom, bottomIndex + 1, bottom, bottomIndex, bottomCount - bottomIndex - 1);
+                        rectIndex -= 4;
+                    }
+                    bottomCount--;
+                    lastCount--;
+                }
+
+                if (appendRect) {
+                    int i = rect[0];
+                    bottom[bottomCount++] = i;
+                    rect = MultiRectAreaOp.checkBufSize(rect, 4);
+                    rect[i++] = pointX1;
+                    rect[i++] = lineY;
+                    rect[i++] = pointX2;
+                    rect[i++] = lineY;
+                    pointIndex += 2;
+                }
+            }
+            lineY++;
+
+            invalidate();
+        }
+
+    }
+
+    /**
+     * RectCash provides simple creating MultiRectArea
+     */
+    public static class RectCash extends MultiRectArea {
+
+        int[] cash;
+
+        public RectCash() {
+            super();
+            cash = new int[MultiRectAreaOp.RECT_CAPACITY];
+            cash[0] = 1;
+        }
+
+        public void addRectCashed(int x1, int y1, int x2, int y2) {
+            addRect(x1, y1, x2, y2);
+            invalidate();
+/*
+            // Exclude from cash unnecessary rectangles
+            int i = 1;
+            while(i < cash[0]) {
+                if (rect[cash[i] + 3] >= y1 - 1) {
+                    if (i > 1) {
+                        System.arraycopy(cash, i, cash, 1, cash[0] - i);
+                    }
+                    break;
+                }
+                i++;
+            }
+            cash[0] -= i - 1;
+
+            // Find in cash rectangle to concatinate
+            i = 1;
+            while(i < cash[0]) {
+                int index = cash[i];
+                if (rect[index + 3] != y1 - 1) {
+                    break;
+                }
+                if (rect[index] == x1 && rect[index + 2] == x2) {
+                    rect[index + 3] += y2 - y1 + 1;
+
+                    int pos = i + 1;
+                    while(pos < cash[0]) {
+                        if (rect[index + 3] <= rect[cash[i] + 3]) {
+                            System.arraycopy(cash, i + 1, cash, i, pos - i);
+                            break;
+                        }
+                        i++;
+                    }
+                    cash[pos - 1] = index;
+
+                    invalidate();
+                    return;
+                }
+                i++;
+            }
+
+            // Add rectangle to buffer
+            int index = rect[0];
+            rect = MultiRectAreaOp.checkBufSize(rect, 4);
+            rect[index + 0] = x1;
+            rect[index + 1] = y1;
+            rect[index + 2] = x2;
+            rect[index + 3] = y2;
+
+            // Add rectangle to cash
+            int length = cash[0];
+            cash = MultiRectAreaOp.checkBufSize(cash, 1);
+            while(i < length) {
+                if (y2 <= rect[cash[i] + 3]) {
+                    System.arraycopy(cash, i, cash, i + 1, length - i);
+                    break;
+                }
+                i++;
+            }
+            cash[i] = index;
+            invalidate();
+*/
+        }
+
+        public void addRectCashed(int[] rect, int rectOff, int rectLength) {
+            for(int i = rectOff; i < rectOff + rectLength;) {
+                addRect(rect[i++], rect[i++], rect[i++], rect[i++]);
+//              addRectCashed(rect[i++], rect[i++], rect[i++], rect[i++]);
+            }
+        }
+
+    }
+
+    /**
+     * MultiRectArea path iterator
+     */
+    class Iterator implements PathIterator {
+
+        int type;
+        int index;
+        int pos;
+
+        int[] rect;
+        AffineTransform t;
+
+        Iterator(MultiRectArea mra, AffineTransform t) {
+            rect = new int[mra.rect[0] - 1];
+            System.arraycopy(mra.rect, 1, rect, 0, rect.length);
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return pos >= rect.length;
+        }
+
+        public void next() {
+            if (index == 4) {
+                pos += 4;
+            }
+            index = (index + 1) % 5;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iiterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = 0;
+
+            switch(index) {
+            case 0 :
+                type = SEG_MOVETO;
+                coords[0] = rect[pos + 0];
+                coords[1] = rect[pos + 1];
+                break;
+            case 1:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 2];
+                coords[1] = rect[pos + 1];
+                break;
+            case 2:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 2];
+                coords[1] = rect[pos + 3];
+                break;
+            case 3:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 0];
+                coords[1] = rect[pos + 3];
+                break;
+            case 4:
+                type = SEG_CLOSE;
+                break;
+            }
+
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iiterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = 0;
+
+            switch(index) {
+            case 0 :
+                type = SEG_MOVETO;
+                coords[0] = rect[pos + 0];
+                coords[1] = rect[pos + 1];
+                break;
+            case 1:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 2];
+                coords[1] = rect[pos + 1];
+                break;
+            case 2:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 2];
+                coords[1] = rect[pos + 3];
+                break;
+            case 3:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 0];
+                coords[1] = rect[pos + 3];
+                break;
+            case 4:
+                type = SEG_CLOSE;
+                break;
+            }
+
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Constructs a new empty MultiRectArea 
+     */
+    public MultiRectArea() {
+        rect = MultiRectAreaOp.createBuf(0);
+    }
+
+    public MultiRectArea(boolean sorted) {
+       this();
+       this.sorted = sorted;
+    }
+    
+    /**
+     * Constructs a new MultiRectArea as a copy of another one 
+     */
+    public MultiRectArea(MultiRectArea mra) {
+        if (mra == null) {
+            rect = MultiRectAreaOp.createBuf(0);
+        } else {
+            rect = new int[mra.rect.length];
+            System.arraycopy(mra.rect, 0, rect, 0, mra.rect.length);
+            check(this, "MultiRectArea(MRA)"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Constructs a new MultiRectArea consists of single rectangle 
+     */
+    public MultiRectArea(Rectangle r) {
+        rect = MultiRectAreaOp.createBuf(0);
+        if (r != null && !r.isEmpty()) {
+            rect[0] = 5;
+            rect[1] = r.x;
+            rect[2] = r.y;
+            rect[3] = r.x + r.width - 1;
+            rect[4] = r.y + r.height - 1;
+        }
+        check(this, "MultiRectArea(Rectangle)"); //$NON-NLS-1$
+    }
+
+    /**
+     * Constructs a new MultiRectArea consists of single rectangle
+     */
+    public MultiRectArea(int x0, int y0, int x1, int y1) {
+        rect = MultiRectAreaOp.createBuf(0);
+        if (x1 >= x0 && y1 >= y0) {
+            rect[0] = 5;
+            rect[1] = x0;
+            rect[2] = y0;
+            rect[3] = x1;
+            rect[4] = y1;
+        }
+        check(this, "MultiRectArea(Rectangle)"); //$NON-NLS-1$
+    }
+
+    /**
+     * Constructs a new MultiRectArea and append rectangle from buffer
+     */
+    public MultiRectArea(Rectangle[] buf) {
+        this();
+        for (Rectangle element : buf) {
+            add(element);
+        }
+    }
+
+    /**
+     * Constructs a new MultiRectArea and append rectangle from array
+     */
+    public MultiRectArea(ArrayList<Rectangle> buf) {
+        this();
+        for(int i = 0; i < buf.size(); i++) {
+            add(buf.get(i));
+        }
+    }
+
+    /**
+     * Sort rectangle buffer
+     */
+    void resort() {
+        int[] buf = new int[4];
+        for(int i = 1; i < rect[0]; i += 4) {
+            int k = i;
+            int x1 = rect[k];
+            int y1 = rect[k + 1];
+            for(int j = i + 4; j < rect[0]; j += 4) {
+                int x2 = rect[j];
+                int y2 = rect[j + 1];
+                if (y1 > y2 || (y1 == y2 && x1 > x2)) {
+                    x1 = x2;
+                    y1 = y2;
+                    k = j;
+                }
+            }
+            if (k != i) {
+                System.arraycopy(rect, i, buf, 0, 4);
+                System.arraycopy(rect, k, rect, i, 4);
+                System.arraycopy(buf, 0, rect, k, 4);
+            }
+        }
+        invalidate();
+    }
+
+    /**
+     * Tests equals with another object
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof MultiRectArea) {
+            MultiRectArea mra = (MultiRectArea) obj;
+            for(int i = 0; i < rect[0]; i++) {
+                if (rect[i] != mra.rect[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Checks validation of MultiRectArea object
+     */
+    static MultiRectArea check(MultiRectArea mra, String msg) {
+        if (CHECK && mra != null) {
+            if (MultiRectArea.checkValidation(mra.getRectangles(), mra.sorted) != -1) {
+                // awt.4C=Invalid MultiRectArea in method {0}
+                new RuntimeException(Messages.getString("awt.4C", msg)); //$NON-NLS-1$
+            }
+        }
+        return mra;
+    }
+
+    /**
+     * Checks validation of MultiRectArea object
+     */
+    public static int checkValidation(Rectangle[] r, boolean sorted) {
+
+        // Check width and height
+        for(int i = 0; i < r.length; i++) {
+            if (r[i].width <= 0 || r[i].height <= 0) {
+                return i;
+            }
+        }
+
+        // Check order
+        if (sorted) {
+            for(int i = 1; i < r.length; i++) {
+                if (r[i - 1].y > r[i].y) {
+                    return i;
+                }
+                if (r[i - 1].y == r[i].y) {
+                    if (r[i - 1].x > r[i].x) {
+                        return i;
+                    }
+                }
+            }
+        }
+
+        // Check override
+        for(int i = 0; i < r.length; i++) {
+            for(int j = i + 1; j < r.length; j++) {
+                if (r[i].intersects(r[j])) {
+                    return i;
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Assigns rectangle from another buffer
+     */
+    protected void setRect(int[] buf, boolean copy) {
+        if (copy) {
+            rect = new int[buf.length];
+            System.arraycopy(buf, 0, rect, 0, buf.length);
+        } else {
+            rect = buf;
+        }
+        invalidate();
+    }
+
+    /**
+     * Union with another MultiRectArea object
+     */
+    public void add(MultiRectArea mra) {
+        setRect(union(this, mra).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Intersect with another MultiRectArea object
+     */
+    public void intersect(MultiRectArea mra) {
+        setRect(intersect(this, mra).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Subtract another MultiRectArea object
+     */
+    public void substract(MultiRectArea mra) {
+        setRect(subtract(this, mra).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Union with Rectangle object
+     */
+    public void add(Rectangle rect) {
+        setRect(union(this, new MultiRectArea(rect)).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Intersect with Rectangle object
+     */
+    public void intersect(Rectangle rect) {
+        setRect(intersect(this, new MultiRectArea(rect)).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Subtract rectangle object
+     */
+    public void substract(Rectangle rect) {
+        setRect(subtract(this, new MultiRectArea(rect)).rect, false);
+    }
+
+    /**
+     * Union two MutliRectareArea objects
+     */
+    public static MultiRectArea intersect(MultiRectArea src1, MultiRectArea src2) {
+        MultiRectArea res = check(MultiRectAreaOp.Intersection.getResult(src1, src2), "intersect(MRA,MRA)"); //$NON-NLS-1$
+        return res;
+    }
+
+    /**
+     * Intersect two MultiRectArea objects
+     */
+    public static MultiRectArea union(MultiRectArea src1, MultiRectArea src2) {
+        MultiRectArea res = check(new MultiRectAreaOp.Union().getResult(src1, src2), "union(MRA,MRA)"); //$NON-NLS-1$
+        return res;
+    }
+
+    /**
+     * Subtract two MultiRectArea objects
+     */
+    public static MultiRectArea subtract(MultiRectArea src1, MultiRectArea src2) {
+        MultiRectArea res = check(MultiRectAreaOp.Subtraction.getResult(src1, src2), "subtract(MRA,MRA)"); //$NON-NLS-1$
+        return res;
+    }
+
+    /**
+     * Print MultiRectArea object to output stream
+     */
+    public static void print(MultiRectArea mra, String msg) {
+        if (mra == null) {
+            System.out.println(msg + "=null"); //$NON-NLS-1$
+        } else {
+            Rectangle[] rects = mra.getRectangles();
+            System.out.println(msg + "(" + rects.length + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+            for (Rectangle element : rects) {
+                System.out.println(
+                        element.x + "," + //$NON-NLS-1$
+                        element.y + "," + //$NON-NLS-1$
+                        (element.x + element.width - 1) + "," + //$NON-NLS-1$
+                        (element.y + element.height - 1));
+            }
+        }
+    }
+
+    /**
+     * Translate MultiRectArea object by (x, y)
+     */
+    public void translate(int x, int y) {
+        for(int i = 1; i < rect[0];) {
+            rect[i++] += x;
+            rect[i++] += y;
+            rect[i++] += x;
+            rect[i++] += y;
+        }
+
+        if (bounds != null && !bounds.isEmpty()) {
+            bounds.translate(x, y);
+        }
+
+        if (rectangles != null) {
+            for (Rectangle element : rectangles) {
+                element.translate(x, y);
+            }
+        }
+    }
+
+    /**
+     * Add rectangle to the buffer without any checking
+     */
+    public void addRect(int x1, int y1, int x2, int y2) {
+        int i = rect[0];
+        rect = MultiRectAreaOp.checkBufSize(rect, 4);
+        rect[i++] = x1;
+        rect[i++] = y1;
+        rect[i++] = x2;
+        rect[i++] = y2;
+    }
+
+    /**
+     * Tests is MultiRectArea empty 
+     */
+    public boolean isEmpty() {
+        return rect[0] == 1;
+    }
+
+    void invalidate() {
+        bounds = null;
+        rectangles = null;
+    }
+
+    /**
+     * Returns bounds of MultiRectArea object
+     */
+    public Rectangle getBounds() {
+        if (bounds != null) {
+            return bounds;
+        }
+
+        if (isEmpty()) {
+            return bounds = new Rectangle();
+        }
+
+        int x1 = rect[1];
+        int y1 = rect[2];
+        int x2 = rect[3];
+        int y2 = rect[4];
+        
+        for(int i = 5; i < rect[0]; i += 4) {
+            int rx1 = rect[i + 0];
+            int ry1 = rect[i + 1];
+            int rx2 = rect[i + 2];
+            int ry2 = rect[i + 3];
+            if (rx1 < x1) {
+                x1 = rx1;
+            }
+            if (rx2 > x2) {
+                x2 = rx2;
+            }
+            if (ry1 < y1) {
+                y1 = ry1;
+            }
+            if (ry2 > y2) {
+                y2 = ry2;
+            }
+        }
+        
+        return bounds = new Rectangle(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+    }
+
+    /**
+     * Recturn rectangle count in the buffer
+     */
+    public int getRectCount() {
+        return (rect[0] - 1) / 4;
+    }
+
+    /**
+     * Returns Rectangle array 
+     */
+    public Rectangle[] getRectangles() {
+        if (rectangles != null) {
+            return rectangles;
+        }
+
+        rectangles = new Rectangle[(rect[0] - 1) / 4];
+        int j = 0;
+        for(int i = 1; i < rect[0]; i += 4) {
+            rectangles[j++] = new Rectangle(
+                    rect[i],
+                    rect[i + 1],
+                    rect[i + 2] - rect[i] + 1,
+                    rect[i + 3] - rect[i + 1] + 1);
+        }
+        return rectangles;
+    }
+
+    /**
+     * Returns Bounds2D
+     */
+    public Rectangle2D getBounds2D() {
+        return getBounds();
+    }
+
+    /**
+     * Tests does point lie inside MultiRectArea object
+     */
+    public boolean contains(double x, double y) {
+        for(int i = 1; i < rect[0]; i+= 4) {
+            if (rect[i] <= x && x <= rect[i + 2] && rect[i + 1] <= y && y <= rect[i + 3]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Tests does Point2D lie inside MultiRectArea object
+     */
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    /**
+     * Tests does rectangle lie inside MultiRectArea object
+     */
+    public boolean contains(double x, double y, double w, double h) {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Tests does Rectangle2D lie inside MultiRectArea object
+     */
+    public boolean contains(Rectangle2D r) {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Tests does rectangle intersect MultiRectArea object
+     */
+    public boolean intersects(double x, double y, double w, double h) {
+        Rectangle r = new Rectangle();
+        r.setRect(x, y, w, h);
+        return intersects(r);
+    }
+
+    /**
+     * Tests does Rectangle2D intersect MultiRectArea object
+     */
+    public boolean intersects(Rectangle2D r) {
+        if (r == null || r.isEmpty()) {
+            return false;
+        }
+        for(int i = 1; i < rect[0]; i+= 4) {
+            if (r.intersects(rect[i], rect[i+1], rect[i + 2]-rect[i]+1, rect[i + 3]-rect[i + 1]+1)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns path iterator
+     */
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(this, t);
+    }
+
+    /**
+     * Returns path iterator
+     */
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    /**
+     * Returns MultiRectArea object converted to string 
+     */
+    @Override
+    public String toString() {
+        int cnt = getRectCount();
+        StringBuffer sb = new StringBuffer((cnt << 5) + 128);
+        sb.append(getClass().getName()).append(" ["); //$NON-NLS-1$
+        for(int i = 1; i < rect[0]; i += 4) {
+            sb.append(i > 1 ? ", [" : "[").append(rect[i]).append(", ").append(rect[i + 1]). //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            append(", ").append(rect[i + 2] - rect[i] + 1).append(", "). //$NON-NLS-1$ //$NON-NLS-2$
+            append(rect[i + 3] - rect[i + 1] + 1).append("]"); //$NON-NLS-1$
+        }
+        return sb.append("]").toString(); //$NON-NLS-1$
+    }
+
+}
+
diff --git a/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java b/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java
new file mode 100644
index 0000000..c75e203
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java
@@ -0,0 +1,837 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Rectangle;
+
+public class MultiRectAreaOp {
+
+    /**
+     * Rectangle buffer capacity
+     */
+    public static final int RECT_CAPACITY = 16;
+    
+    /**
+     * If number of rectangle in MultiRectArea object less than MAX_SIMPLE simple algorithm applies 
+     */
+    private static final int MAX_SIMPLE = 8;
+
+    /**
+     * Create buffer
+     */
+    public static int[] createBuf(int capacity) {
+        if (capacity == 0) {
+            capacity = RECT_CAPACITY;
+        }
+        int[] buf = new int[capacity];
+        buf[0] = 1;
+        return buf;
+    }
+
+    /**
+     * Checks buffer size and reallocate if necessary  
+     */
+    public static int[] checkBufSize(int[] buf, int capacity) {
+        if (buf[0] + capacity >= buf.length) {
+            int length = buf[0] + (capacity > RECT_CAPACITY ? capacity : RECT_CAPACITY);
+            int[] tmp = new int[length];
+            System.arraycopy(buf, 0, tmp, 0, buf[0]);
+            buf = tmp;
+        }
+        buf[0] += capacity;
+        return buf;
+    }
+
+    /**
+     * Region class provides basic functionlity for MultiRectArea objects to make logical operations 
+     */
+    static class Region {
+
+        int[] region;
+        int[] active;
+        int[] bottom;
+        int index;
+
+        public Region(int[] region) {
+            this.region = region;
+            active = new int[RECT_CAPACITY];
+            bottom = new int[RECT_CAPACITY];
+            active[0] = 1;
+            bottom[0] = 1;
+            index = 1;
+        }
+
+        void addActive(int index) {
+            int length = active[0];
+            active = checkBufSize(active, 4);
+            int i = 1;
+
+            while(i < length) {
+                if (region[index] < active[i]) {
+                    // Insert
+                    System.arraycopy(active, i, active, i + 4, length - i);
+                    length = i;
+                    break;
+                }
+                i += 4;
+            }
+            System.arraycopy(region, index, active, length, 4);
+
+        }
+
+        void findActive(int top, int bottom) {
+            while(index < region[0]) {
+                if (region[index + 1] > bottom) { // y1 > bottom
+                    return;
+                }
+                if (region[index + 3] >= top) { // y2 >= top
+                    addActive(index);
+                }
+                index += 4;
+            }
+        }
+
+        void deleteActive(int bottom) {
+            int length = active[0];
+            for(int i = 1; i < length;) {
+                if (active[i + 3] == bottom) {
+                    length -= 4;
+                    if (i < length) {
+                        System.arraycopy(active, i + 4, active, i, length - i);
+                    }
+                } else {
+                     i += 4;
+                }
+            }
+            active[0] = length;
+        }
+
+        void deleteActive() {
+            int length = active[0];
+            for(int i = length - 4; i > 0; i -= 4) {
+                if (active[i + 1] > active[i + 3]) {
+                    length -= 4;
+                    if (i < length) {
+                        System.arraycopy(active, i + 4, active, i, length - i);
+                    }
+                }
+            }
+            active[0] = length;
+        }
+
+        void createLevel(int[] level) {
+            int levelCount = 1;
+            int topIndex = 1;
+            int i = 1;
+            while(i < region[0]) {
+
+                int top = region[i + 1];
+                int bottom = region[i + 3] + 1;
+                int j = topIndex;
+
+                addTop: {
+                    while(j < levelCount) {
+                        if (level[j] == top) {
+                            break addTop;
+                        }
+                        if (level[j] > top) {
+                            System.arraycopy(level, j, level, j + 1, levelCount - j);
+                            break;
+                        }
+                        j++;
+                    }
+
+                    level[j] = top;
+                    levelCount++;
+                    topIndex = j;
+                }
+
+                addBottom: {
+                    while(j < levelCount) {
+                        if (level[j] == bottom) {
+                            break addBottom;
+                        }
+                        if (level[j] > bottom) {
+                            System.arraycopy(level, j, level, j + 1, levelCount - j);
+                            break;
+                        }
+                        j++;
+                    };
+
+                    level[j] = bottom;
+                    levelCount++;
+                }
+
+                i += 4;
+            }
+            level[0] = levelCount;
+        }
+
+        static void sortOrdered(int[] src1, int[] src2, int[] dst) {
+            int length1 = src1[0];
+            int length2 = src2[0];
+            int count = 1;
+            int i1 = 1;
+            int i2 = 1;
+            int v1 = src1[1];
+            int v2 = src2[1];
+            while(true) {
+
+                LEFT: {
+                    while(i1 < length1) {
+                        v1 = src1[i1];
+                        if (v1 >= v2) {
+                            break LEFT;
+                        }
+                        dst[count++] = v1;
+                        i1++;
+                    }
+                    while(i2 < length2) {
+                        dst[count++] = src2[i2++];
+                    }
+                    dst[0] = count;
+                    return;
+                }
+
+                RIGHT: {
+                    while(i2 < length2) {
+                        v2 = src2[i2];
+                        if (v2 >= v1) {
+                            break RIGHT;
+                        }
+                        dst[count++] = v2;
+                        i2++;
+                    }
+                    while(i1 < length1) {
+                        dst[count++] = src1[i1++];
+                    }
+                    dst[0] = count;
+                    return;
+                }
+
+                if (v1 == v2) {
+                    dst[count++] = v1;
+                    i1++;
+                    i2++;
+                    if (i1 < length1) {
+                        v1 = src1[i1];
+                    }
+                    if (i2 < length2 - 1) {
+                        v2 = src2[i2];
+                    }
+                }
+            }
+            // UNREACHABLE
+        }
+
+    }
+
+    /**
+     * Intersection class provides intersection of two MultiRectAre aobjects
+     */
+    static class Intersection {
+
+        static void intersectRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) {
+
+            Region d1 = new Region(reg1);
+            Region d2 = new Region(reg2);
+
+            int[] level = new int[height1 + height2];
+            int[] level1 = new int[height1];
+            int[] level2 = new int[height2];
+            d1.createLevel(level1);
+            d2.createLevel(level2);
+            Region.sortOrdered(level1, level2, level);
+
+            int top;
+            int bottom = level[1] - 1;
+            for(int i = 2; i < level[0]; i++) {
+
+                top = bottom + 1;
+                bottom = level[i] - 1;
+
+                d1.findActive(top, bottom);
+                d2.findActive(top, bottom);
+
+                int i1 = 1;
+                int i2 = 1;
+
+                while(i1 < d1.active[0] && i2 < d2.active[0]) {
+
+                    int x11 = d1.active[i1];
+                    int x12 = d1.active[i1 + 2];
+                    int x21 = d2.active[i2];
+                    int x22 = d2.active[i2 + 2];
+
+                    if (x11 <= x21) {
+                        if (x12 >= x21) {
+                            if (x12 <= x22) {
+                                dst.addRectCashed(x21, top, x12, bottom);
+                                i1 += 4;
+                            } else {
+                                dst.addRectCashed(x21, top, x22, bottom);
+                                i2 += 4;
+                            }
+                        } else {
+                            i1 += 4;
+                        }
+                    } else {
+                        if (x22 >= x11) {
+                            if (x22 <= x12) {
+                                dst.addRectCashed(x11, top, x22, bottom);
+                                i2 += 4;
+                            } else {
+                                dst.addRectCashed(x11, top, x12, bottom);
+                                i1 += 4;
+                            }
+                        } else {
+                            i2 += 4;
+                        }
+                    }
+                }
+
+                d1.deleteActive(bottom);
+                d2.deleteActive(bottom);
+            }
+        }
+
+        static int[] simpleIntersect(MultiRectArea src1, MultiRectArea src2) {
+            int[] rect1 = src1.rect;
+            int[] rect2 = src2.rect;
+            int[] rect = createBuf(0);
+
+            int k = 1;
+            for(int i = 1; i < rect1[0];) {
+
+                int x11 = rect1[i++];
+                int y11 = rect1[i++];
+                int x12 = rect1[i++];
+                int y12 = rect1[i++];
+
+                for(int j = 1; j < rect2[0];) {
+
+                    int x21 = rect2[j++];
+                    int y21 = rect2[j++];
+                    int x22 = rect2[j++];
+                    int y22 = rect2[j++];
+
+                    if (x11 <= x22 && x12 >= x21 &&
+                        y11 <= y22 && y12 >= y21)
+                    {
+                        rect = checkBufSize(rect, 4);
+                        rect[k++] = x11 > x21 ? x11 : x21;
+                        rect[k++] = y11 > y21 ? y11 : y21;
+                        rect[k++] = x12 > x22 ? x22 : x12;
+                        rect[k++] = y12 > y22 ? y22 : y12;
+                    }
+                }
+            }
+
+            rect[0] = k;
+            return rect;
+        }
+
+        public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) {
+
+            if (src1 == null || src2 == null || src1.isEmpty() || src2.isEmpty()) {
+                return new MultiRectArea();
+            }
+
+            MultiRectArea.RectCash dst = new MultiRectArea.RectCash();
+
+            if (!src1.sorted || !src2.sorted || 
+               src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 
+            {
+                dst.setRect(simpleIntersect(src1, src2), false);
+            } else {
+                Rectangle bounds1 = src1.getBounds();
+                Rectangle bounds2 = src2.getBounds();
+                Rectangle bounds3 = bounds1.intersection(bounds2);
+                if (bounds3.width > 0 && bounds3.height > 0) {
+                    intersectRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2);
+                }
+            }
+
+            return dst;
+        }
+
+    }
+
+    /**
+     * Union class provides union of two MultiRectAre aobjects
+     */
+    static class Union {
+
+        int rx1, rx2;
+        int top, bottom;
+        MultiRectArea.RectCash dst;
+
+        boolean next(Region d, int index) {
+            int x1 = d.active[index];
+            int x2 = d.active[index + 2];
+            boolean res = false;
+
+            if (x2 < rx1 - 1) {
+                res = true;
+                dst.addRectCashed(x1, top, x2, bottom);
+            } else
+                if (x1 > rx2 + 1) {
+                    res = false;
+                    dst.addRectCashed(rx1, top, rx2, bottom);
+                    rx1 = x1;
+                    rx2 = x2;
+                } else {
+                    res = x2 <= rx2;
+                    rx1 = Math.min(x1, rx1);
+                    rx2 = Math.max(x2, rx2);
+                }
+
+            // Top
+            if (d.active[index + 1] < top) {
+                dst.addRectCashed(x1, d.active[index + 1], x2, top - 1);
+            }
+            // Bottom
+            if (d.active[index + 3] > bottom) {
+                d.active[index + 1] = bottom + 1;
+            }
+            return res;
+        }
+
+        void check(Region d, int index, boolean t) {
+            int x1 = d.active[index];
+            int x2 = d.active[index + 2];
+            // Top
+            if (d.active[index + 1] < top) {
+                dst.addRectCashed(x1, d.active[index + 1], x2, top - 1);
+            }
+            if (t) {
+                dst.addRectCashed(x1, top, x2, bottom);
+            }
+            // Bottom
+            if (d.active[index + 3] > bottom) {
+                d.active[index + 1] = bottom + 1;
+            }
+        }
+
+        void unionRegions(int[] reg1, int[] reg2, int height1, int height2) {
+            Region d1 = new Region(reg1);
+            Region d2 = new Region(reg2);
+
+            int[] level = new int[height1 + height2];
+            int[] level1 = new int[height1];
+            int[] level2 = new int[height2];
+            d1.createLevel(level1);
+            d2.createLevel(level2);
+            Region.sortOrdered(level1, level2, level);
+
+            bottom = level[1] - 1;
+            for(int i = 2; i < level[0]; i++) {
+
+                top = bottom + 1;
+                bottom = level[i] - 1;
+
+                d1.findActive(top, bottom);
+                d2.findActive(top, bottom);
+
+                int i1 = 1;
+                int i2 = 1;
+                boolean res1, res2;
+
+                if (d1.active[0] > 1) {
+                    check(d1, 1, false);
+                    rx1 = d1.active[1];
+                    rx2 = d1.active[3];
+                    i1 += 4;
+                    res1 = false;
+                    res2 = true;
+                } else
+                    if (d2.active[0] > 1) {
+                        check(d2, 1, false);
+                        rx1 = d2.active[1];
+                        rx2 = d2.active[3];
+                        i2 += 4;
+                        res1 = true;
+                        res2 = false;
+                    } else {
+                        continue;
+                    }
+
+            outer:
+                while(true) {
+
+                    while (res1) {
+                        if (i1 >= d1.active[0]) {
+                            dst.addRectCashed(rx1, top, rx2, bottom);
+                            while(i2 < d2.active[0]) {
+                                check(d2, i2, true);
+                                i2 += 4;
+                            }
+                            break outer;
+                        }
+                        res1 = next(d1, i1);
+                        i1 += 4;
+                    }
+
+                    while (res2) {
+                        if (i2 >= d2.active[0]) {
+                            dst.addRectCashed(rx1, top, rx2, bottom);
+                            while(i1 < d1.active[0]) {
+                                check(d1, i1, true);
+                                i1 += 4;
+                            }
+                            break outer;
+                        }
+                        res2 = next(d2, i2);
+                        i2 += 4;
+                    }
+
+                    res1 = true;
+                    res2 = true;
+                } // while
+
+                d1.deleteActive(bottom);
+                d2.deleteActive(bottom);
+
+            }
+        }
+
+        static void simpleUnion(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) {
+            if (src1.getRectCount() < src2.getRectCount()) {
+                simpleUnion(src2, src1, dst);
+            } else {
+                Subtraction.simpleSubtract(src1, src2, dst);
+                int pos = dst.rect[0];
+                int size = src2.rect[0] - 1;
+                dst.rect = checkBufSize(dst.rect, size);
+                System.arraycopy(src2.rect,1, dst.rect, pos, size);
+                dst.resort();
+            }
+        }
+
+        MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) {
+
+            if (src1 == null || src1.isEmpty()) {
+                return new MultiRectArea(src2);
+            }
+
+            if (src2 == null || src2.isEmpty()) {
+                return new MultiRectArea(src1);
+            }
+
+            dst = new MultiRectArea.RectCash();
+
+            if (!src1.sorted || !src2.sorted ||
+               src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 
+            {
+                simpleUnion(src1, src2, dst);
+            } else {
+                Rectangle bounds1 = src1.getBounds();
+                Rectangle bounds2 = src2.getBounds();
+                Rectangle bounds3 = bounds1.intersection(bounds2);
+
+                if (bounds3.width < 0 || bounds3.height < 0) {
+                    if (bounds1.y + bounds1.height < bounds2.y) {
+                        dst.setRect(addVerRegion(src1.rect, src2.rect), false);
+                    } else
+                        if (bounds2.y + bounds2.height < bounds1.y) {
+                            dst.setRect(addVerRegion(src2.rect, src1.rect), false);
+                        } else
+                            if (bounds1.x < bounds2.x) {
+                                dst.setRect(addHorRegion(src1.rect, src2.rect), false);
+                            } else {
+                                dst.setRect(addHorRegion(src2.rect, src1.rect), false);
+                            }
+                } else {
+                    unionRegions(src1.rect, src2.rect, bounds1.height + 2, bounds2.height + 2);
+                }
+            }
+
+            return dst;
+        }
+
+        int[] addVerRegion(int[] top, int[] bottom) {
+            int length = top[0] + bottom[0] - 1;
+            int[] dst = new int[length];
+            dst[0] = length;
+            System.arraycopy(top, 1, dst, 1, top[0] - 1);
+            System.arraycopy(bottom, 1, dst, top[0], bottom[0] - 1);
+            return dst;
+        }
+
+        int[] addHorRegion(int[] left, int[] right) {
+            int count1 = left[0];
+            int count2 = right[0];
+            int[] dst = new int[count1 + count2 + 1];
+            int count = 1;
+            int index1 = 1;
+            int index2 = 1;
+
+            int top1 = left[2];
+            int top2 = right[2];
+            int pos1, pos2;
+
+            while(true) {
+
+                if (index1 >= count1) {
+                    System.arraycopy(right, index2, dst, count, count2 - index2);
+                    count += count2 - index2;
+                    break;
+                }
+                if (index2 >= count2) {
+                    System.arraycopy(left, index1, dst, count, count1 - index1);
+                    count += count1 - index1;
+                    break;
+                }
+
+                if (top1 < top2) {
+                    pos1 = index1;
+                    do {
+                        index1 += 4;
+                    } while (index1 < count1 && (top1 = left[index1 + 1]) < top2);
+                    System.arraycopy(left, pos1, dst, count, index1 - pos1);
+                    count += index1 - pos1;
+                    continue;
+                }
+
+                if (top1 > top2) {
+                    pos2 = index2;
+                    do {
+                        index2 += 4;
+                    } while (index2 < count2 && (top2 = right[index2 + 1]) < top1);
+                    System.arraycopy(right, pos2, dst, count, index2 - pos2);
+                    count += index2 - pos2;
+                    continue;
+                }
+
+                int top = top1;
+                pos1 = index1;
+                pos2 = index2;
+                do  {
+                    index1 += 4;
+                } while(index1 < count1 && (top1 = left[index1 + 1]) == top);
+                do {
+                    index2 += 4;
+                } while(index2 < count2 && (top2 = right[index2 + 1]) == top);
+
+                System.arraycopy(left, pos1, dst, count, index1 - pos1);
+                count += index1 - pos1;
+                System.arraycopy(right, pos2, dst, count, index2 - pos2);
+                count += index2 - pos2;
+            }
+
+            dst[0] = count;
+            return dst;
+        }
+
+    }
+
+    /**
+     * Subtraction class provides subtraction of two MultiRectAre aobjects
+     */
+    static class Subtraction {
+
+        static void subtractRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) {
+            Region d1 = new Region(reg1);
+            Region d2 = new Region(reg2);
+
+            int[] level = new int[height1 + height2];
+            int[] level1 = new int[height1];
+            int[] level2 = new int[height2];
+            d1.createLevel(level1);
+            d2.createLevel(level2);
+            Region.sortOrdered(level1, level2, level);
+
+            int top;
+            int bottom = level[1] - 1;
+            for(int i = 2; i < level[0]; i++) {
+
+                top = bottom + 1;
+                bottom = level[i] - 1;
+
+                d1.findActive(top, bottom);
+                if (d1.active[0] == 1) {
+                    d2.deleteActive(bottom);
+                    continue;
+                }
+
+                d2.findActive(top, bottom);
+
+                int i1 = 1;
+                int i2 = 1;
+
+                int rx1 = 0;
+                int rx2 = 0;
+
+                boolean next = true;
+
+                while(true) {
+
+                    if (next) {
+                        next = false;
+                        if (i1 >= d1.active[0]) {
+                            break;
+                        }
+                        // Bottom
+                        d1.active[i1 + 1] = bottom + 1;
+                        rx1 = d1.active[i1];
+                        rx2 = d1.active[i1 + 2];
+                        i1 += 4;
+                    }
+
+                    if (i2 >= d2.active[0]) {
+                        dst.addRectCashed(rx1, top, rx2, bottom);
+                        for(int j = i1; j < d1.active[0]; j += 4) {
+                            dst.addRectCashed(d1.active[j], top, d1.active[j + 2], bottom);
+                            d1.active[j + 1] = bottom + 1;
+                        }
+                        break;
+                    }
+
+                    int x1 = d2.active[i2];
+                    int x2 = d2.active[i2 + 2];
+
+                    if (rx1 < x1) {
+                        if (rx2 >= x1) {
+                            if (rx2 <= x2) {
+                                //  [-----------]
+                                //       [-------------]
+                                dst.addRectCashed(rx1, top, x1 - 1, bottom);
+                                next = true;
+                            } else {
+                                // [-----------------]
+                                //      [------]
+                                dst.addRectCashed(rx1, top, x1 - 1, bottom);
+                                rx1 = x2 + 1;
+                                i2 += 4;
+                            }
+                        } else {
+                            // [-----]
+                            //         [----]
+                            dst.addRectCashed(rx1, top, rx2, bottom);
+                            next = true;
+                        }
+                    } else {
+                        if (rx1 <= x2) {
+                            if (rx2 <= x2) {
+                                //    [------]
+                                //  [-----------]
+                                next = true;
+                            } else {
+                                //     [------------]
+                                // [---------]
+                                rx1 = x2 + 1;
+                                i2 += 4;
+                            }
+                        } else {
+                            //         [----]
+                            // [-----]
+                            i2 += 4;
+                        }
+                    }
+
+                }
+                d1.deleteActive();
+                d2.deleteActive(bottom);
+            }
+        }
+
+        static void subtractRect(int x11, int y11, int x12, int y12, int[] rect, int index, MultiRectArea dst) {
+
+            for(int i = index; i < rect[0]; i += 4) {
+                int x21 = rect[i + 0];
+                int y21 = rect[i + 1];
+                int x22 = rect[i + 2];
+                int y22 = rect[i + 3];
+
+                if (x11 <= x22 && x12 >= x21 && y11 <= y22 && y12 >= y21) {
+                    int top, bottom;
+                    if (y11 < y21) {
+                        subtractRect(x11, y11, x12, y21 - 1, rect, i + 4, dst);
+                        top = y21;
+                    } else {
+                        top = y11;
+                    }
+                    if (y12 > y22) {
+                        subtractRect(x11, y22 + 1, x12, y12, rect, i + 4, dst);
+                        bottom = y22;
+                    } else {
+                        bottom = y12;
+                    }
+                    if (x11 < x21) {
+                        subtractRect(x11, top, x21 - 1, bottom, rect, i + 4, dst);
+                    }
+                    if (x12 > x22) {
+                        subtractRect(x22 + 1, top, x12, bottom, rect, i + 4, dst);
+                    }
+                    return;
+                }
+            }
+            dst.addRect(x11, y11, x12, y12);
+        }
+
+        static void simpleSubtract(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) {
+            for(int i = 1; i < src1.rect[0]; i += 4) {
+                subtractRect(
+                        src1.rect[i + 0],
+                        src1.rect[i + 1],
+                        src1.rect[i + 2],
+                        src1.rect[i + 3],
+                        src2.rect,
+                        1,
+                        dst);
+            }
+            dst.resort();
+        }
+
+        public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) {
+
+            if (src1 == null || src1.isEmpty()) {
+                return new MultiRectArea();
+            }
+
+            if (src2 == null || src2.isEmpty()) {
+                return new MultiRectArea(src1);
+            }
+
+            MultiRectArea.RectCash dst = new MultiRectArea.RectCash();
+
+            if (!src1.sorted || !src2.sorted ||
+               src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 
+            {
+                simpleSubtract(src1, src2, dst);
+            } else {
+                Rectangle bounds1 = src1.getBounds();
+                Rectangle bounds2 = src2.getBounds();
+                Rectangle bounds3 = bounds1.intersection(bounds2);
+
+                if (bounds3.width > 0 && bounds3.height > 0) {
+                    subtractRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2);
+                } else {
+                    dst.setRect(src1.rect, true);
+                }
+            }
+
+            return dst;
+        }
+
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/Surface.java b/awt/org/apache/harmony/awt/gl/Surface.java
new file mode 100644
index 0000000..8b0ae38
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/Surface.java
@@ -0,0 +1,309 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 10.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+
+
+/**
+ * This class is super class for others types of Surfaces. 
+ * Surface is storing data and data format description, that are using
+ * in blitting operations    
+ */
+public abstract class Surface implements Transparency{
+
+    // Color Space Types
+    public static final int sRGB_CS = 1;
+    public static final int Linear_RGB_CS = 2;
+    public static final int Linear_Gray_CS = 3;
+    public static final int Custom_CS = 0;
+    
+    // Color Model Types
+    public static final int DCM = 1;  // Direct Color Model
+    public static final int ICM = 2;  // Index Color Model
+    public static final int CCM = 3;  // Component Color Model
+
+    // Sample Model Types
+    public static final int SPPSM = 1;  // Single Pixel Packed Sample Model
+    public static final int MPPSM = 2;  // Multi Pixel Packed Sample Model
+    public static final int CSM   = 3;  // Component Sample Model
+    public static final int PISM  = 4;  // Pixel Interleaved Sample Model
+    public static final int BSM   = 5;  // Banded Sample Model
+
+    // Surface Types
+    private static final int ALPHA_MASK = 0xff000000;
+    private static final int RED_MASK = 0x00ff0000;
+    private static final int GREEN_MASK = 0x0000ff00;
+    private static final int BLUE_MASK = 0x000000ff;
+    private static final int RED_BGR_MASK = 0x000000ff;
+    private static final int GREEN_BGR_MASK = 0x0000ff00;
+    private static final int BLUE_BGR_MASK = 0x00ff0000;
+    private static final int RED_565_MASK = 0xf800;
+    private static final int GREEN_565_MASK = 0x07e0;
+    private static final int BLUE_565_MASK = 0x001f;
+    private static final int RED_555_MASK = 0x7c00;
+    private static final int GREEN_555_MASK = 0x03e0;
+    private static final int BLUE_555_MASK = 0x001f;
+
+    static{
+        //???AWT
+        /*
+        System.loadLibrary("gl"); //$NON-NLS-1$
+        initIDs();
+        */
+    }
+
+
+    protected long surfaceDataPtr;        // Pointer for Native Surface data
+    protected int transparency = OPAQUE;
+    protected int width;
+    protected int height;
+
+    /**
+     * This list contains caches with the data of this surface that are valid at the moment.
+     * Surface should clear this list when its data is updated.
+     * Caches may check if they are still valid using isCacheValid method.
+     * When cache gets data from the surface, it should call addValidCache method of the surface.
+     */
+    private final ArrayList<Object> validCaches = new ArrayList<Object>();
+
+    public abstract ColorModel getColorModel();
+    public abstract WritableRaster getRaster();
+    public abstract int getSurfaceType(); // Syrface type. It is equal 
+                                          // BufferedImge type
+    /**
+     * Lock Native Surface data
+     */
+    public abstract long lock();     
+    
+    /**
+     * Unlock Native Surface data 
+     */
+    public abstract void unlock();
+    
+    /**
+     * Dispose Native Surface data
+     */
+    public abstract void dispose();
+    public abstract Surface getImageSurface();
+
+    public long getSurfaceDataPtr(){
+        return surfaceDataPtr;
+    }
+
+    public final boolean isCaheValid(Object cache) {
+        return validCaches.contains(cache);
+    }
+
+    public final void addValidCache(Object cache) {
+        validCaches.add(cache);
+    }
+
+    protected final void clearValidCaches() {
+        validCaches.clear();
+    }
+
+    /**
+     * Returns could or coldn't the Surface be blit by Native blitter 
+     * @return - true if the Surface could be blit by Native blitter, 
+     *           false in other case
+     */
+    public boolean isNativeDrawable(){
+        return true;
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+
+    public int getWidth(){
+        return width;
+    }
+
+    public int getHeight(){
+        return height;
+    }
+    
+    /**
+     * If Surface has Raster, this method returns data array of Raster's DataBuffer
+     * @return - data array
+     */
+    public Object getData(){
+        return null;
+    }
+    
+    public boolean invalidated(){
+        return true;
+    }
+    
+    public void validate(){}
+    
+    public void invalidate(){}
+
+    /**
+     * Computation type of BufferedImage or Surface
+     * @param cm - ColorModel
+     * @param raster - WritableRaste
+     * @return - type of BufferedImage
+     */
+    public static int getType(ColorModel cm, WritableRaster raster){
+        int transferType = cm.getTransferType();
+        boolean hasAlpha = cm.hasAlpha();
+        ColorSpace cs = cm.getColorSpace();
+        int csType = cs.getType();
+        SampleModel sm = raster.getSampleModel();
+
+        if(csType == ColorSpace.TYPE_RGB){
+            if(cm instanceof DirectColorModel){
+                DirectColorModel dcm = (DirectColorModel) cm;
+                switch (transferType) {
+                case DataBuffer.TYPE_INT:
+                    if (dcm.getRedMask() == RED_MASK &&
+                            dcm.getGreenMask() == GREEN_MASK &&
+                            dcm.getBlueMask() == BLUE_MASK) {
+                        if (!hasAlpha) {
+                            return BufferedImage.TYPE_INT_RGB;
+                        }
+                        if (dcm.getAlphaMask() == ALPHA_MASK) {
+                            if (dcm.isAlphaPremultiplied()) {
+                                return BufferedImage.TYPE_INT_ARGB_PRE;
+                            }
+                            return BufferedImage.TYPE_INT_ARGB;
+                        }
+                        return BufferedImage.TYPE_CUSTOM;
+                    } else if (dcm.getRedMask() == RED_BGR_MASK &&
+                            dcm.getGreenMask() == GREEN_BGR_MASK &&
+                            dcm.getBlueMask() == BLUE_BGR_MASK) {
+                        if (!hasAlpha) {
+                            return BufferedImage.TYPE_INT_BGR;
+                        }
+                    } else {
+                        return BufferedImage.TYPE_CUSTOM;
+                    }
+                case DataBuffer.TYPE_USHORT:
+                    if (dcm.getRedMask() == RED_555_MASK &&
+                            dcm.getGreenMask() == GREEN_555_MASK &&
+                            dcm.getBlueMask() == BLUE_555_MASK && !hasAlpha) {
+                        return BufferedImage.TYPE_USHORT_555_RGB;
+                    } else if (dcm.getRedMask() == RED_565_MASK &&
+                            dcm.getGreenMask() == GREEN_565_MASK &&
+                            dcm.getBlueMask() == BLUE_565_MASK) {
+                        return BufferedImage.TYPE_USHORT_565_RGB;
+                    }
+                default:
+                    return BufferedImage.TYPE_CUSTOM;
+                }
+            }else if(cm instanceof IndexColorModel){
+                IndexColorModel icm = (IndexColorModel) cm;
+                int pixelBits = icm.getPixelSize();
+                if(transferType == DataBuffer.TYPE_BYTE){
+                    if(sm instanceof MultiPixelPackedSampleModel && !hasAlpha &&
+                        pixelBits < 5){
+                            return BufferedImage.TYPE_BYTE_BINARY;
+                    }else if(pixelBits == 8){
+                        return BufferedImage.TYPE_BYTE_INDEXED;
+                    }
+                }
+                return BufferedImage.TYPE_CUSTOM;
+            }else if(cm instanceof ComponentColorModel){
+                ComponentColorModel ccm = (ComponentColorModel) cm;
+                if(transferType == DataBuffer.TYPE_BYTE &&
+                        sm instanceof ComponentSampleModel){
+                    ComponentSampleModel csm =
+                        (ComponentSampleModel) sm;
+                    int[] offsets = csm.getBandOffsets();
+                    int[] bits = ccm.getComponentSize();
+                    boolean isCustom = false;
+                    for (int i = 0; i < bits.length; i++) {
+                        if (bits[i] != 8 ||
+                               offsets[i] != offsets.length - 1 - i) {
+                            isCustom = true;
+                            break;
+                        }
+                    }
+                    if (!isCustom) {
+                        if (!ccm.hasAlpha()) {
+                            return BufferedImage.TYPE_3BYTE_BGR;
+                        } else if (ccm.isAlphaPremultiplied()) {
+                            return BufferedImage.TYPE_4BYTE_ABGR_PRE;
+                        } else {
+                            return BufferedImage.TYPE_4BYTE_ABGR;
+                        }
+                    }
+                }
+                return BufferedImage.TYPE_CUSTOM;
+            }
+            return BufferedImage.TYPE_CUSTOM;
+        }else if(cs == LUTColorConverter.LINEAR_GRAY_CS){
+            if(cm instanceof ComponentColorModel &&
+                    cm.getNumComponents() == 1){
+                int bits[] = cm.getComponentSize();
+                if(transferType == DataBuffer.TYPE_BYTE &&
+                        bits[0] == 8){
+                    return BufferedImage.TYPE_BYTE_GRAY;
+                }else if(transferType == DataBuffer.TYPE_USHORT &&
+                        bits[0] == 16){
+                    return BufferedImage.TYPE_USHORT_GRAY;
+                }else{
+                    return BufferedImage.TYPE_CUSTOM;
+                }
+            }
+            return BufferedImage.TYPE_CUSTOM;
+        }
+        return BufferedImage.TYPE_CUSTOM;
+    }
+
+    public static Surface getImageSurface(Image image){
+        return AwtImageBackdoorAccessor.getInstance().getImageSurface(image);
+    }
+
+    @Override
+    protected void finalize() throws Throwable{
+        dispose();
+    }
+
+    public static boolean isGrayPallete(IndexColorModel icm){
+        return AwtImageBackdoorAccessor.getInstance().isGrayPallete(icm);
+    }
+
+    /**
+     * Initialization of Native data
+     * 
+     */
+    //???AWT: private static native void initIDs();
+}
diff --git a/awt/org/apache/harmony/awt/gl/TextRenderer.java b/awt/org/apache/harmony/awt/gl/TextRenderer.java
new file mode 100644
index 0000000..f57952d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/TextRenderer.java
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Graphics2D;
+import java.awt.font.GlyphVector;
+
+public abstract class TextRenderer {
+    
+    /**
+     * Draws string on specified Graphics at desired position.
+     * 
+     * @param g specified Graphics2D object
+     * @param str String object to draw
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     */
+    public abstract void drawString(Graphics2D g, String str, float x, float y);
+
+    /**
+     * Draws string on specified Graphics at desired position.
+     * 
+     * @param g specified Graphics2D object
+     * @param str String object to draw
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     */    
+    public void drawString(Graphics2D g, String str, int x, int y){
+        drawString(g, str, (float)x, (float)y);
+    }
+
+    /**
+     * Draws GlyphVector on specified Graphics at desired position.
+     * 
+     * @param g specified Graphics2D object
+     * @param glyphVector GlyphVector object to draw
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     */
+    public abstract void drawGlyphVector(Graphics2D g, GlyphVector glyphVector, float x, float y);
+}
diff --git a/awt/org/apache/harmony/awt/gl/XORComposite.java b/awt/org/apache/harmony/awt/gl/XORComposite.java
new file mode 100644
index 0000000..e27e1d3
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/XORComposite.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 21.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.RenderingHints;
+import java.awt.image.ColorModel;
+
+public class XORComposite implements Composite {
+
+    Color xorcolor;
+
+    public XORComposite(Color xorcolor){
+        this.xorcolor = xorcolor;
+    }
+
+    public CompositeContext createContext(ColorModel srcCM, ColorModel dstCM,
+            RenderingHints hints) {
+
+        return new ICompositeContext(this, srcCM, dstCM);
+    }
+
+    public Color getXORColor(){
+        return xorcolor;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/color/ColorConverter.java b/awt/org/apache/harmony/awt/gl/color/ColorConverter.java
new file mode 100644
index 0000000..c98e114
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/ColorConverter.java
@@ -0,0 +1,257 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+/**
+ * This class combines ColorScaler, ICC_Transform and NativeImageFormat functionality
+ * in the workflows for different types of input/output pixel data.
+ */
+public class ColorConverter {
+    private ColorScaler scaler = new ColorScaler();
+
+    public void loadScalingData(ColorSpace cs) {
+        scaler.loadScalingData(cs);
+    }
+
+    /**
+     * Translates pixels, stored in source buffered image and writes the data
+     * to the destination image.
+     * @param t - ICC transform
+     * @param src - source image
+     * @param dst - destination image
+     */
+    public void translateColor(ICC_Transform t,
+            BufferedImage src, BufferedImage dst) {
+      NativeImageFormat srcIF = NativeImageFormat.createNativeImageFormat(src);
+      NativeImageFormat dstIF = NativeImageFormat.createNativeImageFormat(dst);
+
+      if (srcIF != null && dstIF != null) {
+          t.translateColors(srcIF, dstIF);
+          return;
+      }
+
+        srcIF = createImageFormat(src);
+        dstIF = createImageFormat(dst);
+
+        short srcChanData[] = (short[]) srcIF.getChannelData();
+        short dstChanData[] = (short[]) dstIF.getChannelData();
+
+        ColorModel srcCM = src.getColorModel();
+        int nColorChannels = srcCM.getNumColorComponents();
+        scaler.loadScalingData(srcCM.getColorSpace()); // input scaling data
+        ColorModel dstCM = dst.getColorModel();
+
+        // Prepare array for alpha channel
+        float alpha[] = null;
+        boolean saveAlpha = srcCM.hasAlpha() && dstCM.hasAlpha();
+        if (saveAlpha) {
+            alpha = new float[src.getWidth()*src.getHeight()];
+        }
+
+        WritableRaster wr = src.getRaster();
+        int srcDataPos = 0, alphaPos = 0;
+        float normalizedVal[];
+        for (int row=0, nRows = srcIF.getNumRows(); row<nRows; row++) {
+            for (int col=0, nCols = srcIF.getNumCols(); col<nCols; col++) {
+                normalizedVal = srcCM.getNormalizedComponents(
+                    wr.getDataElements(col, row, null),
+                    null, 0);
+                // Save alpha channel
+                if (saveAlpha) {
+                    // We need nColorChannels'th element cause it's nChannels - 1
+                    alpha[alphaPos++] = normalizedVal[nColorChannels];
+                }
+                scaler.scale(normalizedVal, srcChanData, srcDataPos);
+                srcDataPos += nColorChannels;
+            }
+        }
+
+        t.translateColors(srcIF, dstIF);
+
+        nColorChannels = dstCM.getNumColorComponents();
+        boolean fillAlpha = dstCM.hasAlpha();
+        scaler.loadScalingData(dstCM.getColorSpace()); // output scaling data
+        float dstPixel[] = new float[dstCM.getNumComponents()];
+        int dstDataPos = 0;
+        alphaPos = 0;
+        wr = dst.getRaster();
+
+        for (int row=0, nRows = dstIF.getNumRows(); row<nRows; row++) {
+            for (int col=0, nCols = dstIF.getNumCols(); col<nCols; col++) {
+                scaler.unscale(dstPixel, dstChanData, dstDataPos);
+                dstDataPos += nColorChannels;
+                if (fillAlpha) {
+                    if (saveAlpha) {
+                        dstPixel[nColorChannels] = alpha[alphaPos++];
+                    } else {
+                        dstPixel[nColorChannels] = 1f;
+                    }
+                }
+                wr.setDataElements(col, row,
+                        dstCM.getDataElements(dstPixel, 0 , null));
+            }
+        }
+    }
+
+    /**
+     * Translates pixels, stored in the float data buffer.
+     * Each pixel occupies separate array. Input pixels passed in the buffer
+     * are replaced by output pixels and then the buffer is returned
+     * @param t - ICC transform
+     * @param buffer - data buffer
+     * @param srcCS - source color space
+     * @param dstCS - destination color space
+     * @param nPixels - number of pixels
+     * @return translated pixels
+     */
+    public float[][] translateColor(ICC_Transform t,
+            float buffer[][],
+            ColorSpace srcCS,
+            ColorSpace dstCS,
+            int nPixels) {
+        // Scale source data
+        if (srcCS != null) { // if it is null use old scaling data
+            scaler.loadScalingData(srcCS);
+        }
+        int nSrcChannels = t.getNumInputChannels();
+        short srcShortData[] = new short[nPixels*nSrcChannels];
+        for (int i=0, srcDataPos = 0; i<nPixels; i++) {
+            scaler.scale(buffer[i], srcShortData, srcDataPos);
+            srcDataPos += nSrcChannels;
+        }
+
+        // Apply transform
+        short dstShortData[] = this.translateColor(t, srcShortData, null);
+
+        int nDstChannels = t.getNumOutputChannels();
+        int bufferSize = buffer[0].length;
+        if (bufferSize < nDstChannels + 1) { // Re-allocate buffer if needed
+            for (int i=0; i<nPixels; i++) {
+                // One extra element reserved for alpha
+                buffer[i] = new float[nDstChannels + 1];
+            }
+        }
+
+        // Unscale destination data
+        if (dstCS != null) { // if it is null use old scaling data
+            scaler.loadScalingData(dstCS);
+        }
+        for (int i=0, dstDataPos = 0; i<nPixels; i++) {
+            scaler.unscale(buffer[i], dstShortData, dstDataPos);
+            dstDataPos += nDstChannels;
+        }
+
+        return buffer;
+    }
+
+    /**
+     * Translates pixels stored in a raster.
+     * All data types are supported
+     * @param t - ICC transform
+     * @param src - source pixels
+     * @param dst - destination pixels
+     */
+   public void translateColor(ICC_Transform t, Raster src, WritableRaster dst) {
+        try{
+            NativeImageFormat srcFmt = NativeImageFormat.createNativeImageFormat(src);
+            NativeImageFormat dstFmt = NativeImageFormat.createNativeImageFormat(dst);
+
+          if (srcFmt != null && dstFmt != null) {
+              t.translateColors(srcFmt, dstFmt);
+              return;
+          }
+        } catch (IllegalArgumentException e) {
+      }
+
+        // Go ahead and rescale the source image
+        scaler.loadScalingData(src, t.getSrc());
+        short srcData[] = scaler.scale(src);
+
+        short dstData[] = translateColor(t, srcData, null);
+
+        scaler.loadScalingData(dst, t.getDst());
+        scaler.unscale(dstData, dst);
+   }
+
+    /**
+     * Translates pixels stored in an array of shorts.
+     * Samples are stored one-by-one, i.e. array structure is like following: RGBRGBRGB...
+     * The number of pixels is (size of the array) / (number of components).
+     * @param t - ICC transform
+     * @param src - source pixels
+     * @param dst - destination pixels
+     * @return destination pixels, stored in the array, passed in dst
+     */
+    public short[] translateColor(ICC_Transform t, short src[], short dst[]) {
+        NativeImageFormat srcFmt = createImageFormat(t, src, 0, true);
+        NativeImageFormat dstFmt = createImageFormat(t, dst, srcFmt.getNumCols(), false);
+
+        t.translateColors(srcFmt, dstFmt);
+
+        return (short[]) dstFmt.getChannelData();
+    }
+
+
+    /**
+     * Creates NativeImageFormat from buffered image.
+     * @param bi - buffered image
+     * @return created NativeImageFormat
+     */
+    private NativeImageFormat createImageFormat(BufferedImage bi) {
+        int nRows = bi.getHeight();
+        int nCols = bi.getWidth();
+        int nComps = bi.getColorModel().getNumColorComponents();
+        short imgData[] = new short[nRows*nCols*nComps];
+        return new NativeImageFormat(
+                imgData, nComps, nRows, nCols);
+    }
+
+    /**
+     * Creates one-row NativeImageFormat, using either nCols if it is positive,
+     * or arr.length to determine the number of pixels
+     *
+     * @param t - transform
+     * @param arr - short array or null if nCols is positive
+     * @param nCols - number of pixels in the array or 0 if array is not null
+     * @param in - is it an input or output array
+     * @return one-row NativeImageFormat
+     */
+    private NativeImageFormat createImageFormat(
+            ICC_Transform t, short arr[], int nCols, boolean in
+    ) {
+        int nComponents = in ? t.getNumInputChannels() : t.getNumOutputChannels();
+
+        if (arr == null || arr.length < nCols*nComponents) {
+            arr = new short[nCols*nComponents];
+        }
+
+        if (nCols == 0)
+            nCols = arr.length / nComponents;
+
+        return new NativeImageFormat(arr, nComponents, 1, nCols);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/color/ColorScaler.java b/awt/org/apache/harmony/awt/gl/color/ColorScaler.java
new file mode 100644
index 0000000..a1cc169
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/ColorScaler.java
@@ -0,0 +1,355 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+
+/**
+ * This class provides functionality for scaling color data when
+ * ranges of the source and destination color values differs. 
+ */
+public class ColorScaler {
+    private static final float MAX_SHORT = 0xFFFF;
+    private static final float MAX_SIGNED_SHORT = 0x7FFF;
+
+    private static final float MAX_XYZ = 1f + (32767f/32768f);
+
+    // Cached values for scaling color data
+    private float[] channelMinValues = null;
+    private float[] channelMulipliers = null; // for scale
+    private float[] invChannelMulipliers = null; // for unscale
+
+    int nColorChannels = 0;
+
+    // For scaling rasters, false if transfer type is double or float
+    boolean isTTypeIntegral = false;
+
+    /**
+     * Loads scaling data for raster. Note, if profile pf is null,
+     * for non-integral data types multipliers are not initialized.
+     * @param r - raster
+     * @param pf - profile which helps to determine the ranges of the color data
+     */
+    public void loadScalingData(Raster r, ICC_Profile pf) {
+        boolean isSrcTTypeIntegral =
+            r.getTransferType() != DataBuffer.TYPE_FLOAT &&
+            r.getTransferType() != DataBuffer.TYPE_DOUBLE;
+        if (isSrcTTypeIntegral)
+            loadScalingData(r.getSampleModel());
+        else if (pf != null)
+            loadScalingData(pf);
+    }
+
+    /**
+     * Use this method only for integral transfer types.
+     * Extracts min/max values from the sample model
+     * @param sm - sample model
+     */
+    public void loadScalingData(SampleModel sm) {
+        // Supposing integral transfer type
+        isTTypeIntegral = true;
+
+        nColorChannels = sm.getNumBands();
+
+        channelMinValues = new float[nColorChannels];
+        channelMulipliers = new float[nColorChannels];
+        invChannelMulipliers = new float[nColorChannels];
+
+        boolean isSignedShort =
+            (sm.getTransferType() == DataBuffer.TYPE_SHORT);
+
+        float maxVal;
+        for (int i=0; i<nColorChannels; i++) {
+            channelMinValues[i] = 0;
+            if (isSignedShort) {
+                channelMulipliers[i] = MAX_SHORT / MAX_SIGNED_SHORT;
+                invChannelMulipliers[i] = MAX_SIGNED_SHORT / MAX_SHORT;
+            } else {
+                maxVal = ((1 << sm.getSampleSize(i)) - 1);
+                channelMulipliers[i] = MAX_SHORT / maxVal;
+                invChannelMulipliers[i] = maxVal / MAX_SHORT;
+            }
+        }
+    }
+
+    /**
+     * Use this method only for double of float transfer types.
+     * Extracts scaling data from the color space signature
+     * and other tags, stored in the profile
+     * @param pf - ICC profile
+     */
+    public void loadScalingData(ICC_Profile pf) {
+        // Supposing double or float transfer type
+        isTTypeIntegral = false;
+
+        nColorChannels = pf.getNumComponents();
+
+        // Get min/max values directly from the profile
+        // Very much like fillMinMaxValues in ICC_ColorSpace
+        float maxValues[] = new float[nColorChannels];
+        float minValues[] = new float[nColorChannels];
+
+        switch (pf.getColorSpaceType()) {
+            case ColorSpace.TYPE_XYZ:
+                minValues[0] = 0;
+                minValues[1] = 0;
+                minValues[2] = 0;
+                maxValues[0] = MAX_XYZ;
+                maxValues[1] = MAX_XYZ;
+                maxValues[2] = MAX_XYZ;
+                break;
+            case ColorSpace.TYPE_Lab:
+                minValues[0] = 0;
+                minValues[1] = -128;
+                minValues[2] = -128;
+                maxValues[0] = 100;
+                maxValues[1] = 127;
+                maxValues[2] = 127;
+                break;
+            default:
+                for (int i=0; i<nColorChannels; i++) {
+                    minValues[i] = 0;
+                    maxValues[i] = 1;
+                }
+        }
+
+        channelMinValues = minValues;
+        channelMulipliers = new float[nColorChannels];
+        invChannelMulipliers = new float[nColorChannels];
+
+        for (int i = 0; i < nColorChannels; i++) {
+            channelMulipliers[i] =
+                MAX_SHORT / (maxValues[i] - channelMinValues[i]);
+
+            invChannelMulipliers[i] =
+                (maxValues[i] - channelMinValues[i]) / MAX_SHORT;
+        }
+    }
+
+    /**
+     * Extracts scaling data from the color space
+     * @param cs - color space
+     */
+    public void loadScalingData(ColorSpace cs) {
+        nColorChannels = cs.getNumComponents();
+
+        channelMinValues = new float[nColorChannels];
+        channelMulipliers = new float[nColorChannels];
+        invChannelMulipliers = new float[nColorChannels];
+
+        for (int i = 0; i < nColorChannels; i++) {
+            channelMinValues[i] = cs.getMinValue(i);
+
+            channelMulipliers[i] =
+                MAX_SHORT / (cs.getMaxValue(i) - channelMinValues[i]);
+
+            invChannelMulipliers[i] =
+                (cs.getMaxValue(i) - channelMinValues[i]) / MAX_SHORT;
+        }
+    }
+
+    /**
+     * Scales and normalizes the whole raster and returns the result
+     * in the float array
+     * @param r - source raster
+     * @return scaled and normalized raster data
+     */
+    public float[][] scaleNormalize(Raster r) {
+        int width = r.getWidth();
+        int height = r.getHeight();
+        float result[][] = new float[width*height][nColorChannels];
+        float normMultipliers[] = new float[nColorChannels];
+
+        int pos = 0;
+        if (isTTypeIntegral) {
+            // Change max value from MAX_SHORT to 1f
+            for (int i=0; i<nColorChannels; i++) {
+                normMultipliers[i] = channelMulipliers[i] / MAX_SHORT;
+            }
+
+            int sample;
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        sample = r.getSample(row, col, chan);
+                        result[pos][chan] = (sample * normMultipliers[chan]);
+                    }
+                    pos++;
+                }
+            }
+        } else { // Just get the samples...
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        result[pos][chan] = r.getSampleFloat(row, col, chan);
+                    }
+                    pos++;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Unscale the whole float array and put the result
+     * in the raster
+     * @param r - destination raster
+     * @param data - input pixels
+     */
+    public void unscaleNormalized(WritableRaster r, float data[][]) {
+        int width = r.getWidth();
+        int height = r.getHeight();
+        float normMultipliers[] = new float[nColorChannels];
+
+        int pos = 0;
+        if (isTTypeIntegral) {
+            // Change max value from MAX_SHORT to 1f
+            for (int i=0; i<nColorChannels; i++) {
+                normMultipliers[i] = invChannelMulipliers[i] * MAX_SHORT;
+            }
+
+            int sample;
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        sample = (int) (data[pos][chan] * normMultipliers[chan] + 0.5f);
+                        r.setSample(row, col, chan, sample);
+                    }
+                    pos++;
+                }
+            }
+        } else { // Just set the samples...
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        r.setSample(row, col, chan, data[pos][chan]);
+                    }
+                    pos++;
+                }
+            }
+        }
+    }
+
+    /**
+     * Scales the whole raster to short and returns the result
+     * in the array
+     * @param r - source raster
+     * @return scaled and normalized raster data
+     */
+    public short[] scale(Raster r) {
+        int width = r.getWidth();
+        int height = r.getHeight();
+        short result[] = new short[width*height*nColorChannels];
+
+        int pos = 0;
+        if (isTTypeIntegral) {
+            int sample;
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        sample = r.getSample(row, col, chan);
+                        result[pos++] =
+                            (short) (sample * channelMulipliers[chan] + 0.5f);
+                    }
+                }
+            }
+        } else {
+            float sample;
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        sample = r.getSampleFloat(row, col, chan);
+                        result[pos++] = (short) ((sample - channelMinValues[chan])
+                            * channelMulipliers[chan] + 0.5f);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Unscales the whole data array and puts obtained values to the raster
+     * @param data - input data
+     * @param wr - destination raster
+     */
+    public void unscale(short[] data, WritableRaster wr) {
+        int width = wr.getWidth();
+        int height = wr.getHeight();
+
+        int pos = 0;
+        if (isTTypeIntegral) {
+            int sample;
+            for (int row=wr.getMinX(); row<width; row++) {
+                for (int col=wr.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                         sample = (int) ((data[pos++] & 0xFFFF) *
+                                invChannelMulipliers[chan] + 0.5f);
+                         wr.setSample(row, col, chan, sample);
+                    }
+                }
+            }
+        } else {
+            float sample;
+            for (int row=wr.getMinX(); row<width; row++) {
+                for (int col=wr.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                         sample = (data[pos++] & 0xFFFF) *
+                            invChannelMulipliers[chan] + channelMinValues[chan];
+                         wr.setSample(row, col, chan, sample);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Scales one pixel and puts obtained values to the chanData
+     * @param pixelData - input pixel
+     * @param chanData - output buffer
+     * @param chanDataOffset - output buffer offset
+     */
+    public void scale(float[] pixelData, short[] chanData, int chanDataOffset) {
+        for (int chan = 0; chan < nColorChannels; chan++) {
+            chanData[chanDataOffset + chan] =
+                    (short) ((pixelData[chan] - channelMinValues[chan]) *
+                        channelMulipliers[chan] + 0.5f);
+        }
+    }
+
+    /**
+     * Unscales one pixel and puts obtained values to the pixelData
+     * @param pixelData - output pixel
+     * @param chanData - input buffer
+     * @param chanDataOffset - input buffer offset
+     */
+    public void unscale(float[] pixelData, short[] chanData, int chanDataOffset) {
+        for (int chan = 0; chan < nColorChannels; chan++) {
+            pixelData[chan] = (chanData[chanDataOffset + chan] & 0xFFFF)
+                * invChannelMulipliers[chan] + channelMinValues[chan];
+        }
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java b/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java
new file mode 100644
index 0000000..2f7e519
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java
@@ -0,0 +1,82 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ICC_Profile;
+
+/**
+ * Includes utility methods for reading ICC profile data.
+ * Created to provide public access to ICC_Profile methods
+ * for classes outside of java.awt.color
+ */
+public class ICC_ProfileHelper {
+    /**
+     * Utility method.
+     * Gets integer value from the byte array
+     * @param byteArray - byte array
+     * @param idx - byte offset
+     * @return integer value
+     */
+    public static int getIntFromByteArray(byte[] byteArray, int idx) {
+        return (byteArray[idx] & 0xFF)|
+               ((byteArray[idx+1] & 0xFF) << 8) |
+               ((byteArray[idx+2] & 0xFF) << 16)|
+               ((byteArray[idx+3] & 0xFF) << 24);
+    }
+
+    /**
+     * Utility method.
+     * Gets big endian integer value from the byte array
+     * @param byteArray - byte array
+     * @param idx - byte offset
+     * @return integer value
+     */
+    public static int getBigEndianFromByteArray(byte[] byteArray, int idx) {
+        return ((byteArray[idx] & 0xFF) << 24)   |
+               ((byteArray[idx+1] & 0xFF) << 16) |
+               ((byteArray[idx+2] & 0xFF) << 8)  |
+               ( byteArray[idx+3] & 0xFF);
+    }
+
+    /**
+     * Utility method.
+     * Gets short value from the byte array
+     * @param byteArray - byte array
+     * @param idx - byte offset
+     * @return short value
+     */
+    public static short getShortFromByteArray(byte[] byteArray, int idx) {
+        return (short) ((byteArray[idx] & 0xFF) |
+                       ((byteArray[idx+1] & 0xFF) << 8));
+    }
+
+    /**
+     * Used in ICC_Transform class to check the rendering intent of the profile
+     * @param profile - ICC profile
+     * @return rendering intent
+     */
+    public static int getRenderingIntent(ICC_Profile profile) {
+        return getIntFromByteArray(
+                profile.getData(ICC_Profile.icSigHead), // pf header
+                ICC_Profile.icHdrRenderingIntent
+            );
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java b/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java
new file mode 100644
index 0000000..27646c4
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java
@@ -0,0 +1,156 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ICC_Profile;
+
+import org.apache.harmony.awt.gl.color.NativeCMM;
+
+/**
+ * This class encapsulates native ICC transform object, is responsible for its
+ * creation, destruction and passing its handle to the native CMM.
+ */
+public class ICC_Transform {
+    private long transformHandle;
+    private int numInputChannels;
+    private int numOutputChannels;
+    private ICC_Profile src;
+    private ICC_Profile dst;
+
+
+    /**
+     * @return Returns the number of input channels.
+     */
+    public int getNumInputChannels() {
+        return numInputChannels;
+    }
+
+    /**
+     * @return Returns the number of output channels.
+     */
+    public int getNumOutputChannels() {
+        return numOutputChannels;
+    }
+
+    /**
+     * @return Returns the dst.
+     */
+    public ICC_Profile getDst() {
+        return dst;
+    }
+
+    /**
+     * @return Returns the src.
+     */
+    public ICC_Profile getSrc() {
+        return src;
+    }
+
+    /**
+     * Constructs a multiprofile ICC transform
+     * @param profiles - list of ICC profiles
+     * @param renderIntents - only hints for CMM
+     */
+    public ICC_Transform(ICC_Profile[] profiles, int[] renderIntents) {
+        int numProfiles = profiles.length;
+
+        long[] profileHandles = new long[numProfiles];
+        for (int i=0; i<numProfiles; i++) {
+            profileHandles[i] = NativeCMM.getHandle(profiles[i]);
+        }
+
+        transformHandle = NativeCMM.cmmCreateMultiprofileTransform(
+                profileHandles,
+                renderIntents);
+
+        src = profiles[0];
+        dst = profiles[numProfiles-1];
+        numInputChannels = src.getNumComponents();
+        numOutputChannels = dst.getNumComponents();
+    }
+
+    /**
+     * This constructor is able to set intents by default
+     * @param profiles - list of ICC profiles
+     */
+    public ICC_Transform(ICC_Profile[] profiles) {
+        int numProfiles = profiles.length;
+        int[] renderingIntents = new int[numProfiles];
+
+        // Default is perceptual
+        int currRenderingIntent = ICC_Profile.icPerceptual;
+
+        // render as colorimetric for output device
+        if (profiles[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) {
+            currRenderingIntent = ICC_Profile.icRelativeColorimetric;
+        }
+
+        // get the transforms from each profile
+        for (int i = 0; i < numProfiles; i++) {
+            // first or last profile cannot be abstract
+            // if profile is abstract, the only possible way is
+            // use AToB0Tag (perceptual), see ICC spec
+            if (i != 0 &&
+               i != numProfiles - 1 &&
+               profiles[i].getProfileClass() == ICC_Profile.CLASS_ABSTRACT
+            ) {
+                currRenderingIntent = ICC_Profile.icPerceptual;
+            }
+
+            renderingIntents[i] = currRenderingIntent;
+            // use current rendering intent
+            // to select LUT from the next profile (chaining)
+            currRenderingIntent =
+                ICC_ProfileHelper.getRenderingIntent(profiles[i]);
+        }
+
+        // Get the profile handles and go ahead
+        long[] profileHandles = new long[numProfiles];
+        for (int i=0; i<numProfiles; i++) {
+            profileHandles[i] = NativeCMM.getHandle(profiles[i]);
+        }
+
+        transformHandle = NativeCMM.cmmCreateMultiprofileTransform(
+                profileHandles,
+                renderingIntents);
+
+        src = profiles[0];
+        dst = profiles[numProfiles-1];
+        numInputChannels = src.getNumComponents();
+        numOutputChannels = dst.getNumComponents();
+    }
+
+    @Override
+    protected void finalize() {
+        if (transformHandle != 0) {
+            NativeCMM.cmmDeleteTransform(transformHandle);
+        }
+    }
+
+    /**
+     * Invokes native color conversion
+     * @param src - source image format
+     * @param dst - destination image format
+     */
+    public void translateColors(NativeImageFormat src, NativeImageFormat dst) {
+        NativeCMM.cmmTranslateColors(transformHandle, src, dst);
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java b/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java
new file mode 100644
index 0000000..5ea6d25
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java
@@ -0,0 +1,148 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 02.11.2004
+ *
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ColorSpace;
+
+public class LUTColorConverter {
+
+    private static byte from8lRGBtosRGB_LUT[];
+
+    private static byte from16lRGBtosRGB_LUT[];
+
+    private static byte fromsRGBto8lRGB_LUT[];
+
+    private static short fromsRGBto16lRGB_LUT[];
+
+    private static byte fromsRGBto8sRGB_LUTs[][];
+
+    public static ColorSpace LINEAR_RGB_CS;
+
+    public static ColorSpace LINEAR_GRAY_CS;
+
+    public static ColorSpace sRGB_CS;
+
+    public LUTColorConverter() {
+    }
+
+    /*
+     * This class prepared and returned lookup tables for conversion color 
+     * values from Linear RGB Color Space to sRGB and vice versa.
+     * Conversion is producing according to sRGB Color Space definition.
+     * "A Standard Default Color Space for the Internet - sRGB",
+     *  Michael Stokes (Hewlett-Packard), Matthew Anderson (Microsoft), 
+     * Srinivasan Chandrasekar (Microsoft), Ricardo Motta (Hewlett-Packard) 
+     * Version 1.10, November 5, 1996 
+     * This document is available: http://www.w3.org/Graphics/Color/sRGB
+     */
+    public static byte[] getFrom8lRGBtosRGB_LUT() {
+        if (from8lRGBtosRGB_LUT == null) {
+            from8lRGBtosRGB_LUT = new byte[256];
+            float v;
+            for (int i = 0; i < 256; i++) {
+                v = (float)i / 255;
+                v = (v <= 0.04045f) ? v / 12.92f :
+                    (float) Math.pow((v + 0.055) / 1.055, 2.4);
+                from8lRGBtosRGB_LUT[i] = (byte) Math.round(v * 255.0f);
+            }
+        }
+        return from8lRGBtosRGB_LUT;
+    }
+
+    public static byte[] getFrom16lRGBtosRGB_LUT() {
+        if (from16lRGBtosRGB_LUT == null) {
+            from16lRGBtosRGB_LUT = new byte[65536];
+            float v;
+            for (int i = 0; i < 65536; i++) {
+                v = (float) i / 65535;
+                v = (v <= 0.04045f) ? v / 12.92f :
+                    (float) Math.pow((v + 0.055) / 1.055, 2.4);
+                from16lRGBtosRGB_LUT[i] = (byte) Math.round(v * 255.0f);
+            }
+        }
+        return from16lRGBtosRGB_LUT;
+    }
+
+    public static byte[] getFromsRGBto8lRGB_LUT() {
+        if (fromsRGBto8lRGB_LUT == null) {
+            fromsRGBto8lRGB_LUT = new byte[256];
+            float v;
+            for (int i = 0; i < 256; i++) {
+                v = (float) i / 255;
+                v = (v <= 0.0031308f) ? v * 12.92f :
+                    ((float) Math.pow(v, 1.0 / 2.4)) * 1.055f - 0.055f;
+                fromsRGBto8lRGB_LUT[i] = (byte) Math.round(v * 255.0f);
+            }
+        }
+        return fromsRGBto8lRGB_LUT;
+    }
+
+    public static short[] getFromsRGBto16lRGB_LUT() {
+        if (fromsRGBto16lRGB_LUT == null) {
+            fromsRGBto16lRGB_LUT = new short[256];
+            float v;
+            for (int i = 0; i < 256; i++) {
+                v = (float) i / 255;
+                v = (v <= 0.0031308f) ? v * 12.92f :
+                    ((float) Math.pow(v, 1.0 / 2.4)) * 1.055f - 0.055f;
+                fromsRGBto16lRGB_LUT[i] = (short) Math.round(v * 65535.0f);
+            }
+        }
+        return fromsRGBto16lRGB_LUT;
+    }
+
+    public static byte[] getsRGBLUT(int bits) {
+        if (bits < 1) return null;
+        int idx = bits -1;
+        if(fromsRGBto8sRGB_LUTs == null) fromsRGBto8sRGB_LUTs = new byte[16][];
+
+        if(fromsRGBto8sRGB_LUTs[idx] == null){
+            fromsRGBto8sRGB_LUTs[idx] = createLUT(bits);
+        }
+        return fromsRGBto8sRGB_LUTs[idx];
+    }
+
+    private static byte[] createLUT(int bits) {
+        int lutSize = (1 << bits);
+        byte lut[] = new byte[lutSize];
+        for (int i = 0; i < lutSize; i++) {
+            lut[i] = (byte) (255.0f / (lutSize - 1) + 0.5f);
+        }
+        return lut;
+    }
+
+    public static boolean is_LINEAR_RGB_CS(ColorSpace cs) {
+        return (cs == LINEAR_RGB_CS);
+    }
+
+    public static boolean is_LINEAR_GRAY_CS(ColorSpace cs) {
+        return (cs == LINEAR_GRAY_CS);
+    }
+
+    public static boolean is_sRGB_CS(ColorSpace cs) {
+        return (cs == sRGB_CS);
+    }
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/color/NativeCMM.java b/awt/org/apache/harmony/awt/gl/color/NativeCMM.java
new file mode 100644
index 0000000..7f8c7e6
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/NativeCMM.java
@@ -0,0 +1,92 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ICC_Profile;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+
+/**
+ * This class is a wrapper for the native CMM library
+ */
+public class NativeCMM {
+
+    /**
+     * Storage for profile handles, since they are private
+     * in ICC_Profile, but we need access to them.
+     */
+    private static HashMap<ICC_Profile, Long> profileHandles = new HashMap<ICC_Profile, Long>();
+
+    private static boolean isCMMLoaded;
+
+    public static void addHandle(ICC_Profile key, long handle) {
+        profileHandles.put(key, new Long(handle));
+    }
+
+    public static void removeHandle(ICC_Profile key) {
+        profileHandles.remove(key);
+    }
+
+    public static long getHandle(ICC_Profile key) {
+        return profileHandles.get(key).longValue();
+    }
+
+    /* ICC profile management */
+    public static native long cmmOpenProfile(byte[] data);
+    public static native void cmmCloseProfile(long profileID);
+    public static native int cmmGetProfileSize(long profileID);
+    public static native void cmmGetProfile(long profileID, byte[] data);
+    public static native int cmmGetProfileElementSize(long profileID, int signature);
+    public static native void cmmGetProfileElement(long profileID, int signature,
+                                           byte[] data);
+    public static native void cmmSetProfileElement(long profileID, int tagSignature,
+                                           byte[] data);
+
+
+    /* ICC transforms */
+    public static native long cmmCreateMultiprofileTransform(
+            long[] profileHandles,
+            int[] renderingIntents
+        );
+    public static native void cmmDeleteTransform(long transformHandle);
+    public static native void cmmTranslateColors(long transformHandle,
+            NativeImageFormat src,
+            NativeImageFormat dest);
+
+    static void loadCMM() {
+        if (!isCMMLoaded) {
+            AccessController.doPrivileged(
+                  new PrivilegedAction<Void>() {
+                    public Void run() {
+                        System.loadLibrary("lcmm"); //$NON-NLS-1$
+                        return null;
+                    }
+            } );
+            isCMMLoaded = true;
+        }
+    }
+
+    /* load native CMM library */
+    static {
+        loadCMM();
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java b/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java
new file mode 100644
index 0000000..9594047
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java
@@ -0,0 +1,642 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * This class converts java color/sample models to the LCMS pixel formats.
+ * It also encapsulates all the information about the image format, which native CMM
+ * needs to have in order to read/write data.
+ *
+ * At present planar formats (multiple bands) are not supported
+ * and they are handled as a common (custom) case.
+ * Samples other than 1 - 7 bytes and multiple of 8 bits are
+ * also handled as custom (and won't be supported in the nearest future).
+ */
+class NativeImageFormat {
+    //////////////////////////////////////////////
+    //  LCMS Pixel types
+    private static final int PT_ANY = 0;    // Don't check colorspace
+    // 1 & 2 are reserved
+    private static final int PT_GRAY     = 3;
+    private static final int PT_RGB      = 4;
+    // Skipping other since we don't use them here
+    ///////////////////////////////////////////////
+
+    // Conversion of predefined BufferedImage formats to LCMS formats
+    private static final int INT_RGB_LCMS_FMT =
+        colorspaceSh(PT_RGB)|
+        extraSh(1)|
+        channelsSh(3)|
+        bytesSh(1)|
+        doswapSh(1)|
+        swapfirstSh(1);
+
+    private static final int INT_ARGB_LCMS_FMT = INT_RGB_LCMS_FMT;
+
+    private static final int INT_BGR_LCMS_FMT =
+        colorspaceSh(PT_RGB)|
+        extraSh(1)|
+        channelsSh(3)|
+        bytesSh(1);
+
+    private static final int THREE_BYTE_BGR_LCMS_FMT =
+        colorspaceSh(PT_RGB)|
+        channelsSh(3)|
+        bytesSh(1)|
+        doswapSh(1);
+
+    private static final int FOUR_BYTE_ABGR_LCMS_FMT =
+        colorspaceSh(PT_RGB)|
+        extraSh(1)|
+        channelsSh(3)|
+        bytesSh(1)|
+        doswapSh(1);
+
+    private static final int BYTE_GRAY_LCMS_FMT =
+        colorspaceSh(PT_GRAY)|
+        channelsSh(1)|
+        bytesSh(1);
+
+    private static final int USHORT_GRAY_LCMS_FMT =
+        colorspaceSh(PT_GRAY)|
+        channelsSh(1)|
+        bytesSh(2);
+
+    // LCMS format packed into 32 bit value. For description
+    // of this format refer to LCMS documentation.
+    private int cmmFormat = 0;
+
+    // Dimensions
+    private int rows = 0;
+    private int cols = 0;
+
+    //  Scanline may contain some padding in the end
+    private int scanlineStride = -1;
+
+    private Object imageData;
+    // It's possible to have offset from the beginning of the array
+    private int dataOffset;
+
+    // Has the image alpha channel? If has - here its band band offset goes
+    private int alphaOffset = -1;
+
+    // initializes proper field IDs
+    private static native void initIDs();
+
+    static {
+        NativeCMM.loadCMM();
+        initIDs();
+    }
+
+    ////////////////////////////////////
+    // LCMS image format encoders
+    ////////////////////////////////////
+    private static int colorspaceSh(int s) {
+        return (s << 16);
+    }
+
+    private static int swapfirstSh(int s) {
+        return (s << 14);
+    }
+
+    private static int flavorSh(int s) {
+        return (s << 13);
+    }
+
+    private static int planarSh(int s) {
+        return (s << 12);
+    }
+
+    private static int endianSh(int s) {
+        return (s << 11);
+    }
+
+    private static int doswapSh(int s) {
+        return (s << 10);
+    }
+
+    private static int extraSh(int s) {
+        return (s << 7);
+    }
+
+    private static int channelsSh(int s) {
+        return (s << 3);
+    }
+
+    private static int bytesSh(int s) {
+        return s;
+    }
+    ////////////////////////////////////
+    // End of LCMS image format encoders
+    ////////////////////////////////////
+
+    // Accessors
+    Object getChannelData() {
+        return imageData;
+    }
+
+    int getNumCols() {
+        return cols;
+    }
+
+    int getNumRows() {
+        return rows;
+    }
+
+    // Constructors
+    public NativeImageFormat() {
+    }
+
+    /**
+     * Simple image layout for common case with
+     * not optimized workflow.
+     *
+     * For hifi colorspaces with 5+ color channels imgData
+     * should be <code>byte</code> array.
+     *
+     * For common colorspaces with up to 4 color channels it
+     * should be <code>short</code> array.
+     *
+     * Alpha channel is handled by caller, not by CMS.
+     *
+     * Color channels are in their natural order (not BGR but RGB).
+     *
+     * @param imgData - array of <code>byte</code> or <code>short</code>
+     * @param nChannels - number of channels
+     * @param nRows - number of scanlines in the image
+     * @param nCols - number of pixels in one row of the image
+     */
+    public NativeImageFormat(Object imgData, int nChannels, int nRows, int nCols) {
+        if (imgData instanceof short[]) {
+            cmmFormat |= bytesSh(2);
+        }
+        else if (imgData instanceof byte[]) {
+            cmmFormat |= bytesSh(1);
+        }
+        else
+            // awt.47=First argument should be byte or short array
+            throw new IllegalArgumentException(Messages.getString("awt.47")); //$NON-NLS-1$
+
+        cmmFormat |= channelsSh(nChannels);
+
+        rows = nRows;
+        cols = nCols;
+
+        imageData = imgData;
+
+        dataOffset = 0;
+    }
+
+    /**
+     * Deduces image format from the buffered image type
+     * or color and sample models.
+     * @param bi - image
+     * @return image format object
+     */
+    public static NativeImageFormat createNativeImageFormat(BufferedImage bi) {
+        NativeImageFormat fmt = new NativeImageFormat();
+
+        switch (bi.getType()) {
+            case BufferedImage.TYPE_INT_RGB: {
+                fmt.cmmFormat = INT_RGB_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE: {
+                fmt.cmmFormat = INT_ARGB_LCMS_FMT;
+                fmt.alphaOffset = 3;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_BGR: {
+                fmt.cmmFormat = INT_BGR_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                fmt.cmmFormat = THREE_BYTE_BGR_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR: {
+                fmt.cmmFormat = FOUR_BYTE_ABGR_LCMS_FMT;
+                fmt.alphaOffset = 0;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                fmt.cmmFormat = BYTE_GRAY_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: {
+                fmt.cmmFormat = USHORT_GRAY_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_BINARY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_INDEXED: {
+                // A bunch of unsupported formats
+                return null;
+            }
+
+            default:
+                break; // Try to look at sample model and color model
+        }
+
+
+        if (fmt.cmmFormat == 0) {
+            ColorModel cm = bi.getColorModel();
+            SampleModel sm = bi.getSampleModel();
+
+            if (sm instanceof ComponentSampleModel) {
+                ComponentSampleModel csm = (ComponentSampleModel) sm;
+                fmt.cmmFormat = getFormatFromComponentModel(csm, cm.hasAlpha());
+                fmt.scanlineStride = calculateScanlineStrideCSM(csm, bi.getRaster());
+            } else if (sm instanceof SinglePixelPackedSampleModel) {
+                SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+                fmt.cmmFormat = getFormatFromSPPSampleModel(sppsm, cm.hasAlpha());
+                fmt.scanlineStride = calculateScanlineStrideSPPSM(sppsm, bi.getRaster());
+            }
+
+            if (cm.hasAlpha())
+                fmt.alphaOffset = calculateAlphaOffset(sm, bi.getRaster());
+        }
+
+        if (fmt.cmmFormat == 0)
+            return null;
+
+        if (!fmt.setImageData(bi.getRaster().getDataBuffer())) {
+            return null;
+        }
+
+        fmt.rows = bi.getHeight();
+        fmt.cols = bi.getWidth();
+
+        fmt.dataOffset = bi.getRaster().getDataBuffer().getOffset();
+
+        return fmt;
+    }
+
+    /**
+     * Deduces image format from the raster sample model.
+     * @param r - raster
+     * @return image format object
+     */
+    public static NativeImageFormat createNativeImageFormat(Raster r) {
+        NativeImageFormat fmt = new NativeImageFormat();
+        SampleModel sm = r.getSampleModel();
+
+        // Assume that there's no alpha
+        if (sm instanceof ComponentSampleModel) {
+            ComponentSampleModel csm = (ComponentSampleModel) sm;
+            fmt.cmmFormat = getFormatFromComponentModel(csm, false);
+            fmt.scanlineStride = calculateScanlineStrideCSM(csm, r);
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+            fmt.cmmFormat = getFormatFromSPPSampleModel(sppsm, false);
+            fmt.scanlineStride = calculateScanlineStrideSPPSM(sppsm, r);
+        }
+
+        if (fmt.cmmFormat == 0)
+            return null;
+
+        fmt.cols = r.getWidth();
+        fmt.rows = r.getHeight();
+        fmt.dataOffset = r.getDataBuffer().getOffset();
+
+        if (!fmt.setImageData(r.getDataBuffer()))
+            return null;
+
+        return fmt;
+    }
+
+    /**
+     * Obtains LCMS format from the component sample model
+     * @param sm - sample model
+     * @param hasAlpha - true if there's an alpha channel
+     * @return LCMS format
+     */
+    private static int getFormatFromComponentModel(ComponentSampleModel sm, boolean hasAlpha) {
+        // Multiple data arrays (banks) not supported
+        int bankIndex = sm.getBankIndices()[0];
+        for (int i=1; i < sm.getNumBands(); i++) {
+            if (sm.getBankIndices()[i] != bankIndex) {
+                return 0;
+            }
+        }
+
+        int channels = hasAlpha ? sm.getNumBands()-1 : sm.getNumBands();
+        int extra = hasAlpha ? 1 : 0;
+        int bytes = 1;
+        switch (sm.getDataType()) {
+            case DataBuffer.TYPE_BYTE:
+                bytes = 1; break;
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT:
+                bytes = 2; break;
+            case DataBuffer.TYPE_INT:
+                bytes = 4; break;
+            case DataBuffer.TYPE_DOUBLE:
+                bytes = 0; break;
+            default:
+                return 0; // Unsupported data type
+        }
+
+        int doSwap = 0;
+        int swapFirst = 0;
+        boolean knownFormat = false;
+
+        int i;
+
+        // "RGBA"
+        for (i=0; i < sm.getNumBands(); i++) {
+            if (sm.getBandOffsets()[i] != i) break;
+        }
+        if (i == sm.getNumBands()) { // Ok, it is it
+            doSwap = 0;
+            swapFirst = 0;
+            knownFormat = true;
+        }
+
+        // "ARGB"
+        if (!knownFormat) {
+            for (i=0; i < sm.getNumBands()-1; i++) {
+                if (sm.getBandOffsets()[i] != i+1) break;
+            }
+            if (sm.getBandOffsets()[i] == 0) i++;
+            if (i == sm.getNumBands()) { // Ok, it is it
+                doSwap = 0;
+                swapFirst = 1;
+                knownFormat = true;
+            }
+        }
+
+        // "BGRA"
+        if (!knownFormat) {
+            for (i=0; i < sm.getNumBands()-1; i++) {
+                if (sm.getBandOffsets()[i] != sm.getNumBands() - 2 - i) break;
+            }
+            if (sm.getBandOffsets()[i] == sm.getNumBands()-1) i++;
+            if (i == sm.getNumBands()) { // Ok, it is it
+                doSwap = 1;
+                swapFirst = 1;
+                knownFormat = true;
+            }
+        }
+
+        // "ABGR"
+        if (!knownFormat) {
+            for (i=0; i < sm.getNumBands(); i++) {
+                if (sm.getBandOffsets()[i] != sm.getNumBands() - 1 - i) break;
+            }
+            if (i == sm.getNumBands()) { // Ok, it is it
+                doSwap = 1;
+                swapFirst = 0;
+                knownFormat = true;
+            }
+        }
+
+        // XXX - Planar formats are not supported yet
+        if (!knownFormat)
+            return 0;
+
+        return
+            channelsSh(channels) |
+            bytesSh(bytes) |
+            extraSh(extra) |
+            doswapSh(doSwap) |
+            swapfirstSh(swapFirst);
+    }
+
+    /**
+     * Obtains LCMS format from the single pixel packed sample model
+     * @param sm - sample model
+     * @param hasAlpha - true if there's an alpha channel
+     * @return LCMS format
+     */
+    private static int getFormatFromSPPSampleModel(SinglePixelPackedSampleModel sm,
+            boolean hasAlpha) {
+        // Can we extract bytes?
+        int mask = sm.getBitMasks()[0] >>> sm.getBitOffsets()[0];
+        if (!(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF))
+            return 0;
+
+        // All masks are same?
+        for (int i = 1; i < sm.getNumBands(); i++) {
+            if ((sm.getBitMasks()[i] >>> sm.getBitOffsets()[i]) != mask)
+                return 0;
+        }
+
+        int pixelSize = 0;
+        // Check if data type is supported
+        if (sm.getDataType() == DataBuffer.TYPE_USHORT)
+            pixelSize = 2;
+        else if (sm.getDataType() == DataBuffer.TYPE_INT)
+            pixelSize = 4;
+        else
+            return 0;
+
+
+        int bytes = 0;
+        switch (mask) {
+            case 0xFF:
+                bytes = 1;
+                break;
+            case 0xFFFF:
+                bytes = 2;
+                break;
+            case 0xFFFFFFFF:
+                bytes = 4;
+                break;
+            default: return 0;
+        }
+
+
+        int channels = hasAlpha ? sm.getNumBands()-1 : sm.getNumBands();
+        int extra = hasAlpha ? 1 : 0;
+        extra +=  pixelSize/bytes - sm.getNumBands(); // Unused bytes?
+
+        // Form an ArrayList containing offset for each band
+        ArrayList<Integer> offsetsLst = new ArrayList<Integer>();
+        for (int k=0; k < sm.getNumBands(); k++) {
+            offsetsLst.add(new Integer(sm.getBitOffsets()[k]/(bytes*8)));
+        }
+
+        // Add offsets for unused space
+        for (int i=0; i<pixelSize/bytes; i++) {
+            if (offsetsLst.indexOf(new Integer(i)) < 0)
+                offsetsLst.add(new Integer(i));
+        }
+
+        int offsets[] = new int[pixelSize/bytes];
+        for (int i=0; i<offsetsLst.size(); i++) {
+            offsets[i] = offsetsLst.get(i).intValue();
+        }
+
+        int doSwap = 0;
+        int swapFirst = 0;
+        boolean knownFormat = false;
+
+        int i;
+
+        // "RGBA"
+        for (i=0; i < pixelSize; i++) {
+            if (offsets[i] != i) break;
+        }
+        if (i == pixelSize) { // Ok, it is it
+            doSwap = 0;
+            swapFirst = 0;
+            knownFormat = true;
+        }
+
+        // "ARGB"
+        if (!knownFormat) {
+            for (i=0; i < pixelSize-1; i++) {
+                if (offsets[i] != i+1) break;
+            }
+            if (offsets[i] == 0) i++;
+            if (i == pixelSize) { // Ok, it is it
+                doSwap = 0;
+                swapFirst = 1;
+                knownFormat = true;
+            }
+        }
+
+        // "BGRA"
+        if (!knownFormat) {
+            for (i=0; i < pixelSize-1; i++) {
+                if (offsets[i] != pixelSize - 2 - i) break;
+            }
+            if (offsets[i] == pixelSize-1) i++;
+            if (i == pixelSize) { // Ok, it is it
+                doSwap = 1;
+                swapFirst = 1;
+                knownFormat = true;
+            }
+        }
+
+        // "ABGR"
+        if (!knownFormat) {
+            for (i=0; i < pixelSize; i++) {
+                if (offsets[i] != pixelSize - 1 - i) break;
+            }
+            if (i == pixelSize) { // Ok, it is it
+                doSwap = 1;
+                swapFirst = 0;
+                knownFormat = true;
+            }
+        }
+
+        // XXX - Planar formats are not supported yet
+        if (!knownFormat)
+            return 0;
+
+        return
+            channelsSh(channels) |
+            bytesSh(bytes) |
+            extraSh(extra) |
+            doswapSh(doSwap) |
+            swapfirstSh(swapFirst);
+    }
+
+    /**
+     * Obtains data array from the DataBuffer object
+     * @param db - data buffer
+     * @return - true if successful
+     */
+    private boolean setImageData(DataBuffer db) {
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            imageData = dbAccess.getData(db);
+        } catch (IllegalArgumentException e) {
+            return false; // Unknown data buffer type
+        }
+
+        return true;
+    }
+
+    /**
+     * Calculates scanline stride in bytes
+     * @param csm - component sample model
+     * @param r - raster
+     * @return scanline stride in bytes
+     */
+    private static int calculateScanlineStrideCSM(ComponentSampleModel csm, Raster r) {
+        if (csm.getScanlineStride() != csm.getPixelStride()*csm.getWidth()) {
+            int dataTypeSize = DataBuffer.getDataTypeSize(r.getDataBuffer().getDataType()) / 8;
+            return csm.getScanlineStride()*dataTypeSize;
+        }
+        return -1;
+    }
+
+    /**
+     * Calculates scanline stride in bytes
+     * @param sppsm - sample model
+     * @param r - raster
+     * @return scanline stride in bytes
+     */
+    private static int calculateScanlineStrideSPPSM(SinglePixelPackedSampleModel sppsm, Raster r) {
+        if (sppsm.getScanlineStride() != sppsm.getWidth()) {
+            int dataTypeSize = DataBuffer.getDataTypeSize(r.getDataBuffer().getDataType()) / 8;
+            return sppsm.getScanlineStride()*dataTypeSize;
+        }
+        return -1;
+    }
+
+    /**
+     * Calculates byte offset of the alpha channel from the beginning of the pixel data
+     * @param sm - sample model
+     * @param r - raster
+     * @return byte offset of the alpha channel
+     */
+    private static int calculateAlphaOffset(SampleModel sm, Raster r) {
+        if (sm instanceof ComponentSampleModel) {
+            ComponentSampleModel csm = (ComponentSampleModel) sm;
+            int dataTypeSize =
+                DataBuffer.getDataTypeSize(r.getDataBuffer().getDataType()) / 8;
+            return
+                csm.getBandOffsets()[csm.getBandOffsets().length - 1] * dataTypeSize;
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+            return sppsm.getBitOffsets()[sppsm.getBitOffsets().length - 1] / 8;
+        } else {
+            return -1; // No offset, don't copy alpha
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidFont.java b/awt/org/apache/harmony/awt/gl/font/AndroidFont.java
new file mode 100644
index 0000000..e8ad1bb
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidFont.java
@@ -0,0 +1,254 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.File;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import org.apache.harmony.awt.gl.font.FontManager;
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.Glyph;
+import org.apache.harmony.awt.gl.font.LineMetricsImpl;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * Linux platform font peer implementation based on Xft and FreeType libraries.
+ */
+public class AndroidFont extends FontPeerImpl {
+
+    // Pairs of [begin, end],[..].. unicode ranges values 
+    private int[] fontUnicodeRanges;
+    
+    // table with loaded cached Glyphs
+    private Hashtable glyphs = new Hashtable();
+    
+    // X11 display value
+    private long display = 0;
+
+    // X11 screen value
+    private int screen = 0;
+    
+    public AndroidFont(String fontName, int fontStyle, int fontSize) {
+        /*
+         * Workaround : to initialize awt platform-dependent fields and libraries.
+         */
+        Toolkit.getDefaultToolkit();
+        this.name = fontName;
+        this.size = fontSize;
+        this.style = fontStyle;
+       
+        initAndroidFont();
+    }
+
+    /**
+     * Initializes some native dependent font information, e.g. number of glyphs, 
+     * font metrics, italic angle etc. 
+     */
+    public void initAndroidFont(){
+        this.nlm = new AndroidLineMetrics(this, null, " "); //$NON-NLS-1$
+        this.ascent = nlm.getLogicalAscent();
+        this.descent = nlm.getLogicalDescent();
+        this.height = nlm.getHeight();
+        this.leading = nlm.getLogicalLeading();
+        this.maxAdvance = nlm.getLogicalMaxCharWidth();
+
+        if (this.fontType == FontManager.FONT_TYPE_T1){
+            this.defaultChar = 1;
+        } else {
+            this.defaultChar = 0;
+        }
+
+        this.maxCharBounds = new Rectangle2D.Float(0, -nlm.getAscent(), nlm.getMaxCharWidth(), this.height);
+    }
+
+
+    public boolean canDisplay(char chr) {
+        // TODO: to improve performance there is a sence to implement get
+        // unicode ranges to check if char can be displayed without
+        // native calls in isGlyphExists() method
+
+        return isGlyphExists(chr);
+    }
+
+    public LineMetrics getLineMetrics(String str, FontRenderContext frc, AffineTransform at) {
+
+        // Initialize baseline offsets
+        nlm.getBaselineOffsets();
+        
+        LineMetricsImpl lm = (LineMetricsImpl)(this.nlm.clone());
+        lm.setNumChars(str.length());
+
+        if ((at != null) && (!at.isIdentity())){
+            lm.scale((float)at.getScaleX(), (float)at.getScaleY());
+        }
+
+        return lm;
+    }
+
+    public String getPSName() {
+        return psName;
+    }
+
+    public String getFamily(Locale l) {
+        // TODO: implement localized family
+        if (fontType == FontManager.FONT_TYPE_TT){
+            return this.getFamily();
+        }
+
+        return this.fontFamilyName;
+    }
+
+    public String getFontName(Locale l) {
+        if ((pFont == 0) || (this.fontType == FontManager.FONT_TYPE_T1)){
+            return this.name;
+        }
+
+        return this.getFontName();
+    }
+
+
+    public int getMissingGlyphCode() {
+        return getDefaultGlyph().getGlyphCode();
+    }
+
+    public Glyph getGlyph(char index) {
+        Glyph result = null;
+
+        Object key = new Integer(index);
+        if (glyphs.containsKey(key)) {
+            result = (Glyph) glyphs.get(key);
+        } else {
+            if (this.addGlyph(index)) {
+                result = (Glyph) glyphs.get(key);
+            } else {
+                result = this.getDefaultGlyph();
+            }
+        }
+
+        return result;
+    }
+
+    public Glyph getDefaultGlyph() {
+    	throw new RuntimeException("DefaultGlyphs not implemented!");
+    }
+
+    /**
+     * Disposes native font handle. If this font peer was created from InputStream 
+     * temporary created font resource file is deleted.
+     */
+    public void dispose(){
+        String tempDirName;
+        if (pFont != 0){
+            pFont = 0;
+
+            if (isCreatedFromStream()) {
+                File fontFile = new File(getTempFontFileName());
+                tempDirName = fontFile.getParent();
+                fontFile.delete();
+            }
+        }
+    }
+
+    /**
+     * Add glyph to cached Glyph objects in this LinuxFont object.
+     * 
+     * @param uChar the specified character
+     * @return true if glyph of the specified character exists in this
+     * LinuxFont or this character is escape sequence character.
+     */
+    public boolean addGlyph(char uChar) {
+    	throw new RuntimeException("Not implemented!");    	
+    }
+
+   /**
+    * Adds range of existing glyphs to this LinuxFont object
+    * 
+    * @param uFirst the lowest range's bound, inclusive 
+    * @param uLast the highest range's bound, exclusive
+    */
+    public void addGlyphs(char uFirst, char uLast) {
+    	
+        char index = uFirst;
+        if (uLast < uFirst) {
+            // awt.09=min range bound value is grater than max range bound
+            throw new IllegalArgumentException(Messages.getString("awt.09")); //$NON-NLS-1$
+        }
+        while (index < uLast) {
+            addGlyph(index);
+            index++;
+        }
+        
+    }
+
+    /**
+     * Returns true if specified character has corresopnding glyph, false otherwise.  
+     * 
+     * @param uIndex specified char
+     */
+    public boolean isGlyphExists(char uIndex) {
+    	throw new RuntimeException("DefaultGlyphs not implemented!");
+    }
+
+    /**
+     *  Returns an array of unicode ranges that are supported by this LinuxFont. 
+     */
+    public int[] getUnicodeRanges() {
+        int[] ranges = new int[fontUnicodeRanges.length];
+        System.arraycopy(fontUnicodeRanges, 0, ranges, 0,
+                fontUnicodeRanges.length);
+
+        return ranges;
+    }
+
+    /**
+     * Return Font object if it was successfully embedded in System
+     */
+    public static Font embedFont(String absolutePath){
+    	throw new RuntimeException("embedFont not implemented!");
+    }
+
+    public String getFontName(){
+        if ((pFont != 0) && (faceName == null)){
+            if (this.fontType == FontManager.FONT_TYPE_T1){
+                faceName = getFamily();
+            }
+        }
+        return faceName;
+    }
+
+    public String getFamily() {
+        return fontFamilyName;
+    }
+    
+    /**
+     * Returns initiated FontExtraMetrics instance of this WindowsFont.
+     */
+    public FontExtraMetrics getExtraMetrics(){
+    	throw new RuntimeException("Not implemented!");
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java b/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java
new file mode 100644
index 0000000..063a256
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java
@@ -0,0 +1,277 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.peer.FontPeer;
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.font.FontManager;
+import org.apache.harmony.awt.gl.font.FontProperty;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+import android.util.Log;
+
+public class AndroidFontManager extends FontManager {
+
+    // set of all available faces supported by a system
+    String faces[];
+
+    // weight names according to xlfd structure
+    public static final String[] LINUX_WEIGHT_NAMES = {
+            "black", "bold", "demibold", "medium", "light" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    };
+
+    // slant names according to xlfd structure
+    public static final String[] LINUX_SLANT_NAMES = {
+            "i", "o", "r" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    };
+
+    /** Singleton AndroidFontManager instance */
+    public static final AndroidFontManager inst = new AndroidFontManager();
+
+    private AndroidFontManager() {
+        super();
+        faces = new String[] {/*"PLAIN",*/ "NORMAL", "BOLD", "ITALIC", "BOLDITALIC"};
+        initFontProperties();
+    }
+
+    public void initLCIDTable(){
+    	throw new RuntimeException("Not implemented!");
+    }
+
+    /**
+     * Returns temporary File object to store data from InputStream.
+     * This File object saved to `~/.fonts/' folder that is included in the 
+     * list of folders searched for font files, and this is where user-specific 
+     * font files should be installed.
+     */
+    public File getTempFontFile()throws IOException{
+        File fontFile = File.createTempFile("jFont", ".ttf", new File(System.getProperty("user.home") +"/.fonts")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+        fontFile.deleteOnExit();
+
+        return fontFile;
+    }
+
+    /**
+     * Initializes fProperties array field for the current system configuration font
+     * property file.
+     * 
+     * RuntimeException is thrown if font property contains incorrect format of 
+     * xlfd string.
+     * 
+     * @return true is success, false if font property doesn't exist or doesn't
+     * contain roperties. 
+     */
+    public boolean initFontProperties(){
+        File fpFile = getFontPropertyFile();
+        if (fpFile == null){
+            return false;
+        }
+
+        Properties props = getProperties(fpFile);
+        if (props == null){
+            return false;
+        }
+
+        for (int i=0; i < LOGICAL_FONT_NAMES.length; i++){
+            String lName = LOGICAL_FONT_NAMES[i];
+            for (int j=0; j < STYLE_NAMES.length; j++){
+                String styleName = STYLE_NAMES[j];
+                Vector propsVector = new Vector();
+
+                // Number of entries for a logical font
+                int numComp = 0;
+                // Is more entries for this style and logical font name left
+                boolean moreEntries = true;
+                String value = null;
+
+                while(moreEntries){
+                    // Component Font Mappings property name
+                    String property = FONT_MAPPING_KEYS[0].replaceAll("LogicalFontName", lName).replaceAll("StyleName", styleName).replaceAll("ComponentIndex", String.valueOf(numComp)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    value = props.getProperty(property);
+
+                    // If the StyleName is omitted, it's assumed to be plain
+                    if ((j == 0) && (value == null)){
+                        property = FONT_MAPPING_KEYS[1].replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp)); //$NON-NLS-1$ //$NON-NLS-2$
+                        value = props.getProperty(property);
+                    }
+
+                    if (value != null){
+                        String[] fields = parseXLFD(value);
+
+                        if (fields == null){
+                            // awt.08=xfld parse string error: {0}
+                            throw new RuntimeException(Messages.getString("awt.08", value)); //$NON-NLS-1$
+                        }
+                        
+                        String fontName = fields[1];
+                        String weight = fields[2];
+                        String italic = fields[3];
+
+                        int style = getBoldStyle(weight) | getItalicStyle(italic);
+                        // Component Font Character Encodings property value
+                        String encoding = props.getProperty(FONT_CHARACTER_ENCODING.replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp))); //$NON-NLS-1$ //$NON-NLS-2$
+
+                        // Exclusion Ranges property value
+                        String exclString = props.getProperty(EXCLUSION_RANGES.replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp))); //$NON-NLS-1$ //$NON-NLS-2$
+                        int[] exclRange = parseIntervals(exclString);
+
+                        FontProperty fp = new AndroidFontProperty(lName, styleName, null, fontName, value, style, exclRange, encoding);
+
+                        propsVector.add(fp);
+                        numComp++;
+                    } else {
+                        moreEntries = false;
+                    }
+                }
+                fProperties.put(LOGICAL_FONT_NAMES[i] + "." + j, propsVector); //$NON-NLS-1$
+            }
+        }
+
+        return true;
+
+    }
+
+    /**
+     * Returns style according to the xlfd weight string.
+     * If weight string is incorrect returned value is Font.PLAIN
+     * 
+     * @param str weight name String
+     */
+    private int getBoldStyle(String str){
+        for (int i = 0; i < LINUX_WEIGHT_NAMES.length;i++){
+            if (str.equalsIgnoreCase(LINUX_WEIGHT_NAMES[i])){
+                return (i < 3) ? Font.BOLD : Font.PLAIN;
+            }
+        }
+        return Font.PLAIN;
+    }
+    
+    /**
+     * Returns style according to the xlfd slant string.
+     * If slant string is incorrect returned value is Font.PLAIN
+     * 
+     * @param str slant name String
+     */
+    private int getItalicStyle(String str){
+        for (int i = 0; i < LINUX_SLANT_NAMES.length;i++){
+            if (str.equalsIgnoreCase(LINUX_SLANT_NAMES[i])){
+                return (i < 2) ? Font.ITALIC : Font.PLAIN;
+            }
+        }
+        return Font.PLAIN;
+    }
+
+    /**
+     * Parse xlfd string and returns array of Strings with separate xlfd 
+     * elements.<p>
+     * 
+     * xlfd format:
+     *      -Foundry-Family-Weight-Slant-Width-Style-PixelSize-PointSize-ResX-ResY-Spacing-AvgWidth-Registry-Encoding
+     * @param xlfd String parameter in xlfd format
+     */
+    public static String[] parseXLFD(String xlfd){
+        int fieldsCount = 14;
+        String fieldsDelim = "-"; //$NON-NLS-1$
+        String[] res = new String[fieldsCount];
+        if (!xlfd.startsWith(fieldsDelim)){
+            return null;
+        }
+
+        xlfd = xlfd.substring(1);
+        int i=0;
+        int pos;
+        for (i=0; i < fieldsCount-1; i++){
+            pos = xlfd.indexOf(fieldsDelim);
+            if (pos != -1){
+                res[i] = xlfd.substring(0, pos);
+                xlfd = xlfd.substring(pos + 1);
+            } else {
+                return null;
+            }
+        }
+        pos = xlfd.indexOf(fieldsDelim);
+
+        // check if no fields left
+        if(pos != -1){
+            return null;
+        }
+        res[fieldsCount-1] = xlfd;
+
+        return res;
+    }
+
+    public int getFaceIndex(String faceName){
+    	
+        for (int i = 0; i < faces.length; i++) {
+            if(faces[i].equals(faceName)){
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public String[] getAllFamilies(){
+        if (allFamilies == null){
+        	allFamilies = new String[]{"sans-serif", "serif", "monospace"};
+        }
+        return allFamilies;
+    }
+
+    public Font[] getAllFonts(){
+        Font[] fonts = new Font[faces.length];
+        for (int i =0; i < fonts.length;i++){
+            fonts[i] = new Font(faces[i], Font.PLAIN, 1);
+        }
+        return fonts;
+    }
+
+    public FontPeer createPhysicalFontPeer(String name, int style, int size) {
+        AndroidFont peer;
+        int familyIndex = getFamilyIndex(name);
+        if (familyIndex != -1){
+            // !! we use family names from the list with cached families because 
+            // they are differ from the family names in xlfd structure, in xlfd 
+            // family names mostly in lower case.
+            peer = new AndroidFont(getFamily(familyIndex), style, size);
+            peer.setFamily(getFamily(familyIndex));
+            return peer;
+        }
+        int faceIndex = getFaceIndex(name); 
+        if (faceIndex != -1){
+
+            peer = new AndroidFont(name, style, size);
+            return peer;
+        }
+        
+        return null;
+    }
+
+    public FontPeer createDefaultFont(int style, int size) {
+    	Log.i("DEFAULT FONT", Integer.toString(style));
+        return new AndroidFont(DEFAULT_NAME, style, size);
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java b/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java
new file mode 100644
index 0000000..0cfdc43
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java
@@ -0,0 +1,81 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ *
+ */
+package org.apache.harmony.awt.gl.font;
+
+/**
+ * Android FontProperty implementation, applicable for Linux formats of 
+ * font property files. 
+ */
+public class AndroidFontProperty extends FontProperty {
+    
+    /** xlfd string that is applicable for Linux font.properties */ 
+    String xlfd;
+
+    /** logical name of the font corresponding to this FontProperty */ 
+    String logicalName;
+    
+    /** style name of the font corresponding to this FontProperty */
+    String styleName;
+
+    public AndroidFontProperty(String _logicalName, String _styleName, String _fileName, String _name, String _xlfd, int _style, int[] exclusionRange, String _encoding){
+        this.logicalName = _logicalName;
+        this.styleName = _styleName;
+        this.name = _name;
+        this.encoding = _encoding;
+        this.exclRange = exclusionRange;
+        this.fileName = _fileName;
+        this.xlfd = _xlfd;
+        this.style = _style;
+    }
+    
+    /**
+     * Returns logical name of the font corresponding to this FontProperty. 
+     */
+    public String getLogicalName(){
+        return logicalName;
+    }
+    
+    /**
+     * Returns style name of the font corresponding to this FontProperty. 
+     */
+    public String getStyleName(){
+        return styleName;
+    }
+    
+    /**
+     * Returns xlfd string of this FontProperty. 
+     */
+    public String getXLFD(){
+        return xlfd;
+    }
+
+    public String toString(){
+        return new String(this.getClass().getName() +
+                "[name=" + name + //$NON-NLS-1$
+                ",fileName="+ fileName + //$NON-NLS-1$
+                ",Charset=" + encoding + //$NON-NLS-1$
+                ",exclRange=" + exclRange + //$NON-NLS-1$
+                ",xlfd=" + xlfd + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java b/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java
new file mode 100644
index 0000000..4ce5aed
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java
@@ -0,0 +1,219 @@
+package org.apache.harmony.awt.gl.font;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.Font;
+import java.awt.Shape;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import android.util.Log;
+import android.graphics.Path;
+
+public class AndroidGlyphVector extends GlyphVector {
+
+    // array of chars defined in constructor
+    public char[] charVector;
+
+    // array of Glyph objects, that describe information about glyphs
+    public Glyph[] vector;
+
+    // array of default positions of glyphs in GlyphVector
+    // without applying GlyphVector's transform
+    float[] defaultPositions;
+
+    // array of logical positions of glyphs in GlyphVector
+
+    float[] logicalPositions;
+
+    // array of visual (real) positions of glyphs in GlyphVector
+    public float[] visualPositions;
+
+    // FontRenderContext for this vector.
+    protected FontRenderContext vectorFRC;
+
+    // layout flags mask
+    protected int layoutFlags = 0;
+
+    // array of cached glyph outlines 
+    protected Shape[] gvShapes;
+
+    FontPeerImpl peer;
+
+    // font corresponding to the GlyphVector 
+    Font font;
+
+    // ascent of the font
+    float ascent;
+
+    // height of the font
+    float height;
+    
+    // leading of the font
+    float leading;
+    
+    // descent of the font
+    float descent;
+
+    // transform of the GlyphVector
+    AffineTransform transform;
+
+    @SuppressWarnings("deprecation")
+    public AndroidGlyphVector(char[] chars, FontRenderContext frc, Font fnt,
+            int flags) {
+        int len = chars.length;
+        this.font = fnt;
+        LineMetricsImpl lmImpl = (LineMetricsImpl)fnt.getLineMetrics(String.valueOf(chars), frc);     	
+        this.ascent = lmImpl.getAscent();
+        this.height = lmImpl.getHeight();
+        this.leading = lmImpl.getLeading();
+        this.descent = lmImpl.getDescent();
+        this.charVector = chars;
+        this.vectorFRC = frc;
+    }
+
+    public AndroidGlyphVector(char[] chars, FontRenderContext frc, Font fnt) {
+        this(chars, frc, fnt, 0);
+    }
+
+    public AndroidGlyphVector(String str, FontRenderContext frc, Font fnt) {
+        this(str.toCharArray(), frc, fnt, 0);
+    }
+
+    public AndroidGlyphVector(String str, FontRenderContext frc, Font fnt, int flags) {
+        this(str.toCharArray(), frc, fnt, flags);
+    }
+
+	@Override
+	public boolean equals(GlyphVector glyphVector) {
+		return false;
+	}
+
+	public char[] getGlyphs() {
+		return this.charVector;
+	}
+	
+	@Override
+	public Font getFont() {
+		return this.font;
+	}
+
+	@Override
+	public FontRenderContext getFontRenderContext() {
+		return this.vectorFRC;
+	}
+
+	@Override
+	public int getGlyphCode(int glyphIndex) {
+		return charVector[glyphIndex];
+	}
+
+	@Override
+	public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
+			int[] codeReturn) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Shape getGlyphLogicalBounds(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public GlyphMetrics getGlyphMetrics(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	public Path getAndroidGlyphOutline(int glyphIndex) {
+		AndroidGraphics2D g = AndroidGraphics2D.getInstance();
+        Path path = new Path();
+        char tmp[] = new char[1];
+        tmp[0] = charVector[glyphIndex];
+        ((AndroidGraphics2D)g).getAndroidPaint().getTextPath(new String(tmp), 0, 1, 0, 0, path);
+        return path;
+	}
+	
+	@Override
+	public Shape getGlyphOutline(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Point2D getGlyphPosition(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
+			float[] positionReturn) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public AffineTransform getGlyphTransform(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Shape getGlyphVisualBounds(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Rectangle2D getLogicalBounds() {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public int getNumGlyphs() {
+		return charVector.length;
+	}
+
+	@Override
+	public Shape getOutline(float x, float y) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Shape getOutline() {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	public Path getAndroidOutline() {
+		AndroidGraphics2D g = AndroidGraphics2D.getInstance();
+        Path path = new Path();
+        ((AndroidGraphics2D)g).getAndroidPaint().getTextPath(new String(charVector), 0, charVector.length, 0, 0, path);
+        return path;
+	}
+
+	@Override
+	public Rectangle2D getVisualBounds() {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public void performDefaultLayout() {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public void setGlyphPosition(int glyphIndex, Point2D newPos) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public void setGlyphTransform(int glyphIndex, AffineTransform trans) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java b/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java
new file mode 100644
index 0000000..f37be6d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java
@@ -0,0 +1,120 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.FontRenderContext;
+import org.apache.harmony.awt.gl.font.LineMetricsImpl;
+
+
+/**
+ *
+ * Linux implementation of LineMetrics class
+ */
+public class AndroidLineMetrics extends LineMetricsImpl {
+    
+    /**
+     * Constructor
+     */
+    public AndroidLineMetrics(    AndroidFont fnt,
+                                FontRenderContext frc,
+                                String str){
+        numChars = str.length();
+        baseLineIndex = 0;
+
+        ascent = fnt.ascent;    // Ascent of the font
+        descent = -fnt.descent;  // Descent of the font
+        leading = fnt.leading;  // External leading
+
+        height = ascent + descent + leading;    // Height of the font ( == (ascent + descent + leading))
+        underlineThickness = 0.0f;
+        underlineOffset = 0.0f;
+        strikethroughThickness = 0.0f;
+        strikethroughOffset = 0.0f;
+        maxCharWidth = 0.0f;
+
+        //    TODO: Find out pixel metrics
+        /*
+         * positive metrics rounded to the smallest int that is bigger than value
+         * negative metrics rounded to the smallest int that is lesser than value
+         * thicknesses rounded to int ((int)round(value + 0.5))
+         *
+         */
+
+        lAscent = (int)Math.ceil(fnt.ascent);//   // Ascent of the font
+        lDescent = -(int)Math.ceil(fnt.descent);// Descent of the font
+        lLeading = (int)Math.ceil(leading);  // External leading
+
+        lHeight = lAscent + lDescent + lLeading;    // Height of the font ( == (ascent + descent + leading))
+
+        lUnderlineThickness = Math.round(underlineThickness);//(int)metrics[11];
+
+        if (underlineOffset >= 0){
+            lUnderlineOffset = (int)Math.ceil(underlineOffset);
+        } else {
+            lUnderlineOffset = (int)Math.floor(underlineOffset);
+        }
+
+        lStrikethroughThickness = Math.round(strikethroughThickness); //(int)metrics[13];
+
+        if (strikethroughOffset >= 0){
+            lStrikethroughOffset = (int)Math.ceil(strikethroughOffset);
+        } else {
+            lStrikethroughOffset = (int)Math.floor(strikethroughOffset);
+        }
+
+        lMaxCharWidth = (int)Math.ceil(maxCharWidth); //(int)metrics[15];
+        units_per_EM = 0;
+
+    }
+
+    public float[] getBaselineOffsets() {
+        // TODO: implement baseline offsets for TrueType fonts
+        if (baselineOffsets == null){
+            float[] baselineData = null;
+
+            // Temporary workaround:
+            // Commented out native data initialization, since it can 
+            // cause failures with opening files in multithreaded applications.
+            //
+            // TODO: support work with truetype data in multithreaded
+            // applications.
+
+            // If font TrueType data is taken from BASE table
+//            if ((this.font.getFontHandle() != 0) && (font.getFontType() == FontManager.FONT_TYPE_TT)){
+//                baselineData = LinuxNativeFont.getBaselineOffsetsNative(font.getFontHandle(), font.getSize(), ascent, descent, units_per_EM);
+//            }
+//
+                baseLineIndex = 0;
+                baselineOffsets = new float[]{0, (-ascent+descent)/2, -ascent};
+        }
+
+        return baselineOffsets;
+    }
+
+    public int getBaselineIndex() {
+        if (baselineOffsets == null){
+            // get offsets and set correct index
+            getBaselineOffsets();
+        }
+        return baseLineIndex;
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java b/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java
new file mode 100644
index 0000000..c0fb390
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java
@@ -0,0 +1,134 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.LineMetrics;
+import java.awt.font.GraphicAttribute;
+import java.awt.*;
+
+/**
+ * Date: May 14, 2005
+ * Time: 7:44:13 PM
+ *
+ * This class incapsulates text metrics specific for the text layout or
+ * for the separate text segment. Text segment is a text run with the constant direction
+ * and attributes like font, decorations, etc. BasicMetrics is also used to store
+ * calculated text metrics like advance, ascent or descent. this class is very similar to
+ * LineMetrics, but provides some additional info, constructors and is more transparent.
+ */
+public class BasicMetrics {
+    int baseLineIndex;
+
+    float ascent;   // Ascent of the font
+    float descent;  // Descent of the font
+    float leading;  // External leading
+    float advance;
+
+    float italicAngle;
+    float superScriptOffset;
+
+    float underlineOffset;
+    float underlineThickness;
+
+    float strikethroughOffset;
+    float strikethroughThickness;
+
+    /**
+     * Constructs BasicMetrics from LineMetrics and font
+     * @param lm
+     * @param font
+     */
+    BasicMetrics(LineMetrics lm, Font font) {
+        ascent = lm.getAscent();
+        descent = lm.getDescent();
+        leading = lm.getLeading();
+
+        underlineOffset = lm.getUnderlineOffset();
+        underlineThickness = lm.getUnderlineThickness();
+
+        strikethroughOffset = lm.getStrikethroughOffset();
+        strikethroughThickness = lm.getStrikethroughThickness();
+
+        baseLineIndex = lm.getBaselineIndex();
+
+        italicAngle = font.getItalicAngle();
+        superScriptOffset = (float) font.getTransform().getTranslateY();
+    }
+
+    /**
+     * Constructs BasicMetrics from GraphicAttribute.
+     * It gets ascent and descent from the graphic attribute and
+     * computes reasonable defaults for other metrics.
+     * @param ga - graphic attribute
+     */
+    BasicMetrics(GraphicAttribute ga) {
+        ascent = ga.getAscent();
+        descent = ga.getDescent();
+        leading = 2;
+
+        baseLineIndex = ga.getAlignment();
+
+        italicAngle = 0;
+        superScriptOffset = 0;
+
+        underlineOffset = Math.max(descent/2, 1);
+
+        // Just suggested, should be cap_stem_width or something like that
+        underlineThickness = Math.max(ascent/13, 1);
+
+        strikethroughOffset = -ascent/2; // Something like middle of the line
+        strikethroughThickness = underlineThickness;
+    }
+
+    /**
+     * Copies metrics from the TextMetricsCalculator object.
+     * @param tmc - TextMetricsCalculator object
+     */
+    BasicMetrics(TextMetricsCalculator tmc) {
+        ascent = tmc.ascent;
+        descent = tmc.descent;
+        leading = tmc.leading;
+        advance = tmc.advance;
+        baseLineIndex = tmc.baselineIndex;
+    }
+
+    public float getAscent() {
+        return ascent;
+    }
+
+    public float getDescent() {
+        return descent;
+    }
+
+    public float getLeading() {
+        return leading;
+    }
+
+    public float getAdvance() {
+        return advance;
+    }
+
+    public int getBaseLineIndex() {
+        return baseLineIndex;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/CaretManager.java b/awt/org/apache/harmony/awt/gl/font/CaretManager.java
new file mode 100644
index 0000000..b18bdd5
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/CaretManager.java
@@ -0,0 +1,530 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Jun 14, 2005
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.TextHitInfo;
+import java.awt.font.TextLayout;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.*;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class provides functionality for creating caret and highlight shapes
+ * (bidirectional text is also supported, but, unfortunately, not tested yet).
+ */
+public class CaretManager {
+    private TextRunBreaker breaker;
+
+    public CaretManager(TextRunBreaker breaker) {
+        this.breaker = breaker;
+    }
+
+    /**
+     * Checks if TextHitInfo is not out of the text range and throws the
+     * IllegalArgumentException if it is.
+     * @param info - text hit info
+     */
+    private void checkHit(TextHitInfo info) {
+        int idx = info.getInsertionIndex();
+
+        if (idx < 0 || idx > breaker.getCharCount()) {
+            // awt.42=TextHitInfo out of range
+            throw new IllegalArgumentException(Messages.getString("awt.42")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Calculates and returns visual position from the text hit info.
+     * @param hitInfo - text hit info
+     * @return visual index
+     */
+    private int getVisualFromHitInfo(TextHitInfo hitInfo) {
+        final int idx = hitInfo.getCharIndex();
+
+        if (idx >= 0 && idx < breaker.getCharCount()) {
+            int visual = breaker.getVisualFromLogical(idx);
+            // We take next character for (LTR char + TRAILING info) and (RTL + LEADING)
+            if (hitInfo.isLeadingEdge() ^ ((breaker.getLevel(idx) & 0x1) == 0x0)) {
+                visual++;
+            }
+            return visual;
+        } else if (idx < 0) {
+            return breaker.isLTR() ? 0: breaker.getCharCount();
+        } else {
+            return breaker.isLTR() ? breaker.getCharCount() : 0;
+        }
+    }
+
+    /**
+     * Calculates text hit info from the visual position
+     * @param visual - visual position
+     * @return text hit info
+     */
+    private TextHitInfo getHitInfoFromVisual(int visual) {
+        final boolean first = visual == 0;
+
+        if (!(first || visual == breaker.getCharCount())) {
+            int logical = breaker.getLogicalFromVisual(visual);
+            return (breaker.getLevel(logical) & 0x1) == 0x0 ?
+                    TextHitInfo.leading(logical) : // LTR
+                    TextHitInfo.trailing(logical); // RTL
+        } else if (first) {
+            return breaker.isLTR() ?
+                    TextHitInfo.trailing(-1) :
+                    TextHitInfo.leading(breaker.getCharCount());
+        } else { // Last
+            return breaker.isLTR() ?
+                    TextHitInfo.leading(breaker.getCharCount()) :
+                    TextHitInfo.trailing(-1);
+        }
+    }
+
+    /**
+     * Creates caret info. Required for the getCaretInfo
+     * methods of the TextLayout
+     * @param hitInfo - specifies caret position
+     * @return caret info, see TextLayout.getCaretInfo documentation
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo) {
+        checkHit(hitInfo);
+        float res[] = new float[2];
+
+        int visual = getVisualFromHitInfo(hitInfo);
+        float advance, angle;
+        TextRunSegment seg;
+
+        if (visual < breaker.getCharCount()) {
+            int logIdx = breaker.getLogicalFromVisual(visual);
+            int segmentIdx = breaker.logical2segment[logIdx];
+            seg = breaker.runSegments.get(segmentIdx);
+            advance = seg.x + seg.getAdvanceDelta(seg.getStart(), logIdx);
+            angle = seg.metrics.italicAngle;
+
+        } else { // Last character
+            int logIdx = breaker.getLogicalFromVisual(visual-1);
+            int segmentIdx = breaker.logical2segment[logIdx];
+            seg = breaker.runSegments.get(segmentIdx);
+            advance = seg.x + seg.getAdvanceDelta(seg.getStart(), logIdx+1);
+        }
+
+        angle = seg.metrics.italicAngle;
+
+        res[0] = advance;
+        res[1] = angle;
+
+        return res;
+    }
+
+    /**
+     * Returns the next position to the right from the current caret position
+     * @param hitInfo - current position
+     * @return next position to the right
+     */
+    public TextHitInfo getNextRightHit(TextHitInfo hitInfo) {
+        checkHit(hitInfo);
+        int visual = getVisualFromHitInfo(hitInfo);
+
+        if (visual == breaker.getCharCount()) {
+            return null;
+        }
+
+        TextHitInfo newInfo;
+
+        while(visual <= breaker.getCharCount()) {
+            visual++;
+            newInfo = getHitInfoFromVisual(visual);
+
+            if (newInfo.getCharIndex() >= breaker.logical2segment.length) {
+                return newInfo;
+            }
+
+            if (hitInfo.getCharIndex() >= 0) { // Don't check for leftmost info
+                if (
+                        breaker.logical2segment[newInfo.getCharIndex()] !=
+                        breaker.logical2segment[hitInfo.getCharIndex()]
+                ) {
+                    return newInfo; // We crossed segment boundary
+                }
+            }
+
+            TextRunSegment seg = breaker.runSegments.get(breaker.logical2segment[newInfo
+                    .getCharIndex()]);
+            if (!seg.charHasZeroAdvance(newInfo.getCharIndex())) {
+                return newInfo;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the next position to the left from the current caret position
+     * @param hitInfo - current position
+     * @return next position to the left
+     */
+    public TextHitInfo getNextLeftHit(TextHitInfo hitInfo) {
+        checkHit(hitInfo);
+        int visual = getVisualFromHitInfo(hitInfo);
+
+        if (visual == 0) {
+            return null;
+        }
+
+        TextHitInfo newInfo;
+
+        while(visual >= 0) {
+            visual--;
+            newInfo = getHitInfoFromVisual(visual);
+
+            if (newInfo.getCharIndex() < 0) {
+                return newInfo;
+            }
+
+            // Don't check for rightmost info
+            if (hitInfo.getCharIndex() < breaker.logical2segment.length) {
+                if (
+                        breaker.logical2segment[newInfo.getCharIndex()] !=
+                        breaker.logical2segment[hitInfo.getCharIndex()]
+                ) {
+                    return newInfo; // We crossed segment boundary
+                }
+            }
+
+            TextRunSegment seg = breaker.runSegments.get(breaker.logical2segment[newInfo
+                    .getCharIndex()]);
+            if (!seg.charHasZeroAdvance(newInfo.getCharIndex())) {
+                return newInfo;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * For each visual caret position there are two hits. For the simple LTR text one is
+     * a trailing of the previous char and another is the leading of the next char. This
+     * method returns the opposite hit for the given hit.
+     * @param hitInfo - given hit
+     * @return opposite hit
+     */
+    public TextHitInfo getVisualOtherHit(TextHitInfo hitInfo) {
+        checkHit(hitInfo);
+
+        int idx = hitInfo.getCharIndex();
+
+        int resIdx;
+        boolean resIsLeading;
+
+        if (idx >= 0 && idx < breaker.getCharCount()) { // Hit info in the middle
+            int visual = breaker.getVisualFromLogical(idx);
+
+            // Char is LTR + LEADING info
+            if (((breaker.getLevel(idx) & 0x1) == 0x0) ^ hitInfo.isLeadingEdge()) {
+                visual++;
+                if (visual == breaker.getCharCount()) {
+                    if (breaker.isLTR()) {
+                        resIdx = breaker.getCharCount();
+                        resIsLeading = true;
+                    } else {
+                        resIdx = -1;
+                        resIsLeading = false;
+                    }
+                } else {
+                    resIdx = breaker.getLogicalFromVisual(visual);
+                    if ((breaker.getLevel(resIdx) & 0x1) == 0x0) {
+                        resIsLeading = true;
+                    } else {
+                        resIsLeading = false;
+                    }
+                }
+            } else {
+                visual--;
+                if (visual == -1) {
+                    if (breaker.isLTR()) {
+                        resIdx = -1;
+                        resIsLeading = false;
+                    } else {
+                        resIdx = breaker.getCharCount();
+                        resIsLeading = true;
+                    }
+                } else {
+                    resIdx = breaker.getLogicalFromVisual(visual);
+                    if ((breaker.getLevel(resIdx) & 0x1) == 0x0) {
+                        resIsLeading = false;
+                    } else {
+                        resIsLeading = true;
+                    }
+                }
+            }
+        } else if (idx < 0) { // before "start"
+            if (breaker.isLTR()) {
+                resIdx = breaker.getLogicalFromVisual(0);
+                resIsLeading = (breaker.getLevel(resIdx) & 0x1) == 0x0; // LTR char?
+            } else {
+                resIdx = breaker.getLogicalFromVisual(breaker.getCharCount() - 1);
+                resIsLeading = (breaker.getLevel(resIdx) & 0x1) != 0x0; // RTL char?
+            }
+        } else { // idx == breaker.getCharCount()
+            if (breaker.isLTR()) {
+                resIdx = breaker.getLogicalFromVisual(breaker.getCharCount() - 1);
+                resIsLeading = (breaker.getLevel(resIdx) & 0x1) != 0x0; // LTR char?
+            } else {
+                resIdx = breaker.getLogicalFromVisual(0);
+                resIsLeading = (breaker.getLevel(resIdx) & 0x1) == 0x0; // RTL char?
+            }
+        }
+
+        return resIsLeading ? TextHitInfo.leading(resIdx) : TextHitInfo.trailing(resIdx);
+    }
+
+    public Line2D getCaretShape(TextHitInfo hitInfo, TextLayout layout) {
+        return getCaretShape(hitInfo, layout, true, false, null);
+    }
+
+    /**
+     * Creates a caret shape.
+     * @param hitInfo - hit where to place a caret
+     * @param layout - text layout
+     * @param useItalic - unused for now, was used to create
+     * slanted carets for italic text
+     * @param useBounds - true if the cared should fit into the provided bounds
+     * @param bounds - bounds for the caret
+     * @return caret shape
+     */
+    public Line2D getCaretShape(
+            TextHitInfo hitInfo, TextLayout layout,
+            boolean useItalic, boolean useBounds, Rectangle2D bounds
+    ) {
+        checkHit(hitInfo);
+
+        float x1, x2, y1, y2;
+
+        int charIdx = hitInfo.getCharIndex();
+
+        if (charIdx >= 0 && charIdx < breaker.getCharCount()) {
+            TextRunSegment segment = breaker.runSegments.get(breaker.logical2segment[charIdx]);
+            y1 = segment.metrics.descent;
+            y2 = - segment.metrics.ascent - segment.metrics.leading;
+
+            x1 = x2 = segment.getCharPosition(charIdx) + (hitInfo.isLeadingEdge() ?
+                    0 : segment.getCharAdvance(charIdx));
+            // Decided that straight cursor looks better even for italic fonts,
+            // especially combined with highlighting
+            /*
+            // Not graphics, need to check italic angle and baseline
+            if (layout.getBaseline() >= 0) {
+                if (segment.metrics.italicAngle != 0 && useItalic) {
+                    x1 -= segment.metrics.italicAngle * segment.metrics.descent;
+                    x2 += segment.metrics.italicAngle *
+                        (segment.metrics.ascent + segment.metrics.leading);
+
+                    float baselineOffset =
+                        layout.getBaselineOffsets()[layout.getBaseline()];
+                    y1 += baselineOffset;
+                    y2 += baselineOffset;
+                }
+            }
+            */
+        } else {
+            y1 = layout.getDescent();
+            y2 = - layout.getAscent() - layout.getLeading();
+            x1 = x2 = ((breaker.getBaseLevel() & 0x1) == 0 ^ charIdx < 0) ?
+                    layout.getAdvance() : 0;
+        }
+
+        if (useBounds) {
+            y1 = (float) bounds.getMaxY();
+            y2 = (float) bounds.getMinY();
+
+            if (x2 > bounds.getMaxX()) {
+                x1 = x2 = (float) bounds.getMaxX();
+            }
+            if (x1 < bounds.getMinX()) {
+                x1 = x2 = (float) bounds.getMinX();
+            }
+        }
+
+        return new Line2D.Float(x1, y1, x2, y2);
+    }
+
+    /**
+     * Creates caret shapes for the specified offset. On the boundaries where
+     * the text is changing its direction this method may return two shapes
+     * for the strong and the weak carets, in other cases it would return one.
+     * @param offset - offset in the text.
+     * @param bounds - bounds to fit the carets into
+     * @param policy - caret policy
+     * @param layout - text layout
+     * @return one or two caret shapes
+     */
+    public Shape[] getCaretShapes(
+            int offset, Rectangle2D bounds,
+            TextLayout.CaretPolicy policy, TextLayout layout
+    ) {
+        TextHitInfo hit1 = TextHitInfo.afterOffset(offset);
+        TextHitInfo hit2 = getVisualOtherHit(hit1);
+
+        Shape caret1 = getCaretShape(hit1, layout);
+
+        if (getVisualFromHitInfo(hit1) == getVisualFromHitInfo(hit2)) {
+            return new Shape[] {caret1, null};
+        }
+        Shape caret2 = getCaretShape(hit2, layout);
+
+        TextHitInfo strongHit = policy.getStrongCaret(hit1, hit2, layout);
+        return strongHit.equals(hit1) ?
+                new Shape[] {caret1, caret2} :
+                new Shape[] {caret2, caret1};
+    }
+
+    /**
+     * Connects two carets to produce a highlight shape.
+     * @param caret1 - 1st caret
+     * @param caret2 - 2nd caret
+     * @return highlight shape
+     */
+    GeneralPath connectCarets(Line2D caret1, Line2D caret2) {
+        GeneralPath path = new GeneralPath(GeneralPath.WIND_NON_ZERO);
+        path.moveTo((float) caret1.getX1(), (float) caret1.getY1());
+        path.lineTo((float) caret2.getX1(), (float) caret2.getY1());
+        path.lineTo((float) caret2.getX2(), (float) caret2.getY2());
+        path.lineTo((float) caret1.getX2(), (float) caret1.getY2());
+
+        path.closePath();
+
+        return path;
+    }
+
+    /**
+     * Creates a highlight shape from given two hits. This shape
+     * will always be visually contiguous
+     * @param hit1 - 1st hit
+     * @param hit2 - 2nd hit
+     * @param bounds - bounds to fit the shape into
+     * @param layout - text layout
+     * @return highlight shape
+     */
+    public Shape getVisualHighlightShape(
+            TextHitInfo hit1, TextHitInfo hit2,
+            Rectangle2D bounds, TextLayout layout
+    ) {
+        checkHit(hit1);
+        checkHit(hit2);
+
+        Line2D caret1 = getCaretShape(hit1, layout, false, true, bounds);
+        Line2D caret2 = getCaretShape(hit2, layout, false, true, bounds);
+
+        return connectCarets(caret1, caret2);
+    }
+
+    /**
+     * Suppose that the user visually selected a block of text which has
+     * several different levels (mixed RTL and LTR), so, in the logical
+     * representation of the text this selection may be not contigous.
+     * This methods returns a set of logical ranges for the arbitrary
+     * visual selection represented by two hits.
+     * @param hit1 - 1st hit
+     * @param hit2 - 2nd hit
+     * @return logical ranges for the selection
+     */
+    public int[] getLogicalRangesForVisualSelection(TextHitInfo hit1, TextHitInfo hit2) {
+        checkHit(hit1);
+        checkHit(hit2);
+
+        int visual1 = getVisualFromHitInfo(hit1);
+        int visual2 = getVisualFromHitInfo(hit2);
+
+        if (visual1 > visual2) {
+            int tmp = visual2;
+            visual2 = visual1;
+            visual1 = tmp;
+        }
+
+        // Max level is 255, so we don't need more than 512 entries
+        int results[] = new int[512];
+
+        int prevLogical, logical, runStart, numRuns = 0;
+
+        logical = runStart = prevLogical = breaker.getLogicalFromVisual(visual1);
+
+        // Get all the runs. We use the fact that direction is constant in all runs.
+        for (int i=visual1+1; i<=visual2; i++) {
+            logical = breaker.getLogicalFromVisual(i);
+            int diff = logical-prevLogical;
+
+            // Start of the next run encountered
+            if (diff > 1 || diff < -1) {
+                results[(numRuns)*2] = Math.min(runStart, prevLogical);
+                results[(numRuns)*2 + 1] = Math.max(runStart, prevLogical);
+                numRuns++;
+                runStart = logical;
+            }
+
+            prevLogical = logical;
+        }
+
+        // The last unsaved run
+        results[(numRuns)*2] = Math.min(runStart, logical);
+        results[(numRuns)*2 + 1] = Math.max(runStart, logical);
+        numRuns++;
+
+        int retval[] = new int[numRuns*2];
+        System.arraycopy(results, 0, retval, 0, numRuns*2);
+        return retval;
+    }
+
+    /**
+     * Creates a highlight shape from given two endpoints in the logical
+     * representation. This shape is not always visually contiguous
+     * @param firstEndpoint - 1st logical endpoint
+     * @param secondEndpoint - 2nd logical endpoint
+     * @param bounds - bounds to fit the shape into
+     * @param layout - text layout
+     * @return highlight shape
+     */
+    public Shape getLogicalHighlightShape(
+            int firstEndpoint, int secondEndpoint,
+            Rectangle2D bounds, TextLayout layout
+    ) {
+        GeneralPath res = new GeneralPath();
+
+        for (int i=firstEndpoint; i<=secondEndpoint; i++) {
+            int endRun = breaker.getLevelRunLimit(i, secondEndpoint);
+            TextHitInfo hit1 = TextHitInfo.leading(i);
+            TextHitInfo hit2 = TextHitInfo.trailing(endRun-1);
+
+            Line2D caret1 = getCaretShape(hit1, layout, false, true, bounds);
+            Line2D caret2 = getCaretShape(hit2, layout, false, true, bounds);
+
+            res.append(connectCarets(caret1, caret2), false);
+
+            i = endRun;
+        }
+
+        return res;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java b/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java
new file mode 100644
index 0000000..4040a60
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java
@@ -0,0 +1,954 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * GlyphVector implementation
+ */
+public class CommonGlyphVector extends GlyphVector {
+
+    // array of transforms of glyphs in GlyphVector
+    protected AffineTransform[] glsTransforms;
+
+    // array of chars defined in constructor
+    public char[] charVector;
+
+    // array of Glyph objects, that describe information about glyphs
+    public Glyph[] vector;
+
+    // array of default positions of glyphs in GlyphVector
+    // without applying GlyphVector's transform
+    float[] defaultPositions;
+
+    // array of logical positions of glyphs in GlyphVector
+
+    float[] logicalPositions;
+
+    // array of visual (real) positions of glyphs in GlyphVector
+    public float[] visualPositions;
+
+    // FontRenderContext for this vector.
+    protected FontRenderContext vectorFRC;
+
+    // layout flags mask
+    protected int layoutFlags = 0;
+
+    // array of cached glyph outlines 
+    protected Shape[] gvShapes;
+
+    FontPeerImpl peer;
+
+    // font corresponding to the GlyphVector 
+    Font font;
+
+    // ascent of the font
+    float ascent;
+
+    // height of the font
+    float height;
+    
+    // leading of the font
+    float leading;
+    
+    // descent of the font
+    float descent;
+
+    // transform of the GlyphVector
+    AffineTransform transform;
+
+    /**
+     * Creates new CommonGlyphVector object from the specified parameters.
+     * 
+     * @param chars an array of chars
+     * @param frc FontRenderContext object
+     * @param fnt Font object
+     * @param flags layout flags
+     */
+    @SuppressWarnings("deprecation")
+    public CommonGlyphVector(char[] chars, FontRenderContext frc, Font fnt,
+            int flags) {
+        int len = chars.length;
+
+        this.font = fnt;
+        this.transform = fnt.getTransform();
+        this.peer = (FontPeerImpl) fnt.getPeer();
+
+        gvShapes = new Shape[len];
+
+        // !! As pointed in API documentation for the 
+        // getGlyphPosisitions(int index,int numEntries, float[] positionReturn) 
+        // and getGlyphPosition(int index) methods, if the index is equals to 
+        // the number of glyphs the position after the last glyph must be 
+        // returned, thus there are n+1 positions and last (n+1) position 
+        // points to the end of GlyphVector.
+
+        logicalPositions = new float[(len+1)<<1];
+        visualPositions = new float[(len+1)<<1];
+        defaultPositions = new float[(len+1)<<1];
+
+        glsTransforms = new AffineTransform[len];
+
+        this.charVector = chars;
+        this.vectorFRC = frc;
+        //LineMetricsImpl lmImpl = (LineMetricsImpl)peer.getLineMetrics();
+
+        LineMetricsImpl lmImpl = (LineMetricsImpl)fnt.getLineMetrics(String.valueOf(chars), frc);
+
+        this.ascent = lmImpl.getAscent();
+        this.height = lmImpl.getHeight();
+        this.leading = lmImpl.getLeading();
+        this.descent = lmImpl.getDescent();
+        this.layoutFlags = flags;
+
+        if ((flags & Font.LAYOUT_RIGHT_TO_LEFT) != 0){
+            char vector[] = new char[len];
+            for(int i=0; i < len; i++){
+                vector[i] = chars[len-i-1];
+            }
+            this.vector = peer.getGlyphs(vector);
+
+        } else {
+            this.vector = peer.getGlyphs(chars);
+        }
+
+        this.glsTransforms = new AffineTransform[len];
+
+        setDefaultPositions();
+        performDefaultLayout();
+    }
+
+    /**
+     * Creates new CommonGlyphVector object from the specified parameters. 
+     * Layout flags set to default.
+     * 
+     * @param chars an array of chars
+     * @param frc FontRenderContext object
+     * @param fnt Font object
+     */
+    public CommonGlyphVector(char[] chars, FontRenderContext frc, Font fnt) {
+        this(chars, frc, fnt, 0);
+    }
+
+    /**
+     * Creates new CommonGlyphVector object from the specified parameters. 
+     * Layout flags set to default.
+     * 
+     * @param str specified string
+     * @param frc FontRenderContext object
+     * @param fnt Font object
+     */
+    public CommonGlyphVector(String str, FontRenderContext frc, Font fnt) {
+        this(str.toCharArray(), frc, fnt, 0);
+    }
+
+    /**
+     * Creates new CommonGlyphVector object from the specified parameters.
+     * 
+     * @param str specified string
+     * @param frc FontRenderContext object
+     * @param fnt Font object
+     * @param flags layout flags
+     */
+    public CommonGlyphVector(String str, FontRenderContext frc, Font fnt, int flags) {
+        this(str.toCharArray(), frc, fnt, flags);
+    }
+
+    /**
+     * Set array of logical positions of the glyphs to
+     * default with their default advances and height.
+     */
+    void setDefaultPositions(){
+        int len = getNumGlyphs();
+
+        // First [x,y] is set into [0,0] position
+        // for this reason start index is 1
+        for (int i=1; i <= len; i++ ){
+                int idx = i << 1;
+                float advanceX = vector[i-1].getGlyphPointMetrics().getAdvanceX();
+                float advanceY = vector[i-1].getGlyphPointMetrics().getAdvanceY();
+
+                defaultPositions[idx] = defaultPositions[idx-2] + advanceX;
+                defaultPositions[idx+1] = defaultPositions[idx-1] + advanceY;
+
+        }
+        transform.transform(defaultPositions, 0, logicalPositions, 0, getNumGlyphs()+1);
+
+    }
+
+    /**
+     * Returnes the pixel bounds of this GlyphVector rendered at the 
+     * specified x,y location with the given FontRenderContext.
+     *  
+     * @param frc a FontRenderContext that is used
+     * @param x specified x coordinate value
+     * @param y specified y coordinate value
+     * @return a Rectangle that bounds pixels of this GlyphVector
+     */
+    @Override
+    public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
+
+        double xM, yM, xm, ym;
+
+        double minX = 0;
+        double minY = 0;
+        double maxX = 0;
+        double maxY = 0;
+
+        for (int i = 0; i < this.getNumGlyphs(); i++) {
+            Rectangle glyphBounds = this.getGlyphPixelBounds(i, frc, 0, 0);
+            xm = glyphBounds.getMinX();
+            ym = glyphBounds.getMinY();
+            xM = glyphBounds.getMaxX();
+            yM = glyphBounds.getMaxY();
+
+            if (i == 0) {
+                minX = xm;
+                minY = ym;
+                maxX = xM;
+                maxY = yM;
+            }
+
+            if (minX > xm) {
+                minX = xm;
+            }
+            if (minY > ym) {
+                minY = ym;
+            }
+            if (maxX < xM) {
+                maxX = xM;
+            }
+            if (maxY < yM) {
+                maxY = yM;
+            }
+        }
+        return new Rectangle((int)(minX + x), (int)(minY + y), (int)(maxX - minX), (int)(maxY - minY));
+
+    }
+
+    /**
+     * Returns the visual bounds of this GlyphVector.
+     * The visual bounds is the bounds of the total outline of 
+     * this GlyphVector.
+     * @return a Rectangle2D that id the visual bounds of this GlyphVector
+     */
+    @Override
+    public Rectangle2D getVisualBounds() {
+        float xM, yM, xm, ym;
+        float minX = 0;
+        float minY = 0;
+        float maxX = 0;
+        float maxY = 0;
+        boolean firstIteration = true;
+
+        for (int i = 0; i < this.getNumGlyphs(); i++) {
+            Rectangle2D bounds = this.getGlyphVisualBounds(i).getBounds2D();
+            if (bounds.getWidth() == 0){
+                continue;
+            }
+            xm = (float)bounds.getX();
+            ym = (float)bounds.getY();
+
+            xM = (float)(xm + bounds.getWidth());
+
+            yM = ym + (float) bounds.getHeight();
+
+            if (firstIteration) {
+                minX = xm;
+                minY = ym;
+                maxX = xM;
+                maxY = yM;
+                firstIteration = false;
+            } else {
+                if (minX > xm) {
+                    minX = xm;
+                }
+                if (minY > ym) {
+                    minY = ym;
+                }
+                if (maxX < xM) {
+                    maxX = xM;
+                }
+                if (maxY < yM) {
+                    maxY = yM;
+                }
+
+            }
+        }
+
+        return (this.getNumGlyphs() != 0) ? new Rectangle2D.Float(minX, minY,
+                (maxX - minX), (maxY - minY)) : null;
+    }
+
+    /**
+     * Sets new position to the specified glyph.
+     */
+    @Override
+    public void setGlyphPosition(int glyphIndex, Point2D newPos) {
+        if ((glyphIndex > vector.length) || (glyphIndex < 0)) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        float x = (float)newPos.getX();
+        float y = (float)newPos.getY();
+        int index = glyphIndex << 1;
+
+        if ((x != visualPositions[index]) || (y != visualPositions[index + 1])){
+            visualPositions[index] = x;
+            visualPositions[index+1] = y;
+            layoutFlags = layoutFlags | FLAG_HAS_POSITION_ADJUSTMENTS;
+        }
+
+    }
+
+    /**
+     * Returns the position of the specified glyph relative to the origin of
+     * this GlyphVector
+     * @return a Point2D that the origin of the glyph with specified index
+     */
+    @Override
+    public Point2D getGlyphPosition(int glyphIndex) {
+        if ((glyphIndex > vector.length) || (glyphIndex < 0)) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        int index = glyphIndex << 1;
+        Point2D pos = new Point2D.Float(visualPositions[index], visualPositions[index+1]);
+
+        // For last position we don't have to transform !!
+        if(glyphIndex==vector.length){
+            return pos;
+        }
+
+        AffineTransform at = getGlyphTransform(glyphIndex);
+        if ((at == null) || (at.isIdentity())){
+            return pos;
+        }
+
+        pos.setLocation(pos.getX() + at.getTranslateX(), pos.getY() + at.getTranslateY());
+
+        return pos;
+    }
+
+    /**
+     * Sets new transform to the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     * @param trans AffineTransform of the glyph with specified index
+     */
+    @Override
+    public void setGlyphTransform(int glyphIndex, AffineTransform trans) {
+        if ((glyphIndex >= vector.length) || (glyphIndex < 0)) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        if ((trans == null) || (trans.isIdentity())) {
+            glsTransforms[glyphIndex] = null;
+        } else {
+            glsTransforms[glyphIndex] = new AffineTransform(trans);
+            layoutFlags = layoutFlags | FLAG_HAS_TRANSFORMS;
+        }
+    }
+
+    /**
+     * Returns the affine transform of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     * @return an AffineTransform of the glyph with specified index
+     */
+    @Override
+    public AffineTransform getGlyphTransform(int glyphIndex) {
+        if ((glyphIndex >= this.vector.length) || (glyphIndex < 0)) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        return this.glsTransforms[glyphIndex];
+    }
+
+    /**
+     * Returns the metrics of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public GlyphMetrics getGlyphMetrics(int glyphIndex) {
+
+        if ((glyphIndex < 0) || ((glyphIndex) >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        // TODO: is there a sence in GlyphMetrics
+        // if certain glyph or Font has a transform??
+        return this.vector[glyphIndex].getGlyphMetrics();
+    }
+
+    /**
+     * Returns a justification information for the glyph with specified glyph 
+     * index.
+     * @param glyphIndex index of a glyph which GlyphJustificationInfo is to be 
+     * received   
+     * @return a GlyphJustificationInfo object that contains glyph justification 
+     * properties of the specified glyph
+     */
+    @Override
+    public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) {
+        // TODO : Find out the source of Justification info
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Returns the FontRenderContext parameter of this GlyphVector.
+     */
+    @Override
+    public FontRenderContext getFontRenderContext() {
+        return this.vectorFRC;
+    }
+
+    /**
+     * Returns the visual bounds of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public Shape getGlyphVisualBounds(int glyphIndex) {
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        int idx  = glyphIndex << 1;
+
+        AffineTransform fontTransform = this.transform;
+        double xOffs = fontTransform.getTranslateX();
+        double yOffs = fontTransform.getTranslateY();
+
+        if (vector[glyphIndex].getWidth() == 0){
+            return new Rectangle2D.Float((float)xOffs, (float)yOffs, 0, 0);
+        }
+
+        AffineTransform at = AffineTransform.getTranslateInstance(xOffs, yOffs);
+        AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
+
+        if (transform.isIdentity() && ((glyphTransform == null) || glyphTransform.isIdentity())){
+            Rectangle2D blackBox = vector[glyphIndex].getGlyphMetrics().getBounds2D();
+            at.translate(visualPositions[idx], visualPositions[idx+1]);
+            return(at.createTransformedShape(blackBox));
+        }
+
+        GeneralPath shape = (GeneralPath)this.getGlyphOutline(glyphIndex);
+        shape.transform(at);
+        return shape.getBounds2D();
+    }
+
+    /**
+     * Returnes the pixel bounds of the specified glyph within GlyphVector 
+     * rendered at the specified x,y location.
+     *  
+     * @param glyphIndex index of the glyph
+     * @param frc a FontRenderContext that is used
+     * @param x specified x coordinate value
+     * @param y specified y coordinate value
+     * @return a Rectangle that bounds pixels of the specified glyph
+     */
+    @Override
+    public Rectangle getGlyphPixelBounds(int glyphIndex, FontRenderContext frc,
+            float x, float y) {
+        // TODO : need to be implemented with FontRenderContext
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        int idx  = glyphIndex << 1;
+
+        if (vector[glyphIndex].getWidth() == 0){
+            AffineTransform fontTransform = this.transform;
+            double xOffs = x + visualPositions[idx] + fontTransform.getTranslateX();
+            double yOffs = y + visualPositions[idx+1] + fontTransform.getTranslateY();
+            return new Rectangle((int)xOffs, (int)yOffs, 0, 0);
+        }
+
+        GeneralPath shape = (GeneralPath)this.getGlyphOutline(glyphIndex);
+
+        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
+
+        if (frc != null){
+            at.concatenate(frc.getTransform());
+        }
+
+        shape.transform(at);
+
+        Rectangle bounds = shape.getBounds();
+        return new Rectangle((int)bounds.getX(), (int)bounds.getY(),
+                            (int)bounds.getWidth()-1, (int)bounds.getHeight()-1);
+        }
+
+    /**
+     * Returns a Shape that encloses specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public Shape getGlyphOutline(int glyphIndex) {
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        if (gvShapes[glyphIndex] == null) {
+            gvShapes[glyphIndex] = vector[glyphIndex].getShape();
+        }
+
+        GeneralPath gp = (GeneralPath)((GeneralPath)gvShapes[glyphIndex]).clone();
+
+        /* Applying GlyphVector font transform */
+        AffineTransform at = (AffineTransform)this.transform.clone();
+
+        /* Applying Glyph transform */
+        AffineTransform glyphAT = getGlyphTransform(glyphIndex);
+        if (glyphAT != null){
+            at.preConcatenate(glyphAT);
+        }
+
+        int idx  = glyphIndex << 1;
+
+        gp.transform(at);
+        gp.transform(AffineTransform.getTranslateInstance(visualPositions[idx], visualPositions[idx+1]));
+        return gp;
+    }
+
+
+    /**
+     * Returns a Shape that is the outline representation of this GlyphVector 
+     * rendered at the specified x,y coordinates.
+     * 
+     * @param x specified x coordinate value
+     * @param y specified y coordinate value
+     * @return a Shape object that is the outline of this GlyphVector
+     * at the specified coordinates.
+     */
+    @Override
+    public Shape getOutline(float x, float y) {
+        GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
+        for (int i = 0; i < this.vector.length; i++) {
+            GeneralPath outline = (GeneralPath)getGlyphOutline(i);
+
+            /* Applying translation to actual visual bounds */
+            outline.transform(AffineTransform.getTranslateInstance(x, y));
+            gp.append(outline, false);
+        }
+
+        return gp;
+    }
+
+    /**
+     * Returns a Shape that is the outline representation of this GlyphVector.
+     * 
+     * @return a Shape object that is the outline of this GlyphVector
+     */
+    @Override
+    public Shape getOutline() {
+        return this.getOutline(0, 0);
+    }
+
+    /**
+     * Returns an array of glyphcodes for the specified glyphs.
+     * 
+     * @param beginGlyphIndex the start index
+     * @param numEntries the number of glyph codes to get
+     * @param codeReturn the array that receives glyph codes' values
+     * @return an array that receives glyph codes' values
+     */
+    @Override
+    public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
+            int[] codeReturn) {
+
+        if ((beginGlyphIndex < 0) || ((numEntries + beginGlyphIndex) > this.getNumGlyphs())) {
+            // awt.44=beginGlyphIndex is out of vector's range
+            throw new IndexOutOfBoundsException(Messages.getString("awt.44")); //$NON-NLS-1$
+        }
+
+        if (numEntries < 0) {
+            // awt.45=numEntries is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
+        }
+
+        if (codeReturn == null) {
+            codeReturn = new int[numEntries];
+        }
+
+        for (int i = beginGlyphIndex; i < beginGlyphIndex + numEntries; i++) {
+            codeReturn[i-beginGlyphIndex] = this.vector[i].getGlyphCode();
+        }
+
+        return codeReturn;
+    }
+
+    /**
+     * Returns an array of numEntries character indices for the specified glyphs.
+     * 
+     * @param beginGlyphIndex the start index
+     * @param numEntries the number of glyph codes to get
+     * @param codeReturn the array that receives glyph codes' values
+     * @return an array that receives glyph char indices
+     */
+    @Override
+    public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries,
+            int[] codeReturn) {
+        if ((beginGlyphIndex < 0) || (beginGlyphIndex >= this.getNumGlyphs())) {
+            // awt.44=beginGlyphIndex is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.44")); //$NON-NLS-1$
+        }
+
+        if ((numEntries < 0)
+                || ((numEntries + beginGlyphIndex) > this.getNumGlyphs())) {
+            // awt.45=numEntries is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
+        }
+
+        if (codeReturn == null) {
+            codeReturn = new int[numEntries];
+        }
+
+        for (int i = 0; i < numEntries; i++) {
+            codeReturn[i] = this.getGlyphCharIndex(i + beginGlyphIndex);
+        }
+        return codeReturn;
+    }
+
+    /**
+     * Returns an array of numEntries glyphs positions from beginGlyphIndex
+     * glyph in Glyph Vector.
+     * 
+     * @param beginGlyphIndex the start index
+     * @param numEntries the number of glyph codes to get
+     * @param positionReturn the array that receives glyphs' positions
+     * @return an array of floats that receives glyph char indices
+     */
+    @Override
+    public float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
+            float[] positionReturn) {
+
+        int len = (this.getNumGlyphs()+1) << 1;
+        beginGlyphIndex *= 2;
+        numEntries *= 2;
+
+        if ((beginGlyphIndex < 0) || ((numEntries + beginGlyphIndex) > len)) {
+            // awt.44=beginGlyphIndex is out of vector's range
+            throw new IndexOutOfBoundsException(Messages.getString("awt.44")); //$NON-NLS-1$
+        }
+
+        if (numEntries < 0) {
+            // awt.45=numEntries is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
+        }
+
+        if (positionReturn == null) {
+            positionReturn = new float[numEntries];
+        }
+
+        System.arraycopy(visualPositions, beginGlyphIndex, positionReturn, 0, numEntries);
+
+        return positionReturn;
+    }
+
+    /**
+     * Set numEntries elements of the visualPositions array from beginGlyphIndex
+     * of numEntries glyphs positions from beginGlyphIndex glyph in Glyph Vector.
+     * 
+     * @param beginGlyphIndex the start index
+     * @param numEntries the number of glyph codes to get
+     * @param setPositions the array of positions to set
+     */
+    public void setGlyphPositions(int beginGlyphIndex, int numEntries,
+            float[] setPositions) {
+
+        int len = (this.getNumGlyphs()+1) << 1;
+        beginGlyphIndex *= 2;
+        numEntries *= 2;
+
+        if ((beginGlyphIndex < 0) || ((numEntries + beginGlyphIndex) > len)) {
+            // awt.44=beginGlyphIndex is out of vector's range
+            throw new IndexOutOfBoundsException(Messages.getString("awt.44")); //$NON-NLS-1$
+        }
+
+        if (numEntries < 0) {
+            // awt.45=numEntries is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
+        }
+
+        System.arraycopy(setPositions, 0, visualPositions, beginGlyphIndex, numEntries);
+        layoutFlags = layoutFlags & FLAG_HAS_POSITION_ADJUSTMENTS;
+
+    }
+
+    /**
+     * Set elements of the visualPositions array.
+     * 
+     * @param setPositions the array of positions to set
+     */
+    public void setGlyphPositions(float[] setPositions) {
+
+        int len = (this.getNumGlyphs()+1) << 1;
+        if (len != setPositions.length){
+            // awt.46=length of setPositions array differs from the length of positions array
+            throw new IllegalArgumentException(Messages.getString("awt.46")); //$NON-NLS-1$
+        }
+
+        System.arraycopy(setPositions, 0, visualPositions, 0, len);
+        layoutFlags = layoutFlags & FLAG_HAS_POSITION_ADJUSTMENTS;
+
+    }
+
+
+    /**
+     * Returns glyph code of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public int getGlyphCode(int glyphIndex) {
+        if (glyphIndex >= this.vector.length || glyphIndex < 0) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        return this.vector[glyphIndex].getGlyphCode();
+    }
+
+    /**
+     * Returns character index of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public int getGlyphCharIndex(int glyphIndex) {
+
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IllegalArgumentException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        if ((this.layoutFlags & Font.LAYOUT_RIGHT_TO_LEFT) != 0) {
+            return this.charVector.length - glyphIndex - 1;
+        }
+
+        return glyphIndex;
+    }
+
+    /**
+     * Returns a character value of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    public char getGlyphChar(int glyphIndex) {
+
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IllegalArgumentException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        return this.charVector[glyphIndex];
+    }
+
+    /**
+     * Assigns default positions to each glyph in this GlyphVector.
+     */
+    @Override
+    public void performDefaultLayout() {
+
+        System.arraycopy(logicalPositions, 0, visualPositions, 0, logicalPositions.length);
+
+        // Set position changes flag to zero
+        clearLayoutFlags(GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
+    }
+
+    /**
+     * Returns the number of glyphs in this Glyph Vector
+     */
+    @Override
+    public int getNumGlyphs() {
+        return vector.length;
+    }
+
+    /**
+     * Returns the logical bounds of this GlyphVector
+     */
+    @Override
+    public Rectangle2D getLogicalBounds(){
+        // XXX: for transforms where an angle between basis vectors is not 90 degrees
+        // Rectanlge2D class doesn't fit as Logical bounds. For this reason we use
+        // only non-transformed bounds!!
+
+        float x = visualPositions[0];
+        float width = visualPositions[visualPositions.length-2];
+
+        double scaleY =  transform.getScaleY();
+
+        Rectangle2D bounds = new Rectangle2D.Float(x, (float)((-this.ascent-this.leading)*scaleY), width, (float)(this.height*scaleY));
+        return bounds;
+    }
+
+
+    /**
+     * Checks whether given GlyphVector equals to this GlyphVector.
+     * @param glyphVector GlyphVector object to compare
+     */
+    @Override
+    public boolean equals(GlyphVector glyphVector){
+        if (glyphVector == this){
+            return true;
+        }
+
+        if (glyphVector != null) {
+
+            if (!(glyphVector.getFontRenderContext().equals(this.vectorFRC) &&
+                      glyphVector.getFont().equals(this.font))){
+                return false;
+            }
+
+            try {
+                boolean eq = true;
+                for (int i = 0; i < getNumGlyphs(); i++) {
+
+                    int idx = i*2;
+                    eq = (((CommonGlyphVector)glyphVector).visualPositions[idx] == this.visualPositions[idx]) &&
+                        (((CommonGlyphVector)glyphVector).visualPositions[idx+1] == this.visualPositions[idx+1]) &&
+                        (glyphVector.getGlyphCharIndex(i) == this.getGlyphCharIndex(i));
+
+                    if (eq){
+                        AffineTransform trans = glyphVector.getGlyphTransform(i);
+                        if (trans == null){
+                            eq = (this.glsTransforms[i] == null);
+                        }else{
+                            eq = this.glsTransforms[i].equals(trans);
+                        }
+                    }
+
+                    if (!eq){
+                        return false;
+                    }
+                }
+
+                return  eq;
+            } catch (ClassCastException e) {
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
+     * Returns flags describing the state of the GlyphVector.
+     */
+    @Override
+    public int getLayoutFlags() {
+        return layoutFlags;
+    }
+
+    /**
+     * Returns char with the specified index.
+     * 
+     * @param index specified index of the char
+     * 
+     */
+    public char getChar(int index) {
+        return this.charVector[index];
+
+    }
+
+    /**
+     * Clear desired flags in layout flags describing the state. 
+     * 
+     * @param clearFlags flags mask to clear 
+     */
+    
+    private void clearLayoutFlags(int clearFlags){
+        layoutFlags &= ~clearFlags;
+    }
+
+    /**
+     * Returns the logical bounds of the specified glyph within this CommonGlyphVector.
+     * 
+     * @param glyphIndex index of the glyph to get it's logical bounds
+     * @return logical bounds of the specified glyph
+     */
+    @Override
+    public Shape getGlyphLogicalBounds(int glyphIndex){
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())){
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        Glyph glyph = this.vector[glyphIndex];
+
+        float x0 = visualPositions[glyphIndex*2];
+        float y0 = visualPositions[glyphIndex*2+1];
+        float advanceX = glyph.getGlyphPointMetrics().getAdvanceX();
+
+        GeneralPath gp = new GeneralPath();
+        gp.moveTo(0, -ascent - leading);
+        gp.lineTo(advanceX ,-ascent - leading);
+        gp.lineTo(advanceX, descent);
+        gp.lineTo(0, descent);
+        gp.lineTo(0, -ascent - leading);
+        gp.closePath();
+
+        /* Applying GlyphVector font transform */
+        AffineTransform at = (AffineTransform)this.transform.clone();
+
+        /* Applying Glyph transform */
+        AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
+        if (glyphTransform != null){
+            at.concatenate(glyphTransform);
+        }
+
+        /* Applying translation to actual visual bounds */
+        at.preConcatenate(AffineTransform.getTranslateInstance(x0, y0));
+        gp.transform(at);
+        return gp;
+    }
+
+    /**
+     * Returns the Font parameter of this GlyphVector
+     */
+    @Override
+    public Font getFont(){
+        return this.font;
+    }
+
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/font/CompositeFont.java b/awt/org/apache/harmony/awt/gl/font/CompositeFont.java
new file mode 100644
index 0000000..70cb334
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/CompositeFont.java
@@ -0,0 +1,486 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.FontProperty;
+
+/**
+ * CompositeFont class is the implementation of logical font classes. 
+ * Every logical font consists of several physical fonts that described 
+ * in font.properties file according to the face name of this logical font.
+ */
+public class CompositeFont extends FontPeerImpl{
+    
+    // a number of physical fonts that CompositeFont consist of 
+    int numFonts;
+
+    // font family name
+    String family;
+
+    // font face name
+    String face;
+
+    String[] fontNames;
+    
+    // an array of font properties applicable to this CompositeFont
+    FontProperty[] fontProperties;
+    
+    // an array of font peers applicable to this CompositeFont
+    public FontPeerImpl[] fPhysicalFonts;
+    
+    // missing glyph code field
+    int missingGlyphCode = -1;
+    
+    // line metrics of this font
+    LineMetricsImpl nlm = null;
+    
+    // cached num glyphs parameter of this font that is the sum of num glyphs of 
+    // font peers composing this font
+    int cachedNumGlyphs = -1;
+    /**
+     * Creates CompositeFont object that is corresponding to the specified logical 
+     * family name.
+     * 
+     * @param familyName logical family name CompositeFont is to be created from
+     * @param faceName logical face name CompositeFont is to be created from
+     * @param _style style of the CompositeFont to be created
+     * @param _size size of the CompositeFont to be created 
+     * @param fProperties an array of FontProperties describing physical fonts - 
+     * parts of logical font
+     * @param physFonts an array of physical font peers related to the CompositeFont
+     * to be created
+     */
+    public CompositeFont(String familyName, String faceName, int _style, int _size, FontProperty[] fProperties, FontPeerImpl[] physFonts){
+        this.size = _size;
+        this.name = faceName;
+        this.family = familyName;
+        this.style = _style;
+        this.face = faceName;
+        this.psName = faceName;
+        this.fontProperties = fProperties;// !! Supposed that fProperties parameter != null
+        fPhysicalFonts = physFonts;
+        numFonts = fPhysicalFonts.length; 
+        setDefaultLineMetrics("", null); //$NON-NLS-1$
+        this.uniformLM = false;
+    }
+
+    /**
+     * Returns the index of the FontPeer in array of physical fonts that is applicable 
+     * for the given character. This font has to have the highest priority among fonts
+     * that can display this character and don't have exclusion range covering 
+     * specified character. If there is no desired fonts -1 is returned.
+     * 
+     * @param chr specified character
+     * @return index of the font from the array of physical fonts that will be used 
+     * during processing of the specified character. 
+     */
+    public int getCharFontIndex(char chr){
+        for (int i = 0; i < numFonts; i++){
+            if (fontProperties[i].isCharExcluded(chr)){
+                continue;
+            }
+            if (fPhysicalFonts[i].canDisplay(chr)){
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns the index of the FontPeer in array of physical fonts that is applicable 
+     * for the given character. This font has to have the highest priority among fonts
+     * that can display this character and don't have exclusion range covering 
+     * specified character. If there is no desired fonts default value is returned.
+     * 
+     * @param chr specified character
+     * @param defaultValue default index that is returned if the necessary font couldn't be found.
+     * @return index of the font from the array of physical fonts that will be used 
+     * during processing of the specified character. 
+     */
+     public int getCharFontIndex(char chr, int defaultValue){
+        for (int i = 0; i < numFonts; i++){
+            if (fontProperties[i].isCharExcluded(chr)){
+                continue;
+            }
+            if (fPhysicalFonts[i].canDisplay(chr)){
+                return i;
+            }
+        }
+
+        return defaultValue;
+    }
+
+    /**
+     * Returns true if one of the physical fonts composing this font CompositeFont 
+     * can display specified character.
+     *   
+     * @param chr specified character
+     */
+    @Override
+    public boolean canDisplay(char chr){
+        return (getCharFontIndex(chr) != -1);
+    }
+
+    /**
+     * Returns logical ascent (in pixels)
+     */
+    @Override
+    public int getAscent(){
+        return nlm.getLogicalAscent();
+    }
+
+    /**
+     * Returns LineMetrics instance scaled according to the specified transform.  
+     * 
+     * @param str specified String 
+     * @param frc specified FontRenderContext 
+     * @param at specified AffineTransform
+     */
+     @Override
+    public LineMetrics getLineMetrics(String str, FontRenderContext frc , AffineTransform at){
+        LineMetricsImpl lm = (LineMetricsImpl)(this.nlm.clone());
+        lm.setNumChars(str.length());
+
+        if ((at != null) && (!at.isIdentity())){
+            lm.scale((float)at.getScaleX(), (float)at.getScaleY());
+        }
+
+        return lm;
+    }
+
+    /**
+     * Returns cached LineMetrics instance for the null string or creates it if
+     * it wasn't cached yet.
+     */
+    @Override
+    public LineMetrics getLineMetrics(){
+        if (nlm == null){
+            setDefaultLineMetrics("", null); //$NON-NLS-1$
+        }
+
+        return this.nlm;
+    }
+
+    /**
+     * Creates LineMetrics instance and set cached LineMetrics field to it.
+     * Created LineMetrics has maximum values of the idividual metrics of all
+     * composing physical fonts. If there is only one physical font - it's 
+     * LineMetrics object is returned.
+     * 
+     * @param str specified String 
+     * @param frc specified FontRenderContext 
+     */
+    private void setDefaultLineMetrics(String str, FontRenderContext frc){
+        LineMetrics lm = fPhysicalFonts[0].getLineMetrics(str, frc, null);
+        float maxCharWidth = (float)fPhysicalFonts[0].getMaxCharBounds(frc).getWidth();
+
+        if (numFonts == 1) {
+            this.nlm = (LineMetricsImpl)lm;
+            return;
+        }
+
+        float[] baselineOffsets = lm.getBaselineOffsets();
+        int numChars = str.length();
+
+        // XXX: default value - common for all Fonts
+        int baseLineIndex = lm.getBaselineIndex();
+
+        float maxUnderlineThickness = lm.getUnderlineThickness();
+        float maxUnderlineOffset = lm.getUnderlineOffset();
+        float maxStrikethroughThickness = lm.getStrikethroughThickness();
+        float minStrikethroughOffset = lm.getStrikethroughOffset();
+        float maxLeading = lm.getLeading();  // External leading
+        float maxHeight = lm.getHeight();   // Height of the font ( == (ascent + descent + leading))
+        float maxAscent = lm.getAscent();   // Ascent of the font
+        float maxDescent = lm.getDescent(); // Descent of the font
+
+        for (int i = 1; i < numFonts; i++){
+            lm = fPhysicalFonts[i].getLineMetrics(str, frc, null);
+            if (maxUnderlineThickness < lm.getUnderlineThickness()){
+                maxUnderlineThickness = lm.getUnderlineThickness();
+            }
+
+            if (maxUnderlineOffset < lm.getUnderlineOffset()){
+                maxUnderlineOffset = lm.getUnderlineOffset();
+            }
+
+            if (maxStrikethroughThickness < lm.getStrikethroughThickness()){
+                maxStrikethroughThickness = lm.getStrikethroughThickness();
+            }
+
+            if (minStrikethroughOffset > lm.getStrikethroughOffset()){
+                minStrikethroughOffset = lm.getStrikethroughOffset();
+            }
+
+            if (maxLeading < lm.getLeading()){
+                maxLeading = lm.getLeading();
+            }
+
+            if (maxAscent < lm.getAscent()){
+                maxAscent = lm.getAscent();
+            }
+
+            if (maxDescent < lm.getDescent()){
+                maxDescent = lm.getDescent();
+            }
+
+            float width = (float)fPhysicalFonts[i].getMaxCharBounds(frc).getWidth();
+            if(maxCharWidth < width){
+                maxCharWidth = width;
+            }
+            for (int j =0; j < baselineOffsets.length; j++){
+                float[] offsets = lm.getBaselineOffsets();
+                if (baselineOffsets[j] > offsets[j]){
+                    baselineOffsets[j] = offsets[j];
+                }
+            }
+
+        }
+        maxHeight = maxAscent + maxDescent + maxLeading;
+
+        this.nlm =  new LineMetricsImpl(
+                numChars,
+                baseLineIndex,
+                baselineOffsets,
+                maxUnderlineThickness,
+                maxUnderlineOffset,
+                maxStrikethroughThickness,
+                minStrikethroughOffset,
+                maxLeading,
+                maxHeight,
+                maxAscent,
+                maxDescent,
+                maxCharWidth);
+
+    }
+
+    /**
+     * Returns the number of glyphs in this CompositeFont object.
+     */
+    @Override
+    public int getNumGlyphs(){
+        if (this.cachedNumGlyphs == -1){
+
+            this.cachedNumGlyphs = 0;
+
+            for (int i = 0; i < numFonts; i++){
+                this.cachedNumGlyphs += fPhysicalFonts[i].getNumGlyphs();
+            }
+        }
+
+        return this.cachedNumGlyphs;
+    }
+
+    /**
+     * Returns the italic angle of this object.
+     */
+    @Override
+    public float getItalicAngle(){
+        // !! only first physical font used to get this value
+        return fPhysicalFonts[0].getItalicAngle();
+    }
+
+    /**
+     * Returns rectangle that bounds the specified string in terms of composite line metrics.
+     * 
+     * @param chars an array of chars
+     * @param start the initial offset in array of chars
+     * @param end the end offset in array of chars
+     * @param frc specified FontRenderContext
+     */
+    public Rectangle2D getStringBounds(char[] chars, int start, int end, FontRenderContext frc){
+
+        LineMetrics lm = getLineMetrics();
+        float minY = -lm.getAscent();
+        float minX = 0;
+        float height = lm.getHeight();
+        float width = 0;
+
+        for (int i = start; i < end; i++){
+            width += charWidth(chars[i]);
+        }
+
+        Rectangle2D rect2D = new Rectangle2D.Float(minX, minY, width, height);
+        return rect2D;
+
+    }
+
+    /**
+     * Returns maximum rectangle that encloses all maximum char bounds of 
+     * physical fonts composing this CompositeFont.
+     *  
+     * @param frc specified FontRenderContext
+     */
+    @Override
+    public Rectangle2D getMaxCharBounds(FontRenderContext frc){
+
+        Rectangle2D rect2D = fPhysicalFonts[0].getMaxCharBounds(frc);
+        float minY = (float)rect2D.getY();
+        float maxWidth = (float)rect2D.getWidth();
+        float maxHeight = (float)rect2D.getHeight();
+        if (numFonts == 1){
+            return rect2D;
+        }
+
+        for (int i = 1; i < numFonts; i++){
+            if (fPhysicalFonts[i] != null){
+                rect2D = fPhysicalFonts[i].getMaxCharBounds(frc);
+                float y = (float)rect2D.getY();
+                float mWidth = (float)rect2D.getWidth();
+                float mHeight = (float)rect2D.getHeight();
+                if (y < minY){
+                    minY = y;
+                }
+                if (mWidth > maxWidth){
+                    maxHeight = mWidth;
+                }
+                
+                if (mHeight > maxHeight){
+                    maxHeight = mHeight;
+                }
+            }
+        }
+
+        rect2D = new Rectangle2D.Float(0, minY, maxWidth, maxHeight);
+
+        return rect2D;
+    }
+
+    /**
+     * Returns font name.
+     */
+    @Override
+    public String getFontName(){
+        return face;
+    }
+
+    /**
+     * Returns font postscript name.
+     */
+    @Override
+    public String getPSName(){
+        return psName;
+    }
+
+    /**
+     * Returns font family name.
+     */
+    @Override
+    public String getFamily(){
+        return family;
+    }
+
+    /**
+     * Returns the code of the missing glyph.
+     */
+    @Override
+    public int getMissingGlyphCode(){
+        // !! only first physical font used to get this value
+        return fPhysicalFonts[0].getMissingGlyphCode();
+    }
+
+    /**
+     * Returns Glyph object corresponding to the specified character.
+     * 
+     * @param ch specified char
+     */
+    @Override
+    public Glyph getGlyph(char ch){
+        for (int i = 0; i < numFonts; i++){
+            if (fontProperties[i].isCharExcluded(ch)){
+                    continue;
+            }
+            
+            /* Control symbols considered to be supported by the font peer */
+            if ((ch < 0x20) || fPhysicalFonts[i].canDisplay(ch)){
+                return fPhysicalFonts[i].getGlyph(ch);
+            }
+        }
+        return getDefaultGlyph();
+    }
+
+    /**
+     * Returns width of the char with specified index.
+     * 
+     * @param ind specified index of the character 
+     */
+    @Override
+    public int charWidth(int ind){
+        return charWidth((char)ind);
+    }
+
+    /**
+     * Returns width of the specified char.
+     * 
+     * @param c specified character 
+     */
+    @Override
+    public int charWidth(char c){
+        Glyph gl = this.getGlyph(c);
+        return (int)gl.getGlyphPointMetrics().getAdvanceX();
+    }
+
+    /**
+     * Returns debug information about this class.
+     */
+    @Override
+    public String toString(){
+    return new String(this.getClass().getName() +
+            "[name=" + this.name + //$NON-NLS-1$
+            ",style="+ this.style + //$NON-NLS-1$
+            ",fps=" + this.fontProperties + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Returns Glyph object corresponding to the default glyph.
+     */
+    @Override
+    public Glyph getDefaultGlyph(){
+        // !! only first physical font used to get this value
+        return fPhysicalFonts[0].getDefaultGlyph();
+    }
+    
+    /**
+     * Returns FontExtraMetrics object with extra metrics
+     * related to this CompositeFont.
+     */
+    @Override
+    public FontExtraMetrics getExtraMetrics(){
+        // Returns FontExtraMetrics instanse of the first physical 
+        // Font from the array of fonts.
+        return fPhysicalFonts[0].getExtraMetrics();
+    }
+
+    /**
+     * Disposes CompositeFont object's resources.
+     */
+    @Override
+    public void dispose() {
+        // Nothing to dispose
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java b/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java
new file mode 100644
index 0000000..047ba6d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java
@@ -0,0 +1,145 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ * 
+ */
+package org.apache.harmony.awt.gl.font;
+
+/**
+ * Extra font metrics: sub/superscripts sizes, offsets, average char width.
+ */
+public class FontExtraMetrics {
+    
+    /* !! Subscript/superscript metrics are undefined for Type1. As a possible 
+     * solution we can use values for Type1, that are proportionate to TrueType
+     * ones:
+     *  SubscriptSizeX == 0.7 * fontSize
+     *  SubscriptSizeY == 0.65 * fontSize
+     *  SubscriptOffsetX == 0;
+     *  SubscriptOffsetY == 0.15 * fontSize;
+     *  SuperscriptSizeX == 0.7 * fontSize
+     *  SuperscriptSizeY == 0.65 * fontSize
+     *  SuperscriptOffsetX == 0;
+     *  SuperscriptOffsetY == 0.45 * fontSize
+     *  
+     */
+    
+    /*
+     * The average width of characters in the font.
+     */
+    private float lAverageCharWidth;
+    
+    /*
+     * Horizontal size for subscripts.
+     */
+    private float lSubscriptSizeX;
+
+    /*
+     * Vertical size for subscripts.
+     */
+    private float lSubscriptSizeY; 
+    
+    /*
+     * Horizontal offset for subscripts, the offset from the character origin 
+     * to the origin of the subscript character.
+     */
+    private float lSubscriptOffsetX; 
+
+    /*
+     * Vertical offset for subscripts, the offset from the character origin 
+     * to the origin of the subscript character.
+     */
+    private float lSubscriptOffsetY;
+    
+    /*
+     * Horizontal size for superscripts.
+     */
+    private float lSuperscriptSizeX; 
+
+    /*
+     * Vertical size for superscripts.
+     */
+    private float lSuperscriptSizeY;
+    
+    /*
+     * Horizontal offset for superscripts, the offset from the character 
+     * base line to the base line of the superscript character.
+     */
+    private float lSuperscriptOffsetX;
+
+    /*
+     * Vertical offset for superscripts, the offset from the character 
+     * base line to the base line of the superscript character.
+     */
+    private float lSuperscriptOffsetY;
+    
+    public FontExtraMetrics(){
+        // default constructor
+    }
+
+    public FontExtraMetrics(float[] metrics){
+        lAverageCharWidth = metrics[0];
+        lSubscriptSizeX = metrics[1];
+        lSubscriptSizeY = metrics[2];
+        lSubscriptOffsetX = metrics[3];
+        lSubscriptOffsetY = metrics[4];
+        lSuperscriptSizeX = metrics[5];
+        lSuperscriptSizeY = metrics[6];
+        lSuperscriptOffsetX = metrics[7];
+        lSuperscriptOffsetY = metrics[8];
+    }
+
+    public float getAverageCharWidth(){
+        return lAverageCharWidth;
+    }
+    
+    public float getSubscriptSizeX(){
+        return lSubscriptSizeX;
+    }
+
+    public float getSubscriptSizeY(){
+        return lSubscriptSizeY;
+    }
+
+    public float getSubscriptOffsetX(){
+        return lSubscriptOffsetX;
+    }
+
+    public float getSubscriptOffsetY(){
+        return lSubscriptOffsetY;
+    }
+
+    public float getSuperscriptSizeX(){
+        return lSuperscriptSizeX;
+    }
+
+    public float getSuperscriptSizeY(){
+        return lSuperscriptSizeY;
+    }
+
+    public float getSuperscriptOffsetX(){
+        return lSuperscriptOffsetX;
+    }
+
+    public float getSuperscriptOffsetY(){
+        return lSuperscriptOffsetY;
+    }
+    
+    
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontFinder.java b/awt/org/apache/harmony/awt/gl/font/FontFinder.java
new file mode 100644
index 0000000..09bcf5c
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontFinder.java
@@ -0,0 +1,121 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Jul 12, 2005
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.GraphicsEnvironment;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class chooses the default font for the given text.
+ * If it finds the character which current font is unable to display
+ * it starts the next font run and looks for the font which is able to
+ * display the current character. It also caches the font mappings
+ * (index in the array containing all fonts) for the characters,
+ * using that fact that scripts are mainly contiguous in the UTF-16 encoding
+ * and there's a high probability that the upper byte will be the same for the
+ * next character as for the previous. This allows to save the space used for the cache.
+ */
+public class FontFinder {
+    private static final float DEFAULT_FONT_SIZE = 12;
+
+    private static final Font fonts[] =
+            GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
+
+    private static final int NUM_BLOCKS = 256;
+    private static final int BLOCK_SIZE = 256;
+    private static final int INDEX_MASK = 0xFF;
+    private static final int BLOCK_SHIFT = 8;
+
+    // Maps characters into the fonts array
+    private static final int blocks[][] = new int[NUM_BLOCKS][];
+
+    /**
+     * Finds the font which is able to display the given character
+     * and saves the font mapping for this character
+     * @param c - character
+     * @return font
+     */
+    static Font findFontForChar(char c) {
+        int blockNum = c >> BLOCK_SHIFT;
+        int index = c & INDEX_MASK;
+
+        if (blocks[blockNum] == null) {
+            blocks[blockNum] = new int[BLOCK_SIZE];
+        }
+
+        if (blocks[blockNum][index] == 0) {
+            blocks[blockNum][index] = 1;
+
+            for (int i=0; i<fonts.length; i++) {
+                if (fonts[i].canDisplay(c)) {
+                    blocks[blockNum][index] = i+1;
+                    break;
+                }
+            }
+        }
+
+        return getDefaultSizeFont(blocks[blockNum][index]-1);
+    }
+
+    /**
+     * Derives the default size font
+     * @param i - index in the array of all fonts
+     * @return derived font
+     */
+    static Font getDefaultSizeFont(int i) {
+        if (fonts[i].getSize() != DEFAULT_FONT_SIZE) {
+            fonts[i] = fonts[i].deriveFont(DEFAULT_FONT_SIZE);
+        }
+
+        return fonts[i];
+    }
+
+    /**
+     * Assigns default fonts for the given text run.
+     * First three parameters are input, last three are output.
+     * @param text - given text
+     * @param runStart - start of the text run
+     * @param runLimit - end of the text run
+     * @param runStarts - starts of the resulting font runs
+     * @param fonts - mapping of the font run starts to the fonts
+     */
+    static void findFonts(char text[], int runStart, int runLimit, List<Integer> runStarts,
+            Map<Integer, Font> fonts) {
+        Font prevFont = null;
+        Font currFont;
+        for (int i = runStart; i < runLimit; i++) {
+            currFont = findFontForChar(text[i]);
+            if (currFont != prevFont) {
+                prevFont = currFont;
+                Integer idx = new Integer(i);
+                fonts.put(idx, currFont);
+                if (i != runStart) {
+                    runStarts.add(idx);
+                }
+            }
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontManager.java b/awt/org/apache/harmony/awt/gl/font/FontManager.java
new file mode 100644
index 0000000..8354e25
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontManager.java
@@ -0,0 +1,819 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.peer.FontPeer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
+import org.apache.harmony.luni.util.NotImplementedException;
+
+
+public abstract class FontManager {
+    
+    //???AWT
+    boolean NOT_IMP = false;
+    
+    /**
+     * array of font families names
+     */
+    public String[] allFamilies;
+
+    public static final String DEFAULT_NAME = "Default"; /* Default font name */ //$NON-NLS-1$
+    public static final String DIALOG_NAME = "Dialog";  /* Dialog font name */ //$NON-NLS-1$
+
+    /**
+     * Set of constants applicable to the TrueType 'name' table.
+     */
+    public static final byte  FAMILY_NAME_ID  = 1;      /* Family name identifier   */
+    public static final byte  FONT_NAME_ID  = 4;        /* Full font name identifier    */
+    public static final byte  POSTSCRIPT_NAME_ID = 6;   /* PostScript name identifier   */
+    public static final short ENGLISH_LANGID = 0x0409;  /* English (United States)language identifier   */
+
+    /**
+     * Set of constants describing font type.
+     */
+    public static final byte  FONT_TYPE_TT  = 4;        /* TrueType type (TRUETYPE_FONTTYPE)    */
+    public static final byte  FONT_TYPE_T1  = 2;        /* Type1 type    (DEVICE_FONTTYPE)      */
+    public static final byte  FONT_TYPE_UNDEF  = 0;     /* Undefined type                       */
+
+    // logical family types (indices in FontManager.LOGICAL_FONT_NAMES)
+    static final int DIALOG = 3;        // FF_SWISS
+    static final int SANSSERIF = 1;     // FF_SWISS
+    static final int DIALOGINPUT = 4;   // FF_MODERN
+    static final int MONOSPACED = 2;    // FF_MODERN
+    static final int SERIF = 0;         // FF_ROMAN
+
+
+    /**
+     * FontProperty related constants. 
+     */
+    public static final String PLATFORM_FONT_NAME = "PlatformFontName"; //$NON-NLS-1$
+    public static final String LOGICAL_FONT_NAME = "LogicalFontName"; //$NON-NLS-1$
+    public static final String COMPONENT_INDEX = "ComponentIndex"; //$NON-NLS-1$
+    public static final String STYLE_INDEX = "StyleIndex"; //$NON-NLS-1$
+
+    public static final String[] FONT_MAPPING_KEYS = {
+            "LogicalFontName.StyleName.ComponentIndex", "LogicalFontName.ComponentIndex" //$NON-NLS-1$ //$NON-NLS-2$
+    };
+
+    public static final String FONT_CHARACTER_ENCODING = "fontcharset.LogicalFontName.ComponentIndex"; //$NON-NLS-1$
+
+    public static final String EXCLUSION_RANGES = "exclusion.LogicalFontName.ComponentIndex"; //$NON-NLS-1$
+
+    public static final String FONT_FILE_NAME = "filename.PlatformFontName"; //$NON-NLS-1$
+
+    /**
+     * Available logical font families names.
+     */
+    public static final String[] LOGICAL_FONT_FAMILIES = {
+            "Serif", "SansSerif", "Monospaced", "Dialog", "DialogInput" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    };
+
+    /**
+     * Available logical font names.
+     */
+    public static final String[] LOGICAL_FONT_NAMES = {
+            "serif", "serif.plain", "serif.bold", "serif.italic", "serif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "sansserif", "sansserif.plain", "sansserif.bold", "sansserif.italic", "sansserif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "monospaced", "monospaced.plain", "monospaced.bold", "monospaced.italic", "monospaced.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "dialog", "dialog.plain", "dialog.bold", "dialog.italic", "dialog.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "dialoginput", "dialoginput.plain", "dialoginput.bold", "dialoginput.italic", "dialoginput.bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    };
+
+    /**
+     * Available logical font face names.
+     */
+    public static final String[] LOGICAL_FONT_FACES = {
+            "Serif", "Serif.plain", "Serif.bold", "Serif.italic", "Serif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Sansserif", "Sansserif.plain", "Sansserif.bold", "Sansserif.italic", "Sansserif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Monospaced", "Monospaced.plain", "Monospaced.bold", "Monospaced.italic", "Monospaced.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Dialog", "Dialog.plain", "Dialog.bold", "Dialog.italic", "Dialog.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Dialoginput", "Dialoginput.plain", "Dialoginput.bold", "Dialoginput.italic", "Dialoginput.bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    };
+
+    /**
+     * Set of font style names.
+     * Font.getStyle() corresponds to indexes in STYLE_NAMES array.
+     */
+    public static final String[] STYLE_NAMES = {
+            "plain", "bold", "italic", "bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    };
+
+    /**
+     * Logical font styles names table where font styles names used 
+     * as the key and the value is the index of this style name.
+     */
+    private static final Hashtable<String, Integer> style_keys = new Hashtable<String, Integer>(4);
+
+    /**
+     * Initialize font styles keys table.
+     */
+    static {
+        for (int i = 0; i < STYLE_NAMES.length; i++){
+            style_keys.put(STYLE_NAMES[i], Integer.valueOf(i));
+        }
+    }
+
+    /**
+     * Return font style from the logical style name.
+     * 
+     * @param lName style name of the logical face
+     */
+    public static int getLogicalStyle(String lName){
+        Integer value = style_keys.get(lName);
+        return value != null ? value.intValue(): -1;
+    }
+
+    /**
+     * Set of possible "os" property values.
+     */
+    public static final String[] OS_VALUES = {
+            "NT", "98", "2000", "Me", "XP", // For Windows //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Redhat", "Turbo", "SuSE"       // For Linux //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    };
+
+    /**
+     * Set of possible font.property file names.
+     * Language, Country, Encoding, OS, Version should be replaced with
+     * the values from current configuration.
+     */
+    public static final String[] FP_FILE_NAMES = {
+            "/lib/font.properties.Language_Country_Encoding.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country_Encoding.OS", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country_Encoding.Version", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country_Encoding", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country.OS", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country.Version", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country", //$NON-NLS-1$
+            "/lib/font.properties.Language_Encoding.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Language_Encoding.OS", //$NON-NLS-1$
+            "/lib/font.properties.Language_Encoding.Version", //$NON-NLS-1$
+            "/lib/font.properties.Language_Encoding", //$NON-NLS-1$
+            "/lib/font.properties.Language.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Language.OS", //$NON-NLS-1$
+            "/lib/font.properties.Language.Version", //$NON-NLS-1$
+            "/lib/font.properties.Language", //$NON-NLS-1$
+            "/lib/font.properties.Encoding.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Encoding.OS", //$NON-NLS-1$
+            "/lib/font.properties.Encoding.Version", //$NON-NLS-1$
+            "/lib/font.properties.Encoding", //$NON-NLS-1$
+            "/lib/font.properties.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.OS", //$NON-NLS-1$
+            "/lib/font.properties.Version", //$NON-NLS-1$
+            "/lib/font.properties" //$NON-NLS-1$
+    };
+
+    /**
+     * Table with all available font properties corresponding
+     * to the current system configuration.
+     */
+    public Hashtable<String, Vector<FontProperty>> fProperties = new Hashtable<String, Vector<FontProperty>>();
+    
+    public FontManager(){
+        allFamilies = getAllFamilies();
+        /*
+         * Creating and registering shutdown hook to free resources
+         * before object is destroyed.
+         */
+        //???AWT
+        //DisposeNativeHook shutdownHook = new DisposeNativeHook();
+        //Runtime.getRuntime().addShutdownHook(shutdownHook);
+    }
+
+    /**
+     * Maximum number of unreferenced font peers to keep.
+     */
+    public static final int EMPTY_FONTS_CAPACITY = 10;
+
+    /**
+     * Locale - Language ID hash table.
+     */
+    Hashtable<String, Short> tableLCID = new Hashtable<String, Short>();
+
+    /**
+     * Hash table that contains FontPeers instances.
+     */
+    public Hashtable<String, HashMapReference> fontsTable = new Hashtable<String, HashMapReference>();
+    
+    /**
+     * ReferenceQueue for HashMapReference objects to check
+     * if they were collected by garbage collector. 
+     */
+    public ReferenceQueue<FontPeer> queue = new ReferenceQueue<FontPeer>();
+
+    /**
+     * Singleton instance
+     */
+    public final static FontManager inst = CommonGraphics2DFactory.inst.getFontManager();
+
+    /**
+     * Gets singleton instance of FontManager
+     * 
+     * @return instance of FontManager implementation
+     */
+    public static FontManager getInstance() {
+        return inst;
+    }
+
+    /**
+     * Returns platform-dependent Font peer created from the specified 
+     * Font object from the table with cached FontPeers instances.
+     * 
+     * Note, this method checks whether FontPeer with specified parameters 
+     * exists in the table with cached FontPeers' instances. If there is no needed 
+     * instance - it is created and cached.
+     * 
+     * @param fontName name of the font 
+     * @param _fontStyle style of the font 
+     * @param size font size
+     * 
+     * @return platform dependent FontPeer implementation created from 
+     * the specified parameters
+     */
+    public FontPeer getFontPeer(String fontName, int _fontStyle, int size) {
+        updateFontsTable();
+        
+        FontPeer peer = null;
+        String key; 
+        String name;
+        int fontStyle = _fontStyle;
+        
+        int logicalIndex = getLogicalFaceIndex(fontName);
+        
+        if (logicalIndex != -1){
+            name = getLogicalFaceFromFont(fontStyle, logicalIndex);
+            fontStyle = getStyleFromLogicalFace(name);
+            key = name.concat(String.valueOf(size));
+        } else {
+            name = fontName;
+            key = name.concat(String.valueOf(fontStyle)).
+                    concat(String.valueOf(size));
+        }
+        
+        HashMapReference hmr   = fontsTable.get(key);
+        if (hmr != null) {
+            peer = hmr.get();
+        }
+
+        if (peer == null) {
+            peer = createFontPeer(name, fontStyle, size, logicalIndex);
+            if (peer == null){
+                peer = getFontPeer(DIALOG_NAME, fontStyle, size);
+            }
+            fontsTable.put(key, new HashMapReference(key, peer, queue));
+        }
+
+        return peer;
+    }
+    
+    /**
+     * Returns instance of font peer (logical or physical) according to the 
+     * specified parameters.
+     * 
+     * @param name font face name
+     * @param style style of the font
+     * @param size size of the font
+     * @param logicalIndex index of the logical face name in LOGICAL_FONT_FACES 
+     * array or -1 if desired font peer is not logical.
+     */
+    private FontPeer createFontPeer(String name, int style, int size, int logicalIndex){
+        FontPeer peer;
+        if (logicalIndex != -1){
+            peer = createLogicalFontPeer(name, style, size);
+        }else {
+            peer = createPhysicalFontPeer(name, style, size);
+        }
+        
+        return peer;
+    }
+    
+    /**
+     * Returns family name for logical face names as a parameter.
+     * 
+     * @param faceName logical font face name
+     */
+    public String getFamilyFromLogicalFace(String faceName){
+        int pos = faceName.indexOf("."); //$NON-NLS-1$
+        if (pos == -1){
+            return faceName;
+        }
+            
+        return faceName.substring(0, pos);
+    }
+            
+    /**
+     * Returns new logical font peer for the parameters specified using font 
+     * properties.
+     * 
+     * @param faceName face name of the logical font 
+     * @param style style of the font 
+     * @param size font size
+     * 
+     */
+    private FontPeer createLogicalFontPeer(String faceName, int style, int size){
+        String family = getFamilyFromLogicalFace(faceName);
+        FontProperty[] fps = getFontProperties(family.toLowerCase() + "." + style); //$NON-NLS-1$
+        if (fps != null){
+            int numFonts = fps.length;
+            FontPeerImpl[] physicalFonts = new FontPeerImpl[numFonts];
+            for (int i = 0; i < numFonts; i++){
+                FontProperty fp = fps[i];
+                
+                String name = fp.getName();
+                int fpStyle = fp.getStyle();
+                String key = name.concat(String.valueOf(fpStyle)).
+                    concat(String.valueOf(size));
+                
+                HashMapReference hmr   = fontsTable.get(key);
+                if (hmr != null) {
+                    physicalFonts[i] = (FontPeerImpl)hmr.get();
+                }
+
+                if (physicalFonts[i] == null){
+                    physicalFonts[i] = (FontPeerImpl)createPhysicalFontPeer(name, fpStyle, size);
+                    fontsTable.put(key, new HashMapReference(key, physicalFonts[i], queue));
+                }
+
+                if (physicalFonts[i] == null){
+                    physicalFonts[i] = (FontPeerImpl)getDefaultFont(style, size);
+                }
+            }
+            return new CompositeFont(family, faceName, style, size, fps, physicalFonts); 
+        }
+        
+        // if there is no property for this logical font - default font is to be
+        // created
+        FontPeerImpl peer = (FontPeerImpl)getDefaultFont(style, size);
+        
+        return peer;
+    }
+
+    /**
+     * Returns new physical font peer for the parameters specified using font properties
+     * This method must be overridden by subclasses implementations.
+     *  
+     * @param faceName face name or family name of the font 
+     * @param style style of the font 
+     * @param size font size
+     * 
+     */
+    public abstract FontPeer createPhysicalFontPeer(String name, int style, int size);
+    
+    /**
+     * Returns default font peer class with "Default" name that is usually 
+     * used when font with specified font names and style doesn't exsist 
+     * on a system. 
+     * 
+     * @param style style of the font
+     * @param size size of the font
+     */
+    public FontPeer getDefaultFont(int style, int size){
+        updateFontsTable();
+        
+        FontPeer peer = null;
+        String key = DEFAULT_NAME.concat(String.valueOf(style)).
+                    concat(String.valueOf(size));
+        
+        HashMapReference hmr   = fontsTable.get(key);
+        if (hmr != null) {
+            peer = hmr.get();
+        }
+
+        if (peer == null) {
+            peer = createDefaultFont(style, size);
+            
+            ((FontPeerImpl)peer).setFamily(DEFAULT_NAME);
+            ((FontPeerImpl)peer).setPSName(DEFAULT_NAME);
+            ((FontPeerImpl)peer).setFontName(DEFAULT_NAME);
+
+            fontsTable.put(key, new HashMapReference(key, peer, queue));
+        }
+
+        return peer;
+    }
+    
+    /**
+     * 
+     * Returns new default font peer with "Default" name for the parameters 
+     * specified. This method must be overridden by subclasses implementations.
+     *  
+     * @param style style of the font
+     * @param size size of the font
+     */
+    public abstract FontPeer createDefaultFont(int style, int size);
+    
+    /**
+     * Returns face name of the logical font, which is the result
+     * of specified font style and face style union.   
+     * 
+     * @param fontStyle specified style of the font
+     * @param logicalIndex index of the specified face from the 
+     * LOGICAL_FONT_FACES array
+     * @return resulting face name
+     */
+    public String getLogicalFaceFromFont(int fontStyle, int logicalIndex){
+        int style = 0;
+        String name = LOGICAL_FONT_FACES[logicalIndex];
+        int pos = name.indexOf("."); //$NON-NLS-1$
+        
+        if (pos == -1){
+            return createLogicalFace(name, fontStyle);
+        }
+        
+        String styleName = name.substring(pos+1);
+        name = name.substring(0, pos);
+        
+        // appending font style to the face style
+        style = fontStyle | getLogicalStyle(styleName);
+        
+        return createLogicalFace(name, style);
+    }
+    
+    /**
+     * Function returns style value from logical face name.
+     *  
+     * @param name face name
+     * @return font style
+     */
+    public int getStyleFromLogicalFace(String name){
+        int style;
+        int pos = name.indexOf("."); //$NON-NLS-1$
+        
+        if (pos == -1){
+            return Font.PLAIN;
+        }
+        
+        String styleName = name.substring(pos+1);
+        
+        style = getLogicalStyle(styleName);
+        
+        return style;
+    }
+
+    /**
+     * Returns logical face name corresponding to the logical
+     * family name and style of the font.
+     * 
+     * @param family font family
+     * @param styleIndex index of the style name from the STYLE_NAMES array 
+     */
+    public String createLogicalFace(String family, int styleIndex){
+        return family + "." + STYLE_NAMES[styleIndex]; //$NON-NLS-1$
+    }
+    
+    /**
+     * Return language Id from LCID hash corresponding to the specified locale
+     * 
+     * @param l specified locale
+     */
+    public Short getLCID(Locale l){
+        if (this.tableLCID.size() == 0){
+            initLCIDTable();
+        }
+
+        return tableLCID.get(l.toString());
+    }
+
+    /**
+     * Platform-dependent LCID table init.
+     */
+    public abstract void initLCIDTable();
+
+    /**
+     * Freeing native resources. This hook is used to avoid 
+     * sudden application exit and to free resources created in native code.
+     */
+    private class DisposeNativeHook extends Thread {
+
+        @Override
+        public void run() {
+            try{
+                /* Disposing native font peer's resources */
+                Enumeration<String> kEnum = fontsTable.keys();
+
+                while(kEnum.hasMoreElements()){
+                    Object key = kEnum.nextElement();
+                    HashMapReference hmr = fontsTable.remove(key);
+                    FontPeerImpl delPeer = (FontPeerImpl)hmr.get();
+                    
+                    if ((delPeer != null) && (delPeer.getClass() != CompositeFont.class)){
+                        // there's nothing to dispose in CompositeFont objects
+                        delPeer.dispose();
+                    }
+                }
+            } catch (Throwable t){
+                throw new RuntimeException(t);
+            }
+        }
+      }
+
+    /**
+     * Returns File object, created in a directory
+     * according to the System, where JVM is being ran.
+     *
+     * In Linux case we use ".fonts" directory (for fontconfig purpose),
+     * where font file from the stream will be stored, hence in LinuxFontManager this
+     * method is overridden.
+     * In Windows case we use Windows temp directory (default implementation)
+     *
+     */
+    public File getTempFontFile()throws IOException{
+        //???AWT
+        /*
+        File fontFile = File.createTempFile("jFont", ".ttf"); //$NON-NLS-1$ //$NON-NLS-2$
+        fontFile.deleteOnExit();
+
+        return fontFile;
+         */
+        if(NOT_IMP)
+            throw new NotImplementedException("getTempFontFile not Implemented");
+        return null;
+    }
+
+    /**
+     * Returns File object with font properties. It's name obtained using current 
+     * system configuration properties and locale settings. If no appropriate 
+     * file is found method returns null. 
+     */
+    public static File getFontPropertyFile(){
+        File file = null;
+
+        String javaHome = System.getProperty("java.home"); //$NON-NLS-1$
+        Locale l = Locale.getDefault();
+        String language = l.getLanguage();
+        String country = l.getCountry();
+        String fileEncoding = System.getProperty("file.encoding"); //$NON-NLS-1$
+
+        String os = System.getProperty("os.name"); //$NON-NLS-1$
+
+        int i = 0;
+
+        // OS names from system properties don't match
+        // OS identifiers used in font.property files
+        for (; i < OS_VALUES.length; i++){
+            if (os.endsWith(OS_VALUES[i])){
+                os = OS_VALUES[i];
+                break;
+            }
+        }
+
+        if (i == OS_VALUES.length){
+            os = null;
+        }
+
+        String version = System.getProperty("os.version"); //$NON-NLS-1$
+        String pathname;
+
+        for (i = 0; i < FP_FILE_NAMES.length; i++){
+            pathname = FP_FILE_NAMES[i];
+            if (os != null){
+                pathname = pathname.replaceFirst("OS", os); //$NON-NLS-1$
+            }
+
+            pathname = javaHome + pathname;
+
+            pathname = pathname.replaceAll("Language", language). //$NON-NLS-1$
+                                replaceAll("Country", country). //$NON-NLS-1$
+                                replaceAll("Encoding", fileEncoding). //$NON-NLS-1$
+                                replaceAll("Version", version); //$NON-NLS-1$
+
+            file = new File(pathname);
+
+            if (file.exists()){
+                break;
+            }
+        }
+
+        return file.exists() ? file : null;
+    }
+
+    /**
+     * Returns an array of integer range values
+     * if the parameter exclusionString has format:
+     *          Range
+     *          Range [, exclusionString]
+     *
+     *          Range:
+     *              Char-Char
+     *
+     *          Char:
+     *              HexDigit HexDigit HexDigit HexDigit
+     * 
+     * Method returns null if the specified string is null.
+     *  
+     * @param exclusionString string parameter in specified format
+     */
+    public static int[] parseIntervals(String exclusionString){
+        int[] results = null;
+
+        if (exclusionString == null){
+            return null;
+        }
+
+        String[] intervals = exclusionString.split(","); //$NON-NLS-1$
+
+        if (intervals != null){
+            int num = intervals.length;
+            if (num > 0){
+                results = new int[intervals.length << 1];
+                for (int i = 0; i < intervals.length; i++){
+                    String ranges[] = intervals[i].split("-"); //$NON-NLS-1$
+                    results[i*2] = Integer.parseInt(ranges[0], 16);
+                    results[i*2+1] = Integer.parseInt(ranges[1], 16);
+
+                }
+            }
+        }
+        return results;
+    }
+
+    /**
+     * Returns Properties from the properties file or null if 
+     * there is an error with FileInputStream processing.
+     * 
+     * @param file File object containing properties
+     */
+    public static Properties getProperties(File file){
+        Properties props = null;
+        FileInputStream fis = null;
+        try{
+            fis = new FileInputStream(file);
+            props = new Properties();
+            props.load(fis);
+        } catch (Exception e){
+            System.out.println(e);
+        }
+        return props;
+    }
+
+    /**
+     * Returns an array of FontProperties from the properties file
+     * with the specified property name "logical face.style". E.g. 
+     * "dialog.2" corresponds to the font family Dialog with bold style. 
+     *
+     * @param fpName key of the font properties in the properties set
+     */
+    public FontProperty[] getFontProperties(String fpName){
+        Vector<FontProperty> props = fProperties.get(fpName);
+        
+        if (props == null){
+            return null;
+        }
+
+        int size =  props.size();
+        
+        if (size == 0){
+            return null;
+        }
+
+        FontProperty[] fps = new FontProperty[size];
+        for (int i=0; i < fps.length; i++){
+            fps[i] = props.elementAt(i);
+        }
+        return fps;
+    }
+
+    /**
+     * Returns index of the font name in array of font names or -1 if 
+     * this font is not logical.
+     * 
+     * @param fontName specified font name
+     */
+    public static int getLogicalFaceIndex(String fontName){
+        for (int i=0; i<LOGICAL_FONT_NAMES.length; i++ ){
+            if (LOGICAL_FONT_NAMES[i].equalsIgnoreCase(fontName)){
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns true if specified family name is available in this 
+     * GraphicsEnvironment. 
+     * 
+     * @param familyName the specified font family name
+     */
+    public boolean isFamilyExist(String familyName){
+        return (getFamilyIndex(familyName) != -1);
+    }
+
+    /**
+     * Returns index of family name from the array of family names available in 
+     * this GraphicsEnvironment or -1 if no family name was found.
+     * 
+     * @param familyName specified font family name 
+     */
+    public int getFamilyIndex(String familyName){
+        for (int i=0; i<allFamilies.length; i++ ){
+            if (familyName.equalsIgnoreCase(allFamilies[i])){
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns family with index specified from the array of family names available in 
+     * this GraphicsEnvironment.
+     * 
+     * @param index index of the family in families names array 
+     */
+    public String getFamily(int index){
+        return allFamilies[index];
+    }
+    /**
+     * Returns index of face name from the array of face names available in 
+     * this GraphicsEnvironment or -1 if no face name was found. Default return 
+     * value is -1, method must be overridden by FontManager implementation.
+     * 
+     * @param faceName font face name which index is to be searched
+     */
+    public int getFaceIndex(String faceName){
+        return -1;
+    }
+
+    public abstract String[] getAllFamilies();
+
+    public abstract Font[] getAllFonts();
+    
+    /**
+     * Class contains SoftReference instance that can be stored in the 
+     * Hashtable by means of key field corresponding to it.
+     */
+    private class HashMapReference extends SoftReference<FontPeer> {
+        
+        /**
+         * The key for Hashtable.
+         */
+        private final String key;
+
+        /**
+         * Creates a new soft reference with the key specified and 
+         * adding this reference in the reference queue specified.
+         *
+         * @param key the key in Hashtable
+         * @param value object that corresponds to the key
+         * @param queue reference queue where reference is to be added 
+         */
+        public HashMapReference(final String key, final FontPeer value,
+                              final ReferenceQueue<FontPeer> queue) {
+            super(value, queue);
+            this.key = key;
+        }
+
+        /**
+         * Returns the key that corresponds to the SoftReference instance 
+         *
+         * @return the key in Hashtable with cached references
+         */
+        public Object getKey() {
+            return key;
+        }
+    }
+
+    /**
+     * Removes keys from the Hashtable with font peers which corresponding 
+     * HashMapReference objects were garbage collected.
+     */
+    private void updateFontsTable() {
+        HashMapReference r;
+        //???AWT
+        //while ((r = (HashMapReference)queue.poll()) != null) {
+        //    fontsTable.remove(r.getKey());
+        //}
+    }
+
+}
+
+
diff --git a/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java b/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java
new file mode 100644
index 0000000..7783317
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java
@@ -0,0 +1,282 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+//import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+
+import android.graphics.Paint;
+
+/**
+ * FontMetrics implementation
+ */
+
+public class FontMetricsImpl extends FontMetrics {
+
+	private static final long serialVersionUID = 844695615201925138L;
+
+	// ascent of the font
+	private int ascent;
+
+	// descent of the font
+	private int descent;
+
+	// leading of the font
+	private int leading;
+
+	// maximum ascent of the font
+	private int maxAscent;
+
+	// maximum descent of the font
+	private int maxDescent;
+
+	// maximum advance of the font
+	private int maxAdvance;
+
+	// array of char advance widths
+	private int[] widths = new int[256];
+
+	// font peer corresponding to this FontPeerImpl
+	private transient FontPeerImpl peer;
+
+	// X scale parameter of the font transform
+	private float scaleX = 1;
+
+	public AndroidGraphics2D mSg;
+
+	private Font mFn;
+
+	// Y scale parameter of the font transform
+	private float scaleY = 1;
+
+	/**
+	 * Creates new FontMericsImpl object described by the specified Font.
+	 * 
+	 * @param fnt
+	 *            the specified Font object
+	 */
+	public FontMetricsImpl(Font fnt) {
+		super(fnt);
+		this.mFn = fnt;
+		
+		mSg = AndroidGraphics2D.getInstance();
+		Paint p = mSg.getAndroidPaint();
+		
+		this.ascent = (int)-p.ascent();
+		this.descent = (int)p.descent();
+		this.leading = p.getFontMetricsInt().leading;
+		
+		AffineTransform at = fnt.getTransform();
+		if (!at.isIdentity()) {
+			scaleX = (float) at.getScaleX();
+			scaleY = (float) at.getScaleY();
+		}
+				
+	    /*
+	     * metrics[5] - strikethrough thickness<p>
+	     * -metrics[6] - strikethrough offset<p>
+	     * metrics[7] - maximum char width<p>
+	     * metrics[8] - ascent in pixels<p>
+	     * metrics[9] - descent in pixles<p>
+	     * metrics[10] - external leading in pixels<p>
+	     * metrics[11] - underline thickness in pixels<p>
+	     * -metrics[12] - underline offset in pixels<p>
+	     * metrics[13] - strikethrough thickness in pixels<p>
+	     * -metrics[14] - strikethrough offset in pixels<p>
+	     * metrics[15] - maximum char width in pixels<p>
+
+	     * @param _baselineData an array of 3 elements with baseline offsets metrics<p>
+	     * _baselineData[0] - roman baseline offset<p> 
+	     * _baselineData[1] - center baseline offset<p>
+	     * _baselineData[2] - hanging baseline offset<p>
+	     */
+	}
+
+
+	/**
+	 * Initialize the array of the first 256 chars' advance widths of the Font
+	 * describing this FontMetricsImpl object.
+	 */
+	private void initWidths() {
+
+		this.widths = new int[256];
+		for (int chr = 0; chr < 256; chr++) {
+			widths[chr] = (int) (getFontPeer().charWidth((char) chr) * scaleX);
+		}
+
+	}
+
+	/**
+	 * Returns the ascent of the Font describing this FontMetricsImpl object.
+	 */
+	@Override
+	public int getAscent() {
+		return this.ascent;
+	}
+
+	/**
+	 * Returns the descent of the Font describing this FontMetricsImpl object.
+	 */
+	@Override
+	public int getDescent() {
+		return this.descent;
+	}
+
+	/**
+	 * Returns the leading of the Font describing this FontMetricsImpl object.
+	 */
+	@Override
+	public int getLeading() {
+		return this.leading;
+	}
+
+	/**
+	 * Returns the advance width of the specified char of the Font describing
+	 * this FontMetricsImpl object.
+	 * 
+	 * @param ch
+	 *            the char which width is to be returned
+	 * @return the advance width of the specified char of the Font describing
+	 *         this FontMetricsImpl object
+	 */
+	@Override
+	public int charWidth(int ch) {
+		if (ch < 256) {
+			return widths[ch];
+		}
+
+		return getFontPeer().charWidth((char) ch);
+	}
+
+	/**
+	 * Returns the advance width of the specified char of the Font describing
+	 * this FontMetricsImpl object.
+	 * 
+	 * @param ch
+	 *            the char which width is to be returned
+	 * @return the advance width of the specified char of the Font describing
+	 *         this FontMetricsImpl object
+	 */
+	@Override
+	public int charWidth(char ch) {
+		if (ch < 256) {
+			return widths[ch];
+		}
+		return (int) (getFontPeer().charWidth(ch) * scaleX);
+	}
+
+	/**
+	 * Returns the maximum advance of the Font describing this FontMetricsImpl
+	 * object.
+	 */
+	@Override
+	public int getMaxAdvance() {
+		return this.maxAdvance;
+	}
+
+	/**
+	 * Returns the maximum ascent of the Font describing this FontMetricsImpl
+	 * object.
+	 */
+	@Override
+	public int getMaxAscent() {
+		return this.maxAscent;
+	}
+
+	/**
+	 * Returns the maximum descent of the Font describing this FontMetricsImpl
+	 * object.
+	 */
+	@SuppressWarnings("deprecation")
+	@Deprecated
+	@Override
+	public int getMaxDecent() {
+		return this.maxDescent;
+	}
+
+	/**
+	 * Returns the maximum descent of the Font describing this FontMetricsImpl
+	 * object.
+	 */
+	@Override
+	public int getMaxDescent() {
+		return this.maxDescent;
+	}
+
+	/**
+	 * Returns the advance widths of the first 256 characters in the Font
+	 * describing this FontMetricsImpl object.
+	 */
+	@Override
+	public int[] getWidths() {
+		return this.widths;
+	}
+
+	/**
+	 * Returns the total advance width of the specified string in the metrics of
+	 * the Font describing this FontMetricsImpl object.
+	 * 
+	 * @param str
+	 *            the String which width is to be measured
+	 * @return the total advance width of the specified string in the metrics of
+	 *         the Font describing this FontMetricsImpl object
+	 */
+	@Override
+	public int stringWidth(String str) {
+
+		int width = 0;
+		char chr;
+
+		for (int i = 0; i < str.length(); i++) {
+			chr = str.charAt(i);
+			width += charWidth(chr);
+		}
+		return width;
+
+		/*
+		 * float res = 0; int ln = str.length(); char[] c = new char[ln]; float[] f =
+		 * new float[ln]; str.getChars(0, ln, c, 0); mSg.getPaint().getTextWidths(c, 0,
+		 * ln, f);
+		 * 
+		 * for(int i = 0; i < f.length; i++) { res += f[i]; } return (int)res;
+		 */
+	}
+
+	/**
+	 * Returns FontPeer implementation of the Font describing this
+	 * FontMetricsImpl object.
+	 * 
+	 * @return a FontPeer object, that is the platform dependent FontPeer
+	 *         implementation for the Font describing this FontMetricsImpl
+	 *         object.
+	 */
+	@SuppressWarnings("deprecation")
+	public FontPeerImpl getFontPeer() {
+		if (peer == null) {
+			peer = (FontPeerImpl) font.getPeer();
+		}
+		return peer;
+	}
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java b/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java
new file mode 100644
index 0000000..14ff997
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java
@@ -0,0 +1,499 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+
+import com.android.internal.awt.AndroidGraphics2D;
+import com.android.internal.awt.AndroidGraphicsFactory;
+
+import java.awt.Graphics2D;
+import java.awt.Toolkit;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.peer.FontPeer;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+import android.graphics.Paint;
+
+/**
+ * Abstract class for platform dependent peer implementation of the Font class.
+ */
+public abstract class FontPeerImpl implements FontPeer{
+
+    // ascent of this font peer (in pixels)
+    int ascent;
+
+    // descent of this font peer (in pixels)
+    int descent;
+
+    // leading of this font peer (in pixels) 
+    int leading;
+
+    // logical maximum advance of this font peer (in pixels)
+    int maxAdvance;
+
+    // the height of this font peer
+    float height;
+
+    // the style of this font peer
+    int style;
+
+    // the point size of this font peer (in pixels)
+    int size;
+
+    // the logical hight of this font peer (in pixels)
+    int logicalHeight;
+
+    // the name of this font peer
+    String name;
+
+    // family name of this font peer
+    String fontFamilyName;
+
+    // the Face name of this font peer
+    String faceName;
+
+    // bounds rectanlge of the largest character in this font peer
+    Rectangle2D maxCharBounds;
+
+    // italic angle value of this font peer
+    float italicAngle = 0.0f;
+
+    // the number of glyphs supported by this font peer
+    int numGlyphs = 0;
+
+    // native font handle
+    long pFont;
+
+    // cached line metrics object
+    LineMetricsImpl nlm;
+
+    // the postscript name of this font peer
+    String psName = null;
+
+    /**
+     * Default glyph index, that is used, when the desired glyph
+     * is unsupported in this Font.
+     */
+    public char defaultChar = (char)0xFFFF;
+
+    /**
+     * Uniform LineMetrics flag, that is false for CompositeFont.  
+     * Default value is true.
+     */
+    boolean uniformLM = true;
+
+    /**
+     * Flag of the type of this Font that is indicate is the Font
+     * has TrueType or Type1 type. Default value is FONT_TYPE_UNDEF. 
+     */
+    int fontType = FontManager.FONT_TYPE_UNDEF;
+
+    /**
+     * Flag if this Font was created from stream, 
+     * this parameter used in finilize method.
+     */ 
+    private boolean createdFromStream = false;  
+    
+    // temorary Font file name, if this FontPeerImpl was created from InputStream 
+    private String tempFontFileName = null;     
+    
+    // cached FontExtraMetrics object related to this font peer
+    FontExtraMetrics extraMetrix = null;
+
+    public abstract FontExtraMetrics getExtraMetrics();
+    
+    /**
+     * Returns LineMetrics object with specified parameters
+     * @param str specified String
+     * @param frc specified render context
+     * @param at specified affine transform
+     * @return
+     */
+    public abstract LineMetrics getLineMetrics(String str, FontRenderContext frc, AffineTransform at);
+
+    /**
+     * Returns postscript name of the font.  
+     */
+    public abstract String getPSName();
+    
+	//private Graphics2D g = ((AndroidGraphicsFactory)Toolkit.getDefaultToolkit().getGraphicsFactory()).getGraphics2D();
+    //private Graphics2D g = AndroidGraphics2D.getInstance();
+
+    /**
+     * Set postscript name of the font to the specified parameter.  
+     */
+    public void setPSName(String name){
+        this.psName = name;
+    }
+    
+    /**
+     * Returns code of the missing glyph. 
+     */
+    public abstract int getMissingGlyphCode();
+
+    /**
+     * Returns Glyph representation of the given char.
+     * @param ch specified char
+     */
+    public abstract Glyph getGlyph(char ch);
+
+    /**
+     * Disposes nesessary resources.
+     */
+    public abstract void dispose();
+
+    /**
+     * Returns Glyph represeting missing char. 
+     */
+    public abstract Glyph getDefaultGlyph();
+
+    /**
+     * Returns true if this FontPeerImpl can display the specified char
+     */
+    public abstract boolean canDisplay(char c);
+
+    /**
+     * Returns family name of the font in specified locale settings.
+     * @param l specified Locale
+     */
+    public String getFamily(Locale l){
+        return this.getFamily();
+    }
+
+    /**
+     * Sets family name of the font in specified locale settings.
+     */
+    public void setFamily(String familyName){
+        this.fontFamilyName = familyName;
+    }
+
+    /**
+     * Returns face name of the font in specified locale settings.
+     * @param l specified Locale
+     */
+    public String getFontName(Locale l){
+        return this.getFontName();
+    }
+
+    /**
+     * Sets font name of the font in specified locale settings.
+     */
+    public void setFontName(String fontName){
+        this.faceName = fontName;
+    }
+
+    /**
+     * Returns true, if this font peer was created from InputStream, false otherwise.
+     * In case of creating fonts from InputStream some font peer implementations 
+     * may need to free temporary resources.
+     */
+    public boolean isCreatedFromStream(){
+        return this.createdFromStream;
+    }
+
+    /**
+     * Sets createdFromStream flag to the specified parameter.
+     * If parameter is true it means font peer was created from InputStream.
+     * 
+     * @param value true, if font peer was created from InputStream 
+     */
+    public void setCreatedFromStream(boolean value){
+        this.createdFromStream = value;
+    }
+
+    /**
+     * Returns font file name of this font.
+     */
+    public String getTempFontFileName(){
+        return this.tempFontFileName;
+    }
+
+    /**
+     * Sets font file name of this font to the specified one.
+     * @param value String representing font file name
+     */
+    public void setFontFileName(String value){
+        this.tempFontFileName = value;
+    }
+
+    /**
+     * Returns the advance width of the specified char of this FontPeerImpl.
+     * Note, if glyph is absent in the font's glyphset - returned value 
+     * is the advance of the deafualt glyph. For escape-chars returned 
+     * width value is 0.
+     * 
+     * @param ch the char which width is to be returned
+     * @return the advance width of the specified char of this FontPeerImpl
+     */
+    public int charWidth(char ch) {
+    	Paint p;
+    	AndroidGraphics2D g = AndroidGraphics2D.getInstance();
+    	if(g == null) {
+    		throw new RuntimeException("AndroidGraphics2D not instantiated!");
+    	}
+   		p = ((AndroidGraphics2D)g).getAndroidPaint();
+   		char[] ca = {ch};
+   		float[] fa = new float[1];
+   		p.getTextWidths(ca, 0, 1, fa);
+   		return (int)fa[0];
+    }
+
+    /**
+     * Returns the advance width of the specified char of this FontPeerImpl.
+     * 
+     * @param ind the char which width is to be returned
+     * @return the advance width of the specified char of this FontPeerImpl
+     */
+    public int charWidth(int ind) {
+        return charWidth((char)ind);
+    }
+
+    /**
+     * Returns an array of Glyphs that represent characters from the specified 
+     * Unicode range.
+     * 
+     * @param uFirst start position in Unicode range
+     * @param uLast end position in Unicode range
+     * @return
+     */
+    public Glyph[] getGlyphs(char uFirst, char uLast) {
+
+        char i = uFirst;
+        int len = uLast - uFirst;
+        ArrayList<Glyph> lst = new ArrayList<Glyph>(len);
+
+        if (size < 0) {
+            // awt.09=min range bound value is greater than max range bound
+            throw new IllegalArgumentException(Messages.getString("awt.09")); //$NON-NLS-1$
+        }
+
+        while (i < uLast) {
+            lst.add(this.getGlyph(i));
+        }
+
+        return (Glyph[]) lst.toArray();
+    }
+
+    /**
+     * Returns an array of Glyphs representing given array of chars.
+     * 
+     * @param chars specified array of chars
+     */
+    public Glyph[] getGlyphs(char[] chars) {
+        if (chars == null){
+            return null;
+        }
+
+        Glyph[] result = new Glyph[chars.length];
+
+        for (int i = 0; i < chars.length; i++) {
+            result[i] = this.getGlyph(chars[i]);
+        }
+        return result;
+    }
+
+    /**
+     * Returns an array of Glyphs representing given string.
+     * 
+     * @param str specified string
+     */
+    public Glyph[] getGlyphs(String str) {
+        char[] chars = str.toCharArray();
+        return this.getGlyphs(chars);
+    }
+
+    /**
+     * Returns family name of this FontPeerImpl.
+     */
+    public String getFamily() {
+        return fontFamilyName;
+    }
+
+    /**
+     * Returns face name of this FontPeerImpl.
+     */
+    public String getFontName() {
+        if (this.fontType == FontManager.FONT_TYPE_T1){
+            return this.fontFamilyName;
+        }
+
+        return faceName;
+    }
+
+    /**
+     * Returns height of this font peer in pixels. 
+     */
+    public int getLogicalHeight() {
+        return logicalHeight;
+    }
+
+    /**
+     * Sets height of this font peer in pixels to the given value.
+     * 
+     * @param newHeight new height in pixels value
+     */
+    public void setLogicalHeight(int newHeight) {
+        logicalHeight = newHeight;
+    }
+
+    /**
+     * Returns font size. 
+     */
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * Returns font style. 
+     */
+    public int getStyle() {
+        return style;
+    }
+
+    /**
+     * Returns font name. 
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the bounds of the largest char in this FontPeerImpl in 
+     * specified render context.
+     * 
+     * @param frc specified FontRenderContext
+     */
+    public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
+        return maxCharBounds;
+    }
+
+    /**
+     * Returns the number of glyphs in this FontPeerImpl.
+     */
+    public int getNumGlyphs() {
+        return  numGlyphs;
+    }
+
+    /**
+     * Returns tangens of the italic angle of this FontPeerImpl.
+     * If the FontPeerImpl has TrueType font type, italic angle value can be 
+     * calculated as (CharSlopeRun / CharSlopeRise) in terms of GDI.
+     */
+    public float getItalicAngle() {
+        return italicAngle;
+    }
+
+    /**
+     * Returns height of this font peer. 
+     */
+    public float getHeight(){
+        return height;
+    }
+
+    /**
+     * Returns cached LineMetrics object of this font peer. 
+     */
+    public LineMetrics getLineMetrics(){
+        return nlm;
+    }
+
+    /**
+     * Returns native font handle of this font peer. 
+     */
+    public long getFontHandle(){
+        return pFont;
+    }
+
+    /**
+     * Returns ascent of this font peer. 
+     */
+    public int getAscent(){
+    	Paint p;
+    	AndroidGraphics2D g = AndroidGraphics2D.getInstance();
+    	if(g == null) {
+    		throw new RuntimeException("AndroidGraphics2D not instantiated!");
+    	}
+   		p = ((AndroidGraphics2D)g).getAndroidPaint();
+   		return (int)p.ascent();
+        //return ascent;
+    }
+
+    /**
+     * Returns descent of this font peer. 
+     */
+    public int getDescent(){
+        return descent;
+    }
+
+    /**
+     * Returns leading of this font peer. 
+     */
+    public int getLeading(){
+        return leading;
+    }
+
+    /**
+     * Returns true if this font peer has uniform line metrics. 
+     */
+    public boolean hasUniformLineMetrics(){
+        return uniformLM;
+    }
+
+    /**
+     * Returns type of this font.
+     *  
+     * @return one of constant font type values. 
+     */    
+    public int getFontType(){
+        return fontType;
+    }
+
+    /**
+     * Sets new font type to the font object.
+     * 
+     * @param newType new type value
+     */
+    public void setFontType(int newType){
+        if (newType == FontManager.FONT_TYPE_T1 || newType == FontManager.FONT_TYPE_TT){
+            fontType = newType;
+        }
+    }
+
+    /**
+     * Sets new font type to the font object.
+     * 
+     * @param newType new type value
+     */
+    @Override
+    protected void finalize() throws Throwable {
+      super.finalize();
+      
+      dispose();
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontProperty.java b/awt/org/apache/harmony/awt/gl/font/FontProperty.java
new file mode 100644
index 0000000..4eb7cbb
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontProperty.java
@@ -0,0 +1,106 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+
+/**
+ * Class containing font property information. This information can be found 
+ * in font.property files. See API documentation, logical fonts description part. 
+ *
+ */
+public class FontProperty {
+
+    // font file name 
+    String fileName = null;
+    
+    // name of the encoding to be used 
+    String encoding = null;
+    
+    // array of exclusion ranges (pairs of low and high unicode exclusion bounds)
+    int[] exclRange = null;
+    
+    // font face name
+    String name = null;
+    
+    // font style
+    int style = -1;
+
+    /**
+     * Returns font style of this font property. 
+     */
+    public int getStyle(){
+        return this.style;
+    }
+
+    /**
+     * Returns font name of this font property. 
+     */
+    public String getName(){
+        return this.name;
+    }
+
+    /**
+     * Returns encoding used in this font property. 
+     */
+    public String getEncoding(){
+        return this.encoding;
+    }
+    
+    /**
+     * Returns an array of exclusion ranges. This array contain pairs of 
+     * low and high bounds of the intervals of characters to ignore in 
+     * total Unicode characters range.   
+     */
+    public int[] getExclusionRange(){
+        return this.exclRange;
+    }
+
+    /**
+     * Returns file name of the font that is described by this font property. 
+     */
+    public String getFileName(){
+        return this.fileName;
+    }
+
+    /**
+     * Returns true if specified character covered by exclusion ranges of this 
+     * font property, false otherwise.
+     * 
+     * @param ch specified char to check
+     */
+    public boolean isCharExcluded(char ch){
+        if (exclRange == null ){
+            return false;
+        }
+
+        for (int i = 0; i < exclRange.length;){
+            int lb = exclRange[i++];
+            int hb = exclRange[i++];
+
+            if (ch >= lb && ch <= hb){
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/Glyph.java b/awt/org/apache/harmony/awt/gl/font/Glyph.java
new file mode 100644
index 0000000..44b8809
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/Glyph.java
@@ -0,0 +1,236 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Shape;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+import java.awt.image.BufferedImage;
+
+public abstract class Glyph{
+
+    // character of the glyph
+    char glChar;
+    
+    // precise glyph metrics
+    GlyphMetrics glMetrics;
+    
+    // glyph metrics in pixels
+    GlyphMetrics glPointMetrics;
+    
+    //  glyph code of this Glyph
+    int glCode;
+    
+    // justification info of this glyph
+    GlyphJustificationInfo glJustInfo;
+    
+    // native font handle of the font corresponding to this glyph
+    long pFont;
+    
+    // size of the font corresponding to this glyph
+    int fontSize;
+    
+    // bitmap representation of the glyph
+    byte[] bitmap = null;
+    
+    // Buffered image representation of the glyph
+    BufferedImage image;
+    
+    // shape that representing the outline of this glyph
+    Shape glOutline = null;
+
+    /**
+     * image bitmap parameters
+     */
+    
+    //  top side bearing
+    public int bmp_top = 0;
+    
+    // left side bearing
+    public int bmp_left = 0;
+
+    // number of bytes in row
+    public int bmp_pitch;
+    
+    // number of rows
+    public int bmp_rows;
+    
+    // width of the row
+    public int bmp_width;
+
+    /**
+     *  Retruns handle to Native Font object
+     */
+    public long getPFont(){
+        return this.pFont;
+    }
+
+    /**
+     *  Retruns char value of this glyph object
+     */
+    public char getChar(){
+        return glChar;
+    }
+
+    /**
+     *  Retruns precise width of this glyph object
+     */
+    public int getWidth(){
+        return Math.round((float)glMetrics.getBounds2D().getWidth());
+    }
+
+    /**
+     *  Retruns precise height of this glyph object
+     */
+    public int getHeight(){
+        return Math.round((float)glMetrics.getBounds2D().getHeight());
+    }
+
+    /**
+     *  Retruns glyph code of this glyph object
+     */
+    public int getGlyphCode(){
+        return glCode;
+    }
+
+    /**
+     *  Retruns GlyphMetrics of this glyph object with precise metrics.
+     */
+    public GlyphMetrics getGlyphMetrics(){
+        return glMetrics;
+    }
+
+    /**
+     *  Retruns GlyphMetrics of this glyph object in pixels.
+     */
+    public GlyphMetrics getGlyphPointMetrics(){
+        return glPointMetrics;
+    }
+
+    /**
+     *  Retruns GlyphJustificationInfo of this glyph object
+     */
+    public GlyphJustificationInfo getGlyphJustificationInfo(){
+        return glJustInfo;
+    }
+
+    /**
+     *  Sets JustificationInfo of this glyph object
+     * 
+     * @param newJustInfo GlyphJustificationInfo object to set to the Glyph object 
+     */
+    public void setGlyphJustificationInfo(GlyphJustificationInfo newJustInfo){
+        this.glJustInfo = newJustInfo;
+    }
+
+    /**
+     * Returns an int array of 3 elements, so-called ABC structure that contains 
+     * the width of the character:
+     * 1st element = left side bearing of the glyph
+     * 2nd element = width of the glyph
+     * 3d element = right side bearing of the glyph 
+     */
+    public int[] getABC(){
+        int[] abc = new int[3];
+        abc[0] = (int)glMetrics.getLSB();
+        abc[1] = (int)glMetrics.getBounds2D().getWidth();
+        abc[2] = (int)glMetrics.getRSB();
+
+        return abc;
+    }
+
+    /**
+     * Sets BufferedImage representation of this glyph to the specified parameter.
+     * 
+     * @param newImage new BufferedImage object to be set as BufferedImage 
+     * representation.
+     */
+    public void setImage(BufferedImage newImage){
+        this.image = newImage;
+    }
+
+    /**
+     * Returns true if this Glyph and specified object are equal.
+     */
+    @Override
+    public boolean equals(Object obj){
+         if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+          try {
+            Glyph gl = (Glyph)obj;
+
+            return  ((this.getChar() == gl.getChar())
+              && (this.getGlyphMetrics().equals(gl.getGlyphMetrics()))
+              && (this.getGlyphCode() == gl.getGlyphCode()));
+          } catch (ClassCastException e) {
+          }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns height of the glyph in points. 
+     */
+    public int getPointHeight(){
+        return (int)glPointMetrics.getBounds2D().getHeight();
+    }
+
+    /**
+     * Returns width of the glyph in points. 
+     */
+    public int getPointWidth(){
+        return (int)glPointMetrics.getBounds2D().getWidth();
+    }
+
+    public Shape getShape(){
+        if (glOutline == null){
+            glOutline = initOutline(this.glChar);
+        }
+        return glOutline;
+    }
+
+    /**
+     * Sets BufferedImage representation of this glyph.
+     */
+    public BufferedImage getImage(){
+        //!! Implementation classes must override this method
+        return null;
+    }
+
+    /**
+     *  Returns array of bytes, representing image of this glyph
+     */
+    public abstract byte[] getBitmap();
+
+    /**
+     * Returns shape that represents outline of the specified character. 
+     * 
+     * @param c specified character
+     */
+    public abstract Shape initOutline(char c);
+
+}
+
+
diff --git a/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java b/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java
new file mode 100644
index 0000000..370146d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java
@@ -0,0 +1,412 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.LineMetrics;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ *
+ * LineMetrics implementation class.
+ */
+
+public class LineMetricsImpl extends LineMetrics implements Cloneable{
+
+    // array of baseline offsets
+    float[] baselineOffsets;
+
+    // the number of characters to measure
+    int numChars;
+
+    // baseline index of the font corresponding to this line metrics
+    int baseLineIndex;
+
+    // underline thickness
+    float underlineThickness;
+
+    // underline offset
+    float underlineOffset;
+
+    // strikethrough thickness
+    float strikethroughThickness;
+
+    // strikethrough offset
+    float strikethroughOffset;
+
+    // External leading
+    float leading;
+
+    // Height of the font ( == (ascent+descent+leading))
+    float height;
+
+    // Ascent of the font
+    float ascent;
+
+    // Descent of the font
+    float descent;
+
+    // Width of the widest char in the font
+    float maxCharWidth;
+
+    // underline thickness (in pixels)
+    int lUnderlineThickness;
+
+    // underline offset (in pixels)
+    int lUnderlineOffset;
+
+    // strikethrough thickness (in pixels)
+    int lStrikethroughThickness;
+
+    // strikethrough offset (in pixels)
+    int lStrikethroughOffset;
+
+    // External leading (in pixels)
+    int lLeading;
+
+    // Height of the font ( == (ascent+descent+leading)) (in pixels)
+    int lHeight;
+
+    // Ascent of the font (in pixels)
+    int lAscent;
+    
+    // Descent of the font (in pixels)
+    int lDescent;
+
+    //  Width of the widest char in the font (in pixels)
+    int lMaxCharWidth;
+
+    // units per EM square in font value
+    int units_per_EM = 0;
+
+    /**
+     * Creates LineMetricsImpl object from specified parameters. If baseline data parameter
+     * is null than {0, (-ascent+descent)/2, -ascent} values are used for baseline offsets.
+     *  
+     * @param len a number of characters 
+     * @param metrics an array of 16 elements with metrics values that can be 
+     * initialized in native code.<p>
+     * metrics[0] - ascent<p>
+     * metrics[1] - descent<p>
+     * metrics[2] - external leading<p>
+     * metrics[3] - underline thickness<p>
+     * -metrics[4] - underline offset<p>
+     * metrics[5] - strikethrough thickness<p>
+     * -metrics[6] - strikethrough offset<p>
+     * metrics[7] - maximum char width<p>
+     * metrics[8] - ascent in pixels<p>
+     * metrics[9] - descent in pixles<p>
+     * metrics[10] - external leading in pixels<p>
+     * metrics[11] - underline thickness in pixels<p>
+     * -metrics[12] - underline offset in pixels<p>
+     * metrics[13] - strikethrough thickness in pixels<p>
+     * -metrics[14] - strikethrough offset in pixels<p>
+     * metrics[15] - maximum char width in pixels<p>
+
+     * @param _baselineData an array of 3 elements with baseline offsets metrics<p>
+     * _baselineData[0] - roman baseline offset<p> 
+     * _baselineData[1] - center baseline offset<p>
+     * _baselineData[2] - hanging baseline offset<p>
+     */
+    public LineMetricsImpl(int len, float[] metrics, float[] _baselineData){
+        numChars = len;
+
+        ascent = metrics[0];    // Ascent of the font
+        descent = metrics[1];   // Descent of the font
+        leading = metrics[2];  // External leading
+        height = metrics[0] + metrics[1] + metrics[2];  // Height of the font ( == (ascent + descent + leading))
+    }
+
+    /**
+     * Creates LineMetricsImpl object from specified parameters. If baseline data parameter
+     * is null than {0, (-ascent+descent)/2, -ascent} values are used for baseline offsets.
+     *  
+     * @param _numChars number of chars 
+     * @param _baseLineIndex index of the baseline offset
+     * @param _baselineOffsets an array of baseline offsets
+     * @param _underlineThickness underline thickness
+     * @param _underlineOffset underline offset
+     * @param _strikethroughThickness strikethrough thickness
+     * @param _strikethroughOffset strinkethrough offset
+     * @param _leading leading of the font
+     * @param _height font height
+     * @param _ascent ascent of the font
+     * @param _descent descent of the font
+     * @param _maxCharWidth max char width
+     */
+    public LineMetricsImpl(int _numChars, int _baseLineIndex,
+            float[] _baselineOffsets, float _underlineThickness,
+            float _underlineOffset, float _strikethroughThickness,
+            float _strikethroughOffset, float _leading, float _height,
+            float _ascent, float _descent, float _maxCharWidth) {
+
+        numChars = _numChars;
+        baseLineIndex = _baseLineIndex;
+        underlineThickness = _underlineThickness;
+        underlineOffset = _underlineOffset;
+        strikethroughThickness = _strikethroughThickness;
+        strikethroughOffset = _strikethroughOffset;
+        leading = _leading;
+        height = _height;
+        ascent = _ascent;
+        descent = _descent;
+        baselineOffsets = _baselineOffsets;
+        lUnderlineThickness = (int) underlineThickness;
+        lUnderlineOffset = (int) underlineOffset;
+        lStrikethroughThickness = (int) strikethroughThickness;
+        lStrikethroughOffset = (int) strikethroughOffset;
+        lLeading = (int) leading;
+        lHeight = (int) height;
+        lAscent = (int) ascent;
+        lDescent = (int) descent;
+        maxCharWidth = _maxCharWidth;
+    }
+
+    public LineMetricsImpl(){
+
+    }
+
+    /**
+     * All metrics are scaled according to scaleX and scaleY values. 
+     * This function helps to recompute metrics according to the scale factors
+     * of desired AffineTransform.
+     * 
+     * @param scaleX scale X factor
+     * @param scaleY scale Y factor
+     */
+    public void scale(float scaleX, float scaleY){
+        float absScaleX = Math.abs(scaleX);
+        float absScaleY = Math.abs(scaleY);
+
+        underlineThickness *= absScaleY;
+        underlineOffset *= scaleY;
+        strikethroughThickness *= absScaleY;
+        strikethroughOffset *= scaleY;
+        leading *= absScaleY;
+        height *= absScaleY;
+        ascent *= absScaleY;
+        descent *= absScaleY;
+
+        if(baselineOffsets == null) {
+            getBaselineOffsets();
+        }
+
+        for (int i=0; i< baselineOffsets.length; i++){
+            baselineOffsets[i] *= scaleY;
+        }
+
+        lUnderlineThickness *= absScaleY;
+        lUnderlineOffset *= scaleY;
+        lStrikethroughThickness *= absScaleY;
+        lStrikethroughOffset *= scaleY;
+        lLeading  *= absScaleY;
+        lHeight *= absScaleY;
+        lAscent *= absScaleY;
+        lDescent *= absScaleY;
+        maxCharWidth *= absScaleX;
+
+    }
+
+
+    /**
+     * Returns offset of the baseline.
+     */
+    @Override
+    public float[] getBaselineOffsets() {
+        // XXX: at the moment there only horizontal metrics are taken into
+        // account. If there is no baseline information in TrueType font
+        // file default values used: {0, -ascent, (-ascent+descent)/2}
+
+        return baselineOffsets;
+    }
+
+    /**
+     * Returns a number of chars in specified text
+     */
+    @Override
+    public int getNumChars() {
+        return numChars;
+    }
+
+    /**
+     * Returns index of the baseline, one of predefined constants.
+     */
+    @Override
+    public int getBaselineIndex() {
+        // Baseline index is the deafult baseline index value
+        // taken from the TrueType table "BASE".
+        return baseLineIndex;
+    }
+
+    /**
+     * Returns thickness of the Underline.
+     */
+    @Override
+    public float getUnderlineThickness() {
+        return underlineThickness;
+    }
+
+    /**
+     * Returns offset of the Underline.
+     */
+    @Override
+    public float getUnderlineOffset() {
+        return underlineOffset;
+    }
+
+    /**
+     * Returns thickness of the Strikethrough line.
+     */
+    @Override
+    public float getStrikethroughThickness() {
+        return strikethroughThickness;
+    }
+
+    /**
+     * Returns offset of the Strikethrough line.
+     */
+    @Override
+    public float getStrikethroughOffset() {
+        return strikethroughOffset;
+    }
+
+    /**
+     * Returns the leading.
+     */
+    @Override
+    public float getLeading() {
+        return leading;
+    }
+
+    /**
+     * Returns the height of the font.
+     */
+    @Override
+    public float getHeight() {
+        //return height; // equals to (ascent + descent + leading);
+    	return ascent + descent + leading;
+    }
+
+    /**
+     * Returns the descent.
+     */
+    @Override
+    public float getDescent() {
+        return descent;
+    }
+
+    /**
+     * Returns the ascent.
+     */
+    @Override
+    public float getAscent() {
+        return ascent;
+    }
+
+    /**
+     * Returns logical thickness of the Underline.
+     */
+    public int getLogicalUnderlineThickness() {
+        return lUnderlineThickness;
+    }
+
+    /**
+     * Returns logical offset of the Underline.
+     */
+    public int getLogicalUnderlineOffset() {
+        return lUnderlineOffset;
+    }
+
+    /**
+     * Returns logical thickness of the Strikethrough line.
+     */
+    public int getLogicalStrikethroughThickness() {
+        return lStrikethroughThickness;
+    }
+
+    /**
+     * Returns logical offset of the Strikethrough line.
+     */
+    public int getLogicalStrikethroughOffset() {
+        return lStrikethroughOffset;
+    }
+
+    /**
+     * Returns the logical leading.
+     */
+    public int getLogicalLeading() {
+        return lLeading;
+    }
+
+    /**
+     * Returns the logical height of the font.
+     */
+    public int getLogicalHeight() {
+        return lHeight; // equals to (ascent + descent + leading);
+    }
+
+    /**
+     * Returns the logical descent.
+     */
+    public int getLogicalDescent() {
+        return lDescent;
+    }
+
+    /**
+     * Returns the logical ascent.
+     */
+    public int getLogicalAscent() {
+        return lAscent;
+    }
+
+    /**
+     * Returns the logical size of the widest char.
+     */
+    public int getLogicalMaxCharWidth() {
+        return lMaxCharWidth;
+    }
+
+    /**
+     * Returns the size of the widest char.
+     */
+    public float getMaxCharWidth() {
+        return maxCharWidth;
+    }
+
+    /**
+     * Set num chars to the desired value.
+     * 
+     * @param num specified number of chars
+     */
+    public void setNumChars(int num){
+        numChars = num;
+    }
+
+    @Override
+    public Object clone(){
+        try{
+            return super.clone();
+        }catch (CloneNotSupportedException e){
+            return null;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/font/TextDecorator.java b/awt/org/apache/harmony/awt/gl/font/TextDecorator.java
new file mode 100644
index 0000000..81905fd
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextDecorator.java
@@ -0,0 +1,433 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.font.TextAttribute;
+import java.awt.geom.Area;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.Map;
+
+/**
+ * This class is responsible for rendering text decorations like
+ * underline, strikethrough, text with background, etc.
+ */
+public class TextDecorator {
+    private static final TextDecorator inst = new TextDecorator();
+    private TextDecorator() {}
+    static TextDecorator getInstance() {
+        return inst;
+    }
+
+    /**
+     * This class encapsulates a set of decoration attributes for a single text run.
+     */
+    static class Decoration {
+        private static final BasicStroke UNDERLINE_LOW_ONE_PIXEL_STROKE =
+                new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10);
+
+        private static final BasicStroke UNDERLINE_LOW_TWO_PIXEL_STROKE =
+                new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10);
+
+        private static final BasicStroke UNDERLINE_LOW_DOTTED_STROKE =
+                new BasicStroke(
+                        1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
+                        new float[] { 1, 1 }, 0
+                );
+
+        private static final BasicStroke UNDERLINE_LOW_DOTTED_STROKE2 =
+                new BasicStroke(
+                        1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
+                        new float[] { 1, 1 }, 1
+                );
+
+        private static final BasicStroke UNDERLINE_LOW_DASHED_STROKE =
+                new BasicStroke(
+                        1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
+                        new float[] { 4, 4 }, 0
+                );
+
+        boolean ulOn = false; // Have standard underline?
+        BasicStroke ulStroke;
+
+        BasicStroke imUlStroke;  // Stroke for INPUT_METHOD_UNDERLINE
+        BasicStroke imUlStroke2; // Specially for UNDERLINE_LOW_GRAY
+
+        boolean strikeThrough;
+        BasicStroke strikeThroughStroke;
+
+        boolean haveStrokes = false; // Strokes already created?
+
+        boolean swapBfFg;
+        Paint bg; // background color
+        Paint fg; // foreground color
+
+        Paint graphicsPaint; // Slot for saving current paint
+
+        Decoration(
+                Integer imUl,
+                boolean swap,
+                boolean sth,
+                Paint bg, Paint fg,
+                boolean ulOn) {
+
+            if (imUl != null) {
+                // Determine which stroke to use
+                if (imUl == TextAttribute.UNDERLINE_LOW_ONE_PIXEL) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_ONE_PIXEL_STROKE;
+                } else if (imUl == TextAttribute.UNDERLINE_LOW_TWO_PIXEL) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_TWO_PIXEL_STROKE;
+                } else if (imUl == TextAttribute.UNDERLINE_LOW_DOTTED) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_DOTTED_STROKE;
+                } else if (imUl == TextAttribute.UNDERLINE_LOW_GRAY) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_DOTTED_STROKE;
+                    this.imUlStroke2 = Decoration.UNDERLINE_LOW_DOTTED_STROKE2;
+                } else if (imUl == TextAttribute.UNDERLINE_LOW_DASHED) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_DASHED_STROKE;
+                }
+            }
+
+            this.ulOn = ulOn; // Has underline
+            this.swapBfFg = swap;
+            this.strikeThrough = sth;
+            this.bg = bg;
+            this.fg = fg;
+        }
+
+        /**
+         * Creates strokes of proper width according to the info
+         * stored in the BasicMetrics
+         * @param metrics - basic metrics
+         */
+        private void getStrokes(BasicMetrics metrics) {
+            if (!haveStrokes) {
+                if (strikeThrough) {
+                    strikeThroughStroke =
+                            new BasicStroke(
+                                    metrics.strikethroughThickness,
+                                    BasicStroke.CAP_BUTT,
+                                    BasicStroke.JOIN_MITER,
+                                    10
+                            );
+                }
+
+                if (ulOn) {
+                    ulStroke =
+                            new BasicStroke(
+                                    metrics.underlineThickness,
+                                    BasicStroke.CAP_BUTT,
+                                    BasicStroke.JOIN_MITER,
+                                    10
+                            );
+                }
+
+                haveStrokes = true;
+            }
+        }
+    }
+
+    /**
+     * Creates Decoration object from the set of text attributes
+     * @param attributes - text attributes
+     * @return Decoration object
+     */
+    static Decoration getDecoration(Map<? extends Attribute, ?> attributes) {
+        if (attributes == null) {
+            return null; // It is for plain text
+        }
+
+        Object underline = attributes.get(TextAttribute.UNDERLINE);
+        boolean hasStandardUnderline = underline == TextAttribute.UNDERLINE_ON;
+
+        Object imUnderline = attributes.get(TextAttribute.INPUT_METHOD_UNDERLINE);
+        Integer imUl = (Integer) imUnderline;
+
+        boolean swapBgFg =
+                TextAttribute.SWAP_COLORS_ON.equals(
+                        attributes.get(TextAttribute.SWAP_COLORS)
+                );
+
+        boolean strikeThrough =
+                TextAttribute.STRIKETHROUGH_ON.equals(
+                        attributes.get(TextAttribute.STRIKETHROUGH)
+                );
+
+        Paint fg = (Paint) attributes.get(TextAttribute.FOREGROUND);
+        Paint bg = (Paint) attributes.get(TextAttribute.BACKGROUND);
+
+        if (
+                !hasStandardUnderline &&
+                imUnderline == null &&
+                fg == null &&
+                bg == null &&
+                !swapBgFg &&
+                !strikeThrough
+        ) {
+            return null;
+        }
+        return new Decoration(imUl, swapBgFg, strikeThrough, bg, fg, hasStandardUnderline);
+    }
+
+    /**
+     * Fills the background before drawing if needed.
+     * 
+     * @param trs - text segment
+     * @param g2d - graphics to draw to
+     * @param xOffset - offset in X direction to the upper left corner of the
+     *        layout from the origin of the graphics
+     * @param yOffset - offset in Y direction to the upper left corner of the
+     *        layout from the origin of the graphics
+     */
+    static void prepareGraphics(
+            TextRunSegment trs, Graphics2D g2d,
+            float xOffset, float yOffset
+    ) {
+        Decoration d = trs.decoration;
+
+        if (d.fg == null && d.bg == null && d.swapBfFg == false) {
+            return; // Nothing to do
+        }
+
+        d.graphicsPaint = g2d.getPaint();
+
+        if (d.fg == null) {
+            d.fg = d.graphicsPaint;
+        }
+
+        if (d.swapBfFg) {
+            // Fill background area
+            g2d.setPaint(d.fg);
+            Rectangle2D bgArea = trs.getLogicalBounds();
+            Rectangle2D toFill =
+                    new Rectangle2D.Double(
+                            bgArea.getX() + xOffset,
+                            bgArea.getY() + yOffset,
+                            bgArea.getWidth(),
+                            bgArea.getHeight()
+                    );
+            g2d.fill(toFill);
+
+            // Set foreground color
+            g2d.setPaint(d.bg == null ? Color.WHITE : d.bg);
+        } else {
+            if (d.bg != null) { // Fill background area
+                g2d.setPaint(d.bg);
+                Rectangle2D bgArea = trs.getLogicalBounds();
+                Rectangle2D toFill =
+                        new Rectangle2D.Double(
+                                bgArea.getX() + xOffset,
+                                bgArea.getY() + yOffset,
+                                bgArea.getWidth(),
+                                bgArea.getHeight()
+                        );
+                g2d.fill(toFill);
+            }
+
+            // Set foreground color
+            g2d.setPaint(d.fg);
+        }
+    }
+
+    /**
+     * Restores the original state of the graphics if needed
+     * @param d - decoration
+     * @param g2d - graphics
+     */
+    static void restoreGraphics(Decoration d, Graphics2D g2d) {
+        if (d.fg == null && d.bg == null && d.swapBfFg == false) {
+            return; // Nothing to do
+        }
+
+        g2d.setPaint(d.graphicsPaint);
+    }
+
+    /**
+     * Renders the text decorations
+     * @param trs - text run segment
+     * @param g2d - graphics to render to
+     * @param xOffset - offset in X direction to the upper left corner
+     * of the layout from the origin of the graphics
+     * @param yOffset - offset in Y direction to the upper left corner
+     * of the layout from the origin of the graphics
+     */
+    static void drawTextDecorations(
+            TextRunSegment trs, Graphics2D g2d,
+            float xOffset, float yOffset
+    ) {
+        Decoration d = trs.decoration;
+
+        if (!d.ulOn && d.imUlStroke == null && !d.strikeThrough) {
+            return; // Nothing to do
+        }
+
+        float left = xOffset + (float) trs.getLogicalBounds().getMinX();
+        float right = xOffset + (float) trs.getLogicalBounds().getMaxX();
+
+        Stroke savedStroke = g2d.getStroke();
+
+        d.getStrokes(trs.metrics);
+
+        if (d.strikeThrough) {
+            float y = trs.y + yOffset + trs.metrics.strikethroughOffset;
+            g2d.setStroke(d.strikeThroughStroke);
+            g2d.draw(new Line2D.Float(left, y, right, y));
+        }
+
+        if (d.ulOn) {
+            float y = trs.y + yOffset + trs.metrics.underlineOffset;
+            g2d.setStroke(d.ulStroke);
+            g2d.draw(new Line2D.Float(left, y, right, y));
+        }
+
+        if (d.imUlStroke != null) {
+            float y = trs.y + yOffset + trs.metrics.underlineOffset;
+            g2d.setStroke(d.imUlStroke);
+            g2d.draw(new Line2D.Float(left, y, right, y));
+            if (d.imUlStroke2 != null) {
+                y++;
+                g2d.setStroke(d.imUlStroke2);
+                g2d.draw(new Line2D.Float(left, y, right, y));
+            }
+        }
+
+        g2d.setStroke(savedStroke);
+    }
+
+    /**
+     * Extends the visual bounds of the text run segment to
+     * include text decorations.
+     * @param trs - text segment
+     * @param segmentBounds - bounds of the undecorated text
+     * @param d - decoration
+     * @return extended bounds
+     */
+    static Rectangle2D extendVisualBounds(
+            TextRunSegment trs,
+            Rectangle2D segmentBounds,
+            Decoration d
+    ) {
+        if (d == null) {
+            return segmentBounds;
+        }
+        double minx = segmentBounds.getMinX();
+        double miny = segmentBounds.getMinY();
+        double maxx = segmentBounds.getMaxX();
+        double maxy = segmentBounds.getMaxY();
+
+        Rectangle2D lb = trs.getLogicalBounds();
+
+        if (d.swapBfFg || d.bg != null) {
+            minx = Math.min(lb.getMinX() - trs.x, minx);
+            miny = Math.min(lb.getMinY() - trs.y, miny);
+            maxx = Math.max(lb.getMaxX() - trs.x, maxx);
+            maxy = Math.max(lb.getMaxY() - trs.y, maxy);
+        }
+
+        if (d.ulOn || d.imUlStroke != null || d.strikeThrough) {
+            minx = Math.min(lb.getMinX() - trs.x, minx);
+            maxx = Math.max(lb.getMaxX() - trs.x, maxx);
+
+            d.getStrokes(trs.metrics);
+
+            if (d.ulStroke != null) {
+                maxy = Math.max(
+                        maxy,
+                        trs.metrics.underlineOffset +
+                        d.ulStroke.getLineWidth()
+                );
+            }
+
+            if (d.imUlStroke != null) {
+                maxy = Math.max(
+                        maxy,
+                        trs.metrics.underlineOffset +
+                        d.imUlStroke.getLineWidth() +
+                        (d.imUlStroke2 == null ? 0 : d.imUlStroke2.getLineWidth())
+                );
+            }
+        }
+
+        return new Rectangle2D.Double(minx, miny, maxx-minx, maxy-miny);
+    }
+
+    /**
+     * Extends the outline of the text run segment to
+     * include text decorations.
+     * @param trs - text segment
+     * @param segmentOutline - outline of the undecorated text
+     * @param d - decoration
+     * @return extended outline
+     */
+    static Shape extendOutline(
+            TextRunSegment trs,
+            Shape segmentOutline,
+            Decoration d
+    ) {
+        if (d == null || !d.ulOn && d.imUlStroke == null && !d.strikeThrough) {
+            return segmentOutline; // Nothing to do
+        }
+
+        Area res = new Area(segmentOutline);
+
+        float left = (float) trs.getLogicalBounds().getMinX() - trs.x;
+        float right = (float) trs.getLogicalBounds().getMaxX() - trs.x;
+
+        d.getStrokes(trs.metrics);
+
+        if (d.strikeThrough) {
+            float y = trs.metrics.strikethroughOffset;
+            res.add(new Area(d.strikeThroughStroke.createStrokedShape(
+                    new Line2D.Float(left, y, right, y)
+            )));
+        }
+
+        if (d.ulOn) {
+            float y = trs.metrics.underlineOffset;
+            res.add(new Area(d.ulStroke.createStrokedShape(
+                    new Line2D.Float(left, y, right, y)
+            )));
+        }
+
+        if (d.imUlStroke != null) {
+            float y = trs.metrics.underlineOffset;
+            res.add(new Area(d.imUlStroke.createStrokedShape(
+                    new Line2D.Float(left, y, right, y)
+            )));
+
+            if (d.imUlStroke2 != null) {
+                y++;
+                res.add(new Area(d.imUlStroke2.createStrokedShape(
+                        new Line2D.Float(left, y, right, y)
+                )));
+            }
+        }
+
+        return res;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java b/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java
new file mode 100644
index 0000000..be5762a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java
@@ -0,0 +1,209 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.LineMetrics;
+import java.awt.font.GraphicAttribute;
+import java.awt.Font;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class operates with an arbitrary text string which can include
+ * any number of style, font and direction runs. It is responsible for computation
+ * of the text metrics, such as ascent, descent, leading and advance. Actually,
+ * each text run segment contains logic which allows it to compute its own metrics and
+ * responsibility of this class is to combine metrics for all segments included in the text,
+ * managed by the associated TextRunBreaker object.
+ */
+public class TextMetricsCalculator {
+    TextRunBreaker breaker; // Associated run breaker
+
+    // Metrics
+    float ascent = 0;
+    float descent = 0;
+    float leading = 0;
+    float advance = 0;
+
+    private float baselineOffsets[];
+    int baselineIndex;
+
+    public TextMetricsCalculator(TextRunBreaker breaker) {
+        this.breaker = breaker;
+        checkBaselines();
+    }
+
+    /**
+     * Returns either values cached by checkBaselines method or reasonable
+     * values for the TOP and BOTTOM alignments.
+     * @param baselineIndex - baseline index
+     * @return baseline offset
+     */
+    float getBaselineOffset(int baselineIndex) {
+        if (baselineIndex >= 0) {
+            return baselineOffsets[baselineIndex];
+        } else if (baselineIndex == GraphicAttribute.BOTTOM_ALIGNMENT) {
+            return descent;
+        } else if (baselineIndex == GraphicAttribute.TOP_ALIGNMENT) {
+            return -ascent;
+        } else {
+            // awt.3F=Invalid baseline index
+            throw new IllegalArgumentException(Messages.getString("awt.3F")); //$NON-NLS-1$
+        }
+    }
+
+    public float[] getBaselineOffsets() {
+        float ret[] = new float[baselineOffsets.length];
+        System.arraycopy(baselineOffsets, 0, ret, 0, baselineOffsets.length);
+        return ret;
+    }
+
+    /**
+     * Take baseline offsets from the first font or graphic attribute
+     * and normalizes them, than caches the results.
+     */
+    public void checkBaselines() {
+        // Take baseline offsets of the first font and normalize them
+        HashMap<Integer, Font> fonts = breaker.fonts;
+
+        Object val = fonts.get(new Integer(0));
+
+        if (val instanceof Font) {
+            Font firstFont = (Font) val;
+            LineMetrics lm = firstFont.getLineMetrics(breaker.text, 0, 1, breaker.frc);
+            baselineOffsets = lm.getBaselineOffsets();
+            baselineIndex = lm.getBaselineIndex();
+        } else if (val instanceof GraphicAttribute) {
+            // Get first graphic attribute and use it
+            GraphicAttribute ga = (GraphicAttribute) val;
+
+            int align = ga.getAlignment();
+
+            if (
+                    align == GraphicAttribute.TOP_ALIGNMENT ||
+                    align == GraphicAttribute.BOTTOM_ALIGNMENT
+            ) {
+                baselineIndex = GraphicAttribute.ROMAN_BASELINE;
+            } else {
+                baselineIndex = align;
+            }
+
+            baselineOffsets = new float[3];
+            baselineOffsets[0] = 0;
+            baselineOffsets[1] = (ga.getDescent() - ga.getAscent()) / 2.f;
+            baselineOffsets[2] = -ga.getAscent();
+        } else { // Use defaults - Roman baseline and zero offsets
+            baselineIndex = GraphicAttribute.ROMAN_BASELINE;
+            baselineOffsets = new float[3];
+        }
+
+        // Normalize offsets if needed
+        if (baselineOffsets[baselineIndex] != 0) {
+            float baseOffset = baselineOffsets[baselineIndex];
+            for (int i = 0; i < baselineOffsets.length; i++) {
+                baselineOffsets[i] -= baseOffset;
+            }
+        }
+    }
+
+    /**
+     * Computes metrics for the text managed by the associated TextRunBreaker
+     */
+    void computeMetrics() {
+
+        ArrayList<TextRunSegment> segments = breaker.runSegments;
+
+        float maxHeight = 0;
+        float maxHeightLeading = 0;
+
+        for (int i = 0; i < segments.size(); i++) {
+            TextRunSegment segment = segments.get(i);
+            BasicMetrics metrics = segment.metrics;
+            int baseline = metrics.baseLineIndex;
+
+            if (baseline >= 0) {
+                float baselineOffset = baselineOffsets[metrics.baseLineIndex];
+                float fixedDescent = metrics.descent + baselineOffset;
+
+                ascent = Math.max(ascent, metrics.ascent - baselineOffset);
+                descent = Math.max(descent, fixedDescent);
+                leading = Math.max(leading, fixedDescent + metrics.leading);
+            } else { // Position is not fixed by the baseline, need sum of ascent and descent
+                float height = metrics.ascent + metrics.descent;
+
+                maxHeight = Math.max(maxHeight, height);
+                maxHeightLeading = Math.max(maxHeightLeading, height + metrics.leading);
+            }
+        }
+
+        // Need to increase sizes for graphics?
+        if (maxHeightLeading != 0) {
+            descent = Math.max(descent, maxHeight - ascent);
+            leading = Math.max(leading, maxHeightLeading - ascent);
+        }
+
+        // Normalize leading
+        leading -= descent;
+
+        BasicMetrics currMetrics;
+        float currAdvance = 0;
+
+        for (int i = 0; i < segments.size(); i++) {
+            TextRunSegment segment = segments.get(breaker.getSegmentFromVisualOrder(i));
+            currMetrics = segment.metrics;
+
+            segment.y = getBaselineOffset(currMetrics.baseLineIndex)
+                    + currMetrics.superScriptOffset;
+            segment.x = currAdvance;
+
+            currAdvance += segment.getAdvance();
+        }
+
+        advance = currAdvance;
+    }
+
+    /**
+     * Computes metrics and creates BasicMetrics object from them
+     * @return basic metrics
+     */
+    public BasicMetrics createMetrics() {
+        computeMetrics();
+        return new BasicMetrics(this);
+    }
+
+    /**
+     * Corrects advance after justification. Gets BasicMetrics object
+     * and updates advance stored into it.
+     * @param metrics - metrics with outdated advance which should be corrected 
+     */
+    public void correctAdvance(BasicMetrics metrics) {
+        ArrayList<TextRunSegment> segments = breaker.runSegments;
+        TextRunSegment segment = segments.get(breaker
+                .getSegmentFromVisualOrder(segments.size() - 1));
+
+        advance = segment.x + segment.getAdvance();
+        metrics.advance = advance;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java b/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java
new file mode 100644
index 0000000..be606f7
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java
@@ -0,0 +1,861 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
+import java.awt.im.InputMethodHighlight;
+import java.awt.font.*;
+import java.awt.*;
+import java.text.AttributedCharacterIterator;
+import java.text.Annotation;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.*;
+
+import org.apache.harmony.awt.gl.font.TextDecorator.Decoration;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+// TODO - bidi not implemented yet
+
+/**
+ * This class is responsible for breaking the text into the run segments
+ * with constant font, style, other text attributes and direction.
+ * It also stores the created text run segments and covers functionality
+ * related to the operations on the set of segments, like calculating metrics,
+ * rendering, justification, hit testing, etc.
+ */
+public class TextRunBreaker implements Cloneable {
+    AttributedCharacterIterator aci;
+    FontRenderContext frc;
+
+    char[] text;
+
+    byte[] levels;
+
+    HashMap<Integer, Font> fonts;
+    HashMap<Integer, Decoration> decorations;
+
+    // Related to default font substitution
+    int forcedFontRunStarts[];
+
+    ArrayList<TextRunSegment> runSegments = new ArrayList<TextRunSegment>();
+
+    // For fast retrieving of the segment containing
+    // character with known logical index
+    int logical2segment[];
+    int segment2visual[]; // Visual order of segments TODO - implement
+    int visual2segment[];
+    int logical2visual[];
+    int visual2logical[];
+
+    SegmentsInfo storedSegments;
+    private boolean haveAllSegments = false;
+    int segmentsStart, segmentsEnd;
+
+    float justification = 1.0f;
+
+    public TextRunBreaker(AttributedCharacterIterator aci, FontRenderContext frc) {
+        this.aci = aci;
+        this.frc = frc;
+
+        segmentsStart = aci.getBeginIndex();
+        segmentsEnd = aci.getEndIndex();
+
+        int len = segmentsEnd - segmentsStart;
+        text = new char[len];
+        aci.setIndex(segmentsEnd);
+        while (len-- != 0) { // Going in backward direction is faster? Simplier checks here?
+            text[len] = aci.previous();
+        }
+
+        createStyleRuns();
+    }
+
+    /**
+     * Visual order of text segments may differ from the logical order.
+     * This method calculates visual position of the segment from its logical position.
+     * @param segmentNum - logical position of the segment
+     * @return visual position of the segment
+     */
+    int getVisualFromSegmentOrder(int segmentNum) {
+        return (segment2visual == null) ? segmentNum : segment2visual[segmentNum];
+    }
+
+    /**
+     * Visual order of text segments may differ from the logical order.
+     * This method calculates logical position of the segment from its visual position.
+     * @param visual - visual position of the segment
+     * @return logical position of the segment
+     */
+    int getSegmentFromVisualOrder(int visual) {
+        return (visual2segment == null) ? visual : visual2segment[visual];
+    }
+
+    /**
+     * Visual order of the characters may differ from the logical order.
+     * This method calculates visual position of the character from its logical position.
+     * @param logical - logical position of the character
+     * @return visual position
+     */
+    int getVisualFromLogical(int logical) {
+        return (logical2visual == null) ? logical : logical2visual[logical];
+    }
+
+    /**
+     * Visual order of the characters may differ from the logical order.
+     * This method calculates logical position of the character from its visual position.
+     * @param visual - visual position
+     * @return logical position
+     */
+    int getLogicalFromVisual(int visual) {
+        return (visual2logical == null) ? visual : visual2logical[visual];
+    }
+
+    /**
+     * Calculates the end index of the level run, limited by the given text run.
+     * @param runStart - run start
+     * @param runEnd - run end
+     * @return end index of the level run
+     */
+    int getLevelRunLimit(int runStart, int runEnd) {
+        if (levels == null) {
+            return runEnd;
+        }
+        int endLevelRun = runStart + 1;
+        byte level = levels[runStart];
+
+        while (endLevelRun <= runEnd && levels[endLevelRun] == level) {
+            endLevelRun++;
+        }
+
+        return endLevelRun;
+    }
+
+    /**
+     * Adds InputMethodHighlight to the attributes
+     * @param attrs - text attributes
+     * @return patched text attributes
+     */
+    Map<? extends Attribute, ?> unpackAttributes(Map<? extends Attribute, ?> attrs) {
+        if (attrs.containsKey(TextAttribute.INPUT_METHOD_HIGHLIGHT)) {
+            Map<TextAttribute, ?> styles = null;
+
+            Object val = attrs.get(TextAttribute.INPUT_METHOD_HIGHLIGHT);
+
+            if (val instanceof Annotation) {
+                val = ((Annotation) val).getValue();
+            }
+
+            if (val instanceof InputMethodHighlight) {
+                InputMethodHighlight ihl = ((InputMethodHighlight) val);
+                styles = ihl.getStyle();
+
+                if (styles == null) {
+                    Toolkit tk = Toolkit.getDefaultToolkit();
+                    styles = tk.mapInputMethodHighlight(ihl);
+                }
+            }
+
+            if (styles != null) {
+                HashMap<Attribute, Object> newAttrs = new HashMap<Attribute, Object>();
+                newAttrs.putAll(attrs);
+                newAttrs.putAll(styles);
+                return newAttrs;
+            }
+        }
+
+        return attrs;
+    }
+
+    /**
+     * Breaks the text into separate style runs.
+     */
+    void createStyleRuns() {
+        // TODO - implement fast and simple case
+        fonts = new HashMap<Integer, Font>();
+        decorations = new HashMap<Integer, Decoration>();
+        ////
+
+        ArrayList<Integer> forcedFontRunStartsList = null;
+
+        Map<? extends Attribute, ?> attributes = null;
+
+        // Check justification attribute
+        Object val = aci.getAttribute(TextAttribute.JUSTIFICATION);
+        if (val != null) {
+            justification = ((Float) val).floatValue();
+        }
+
+        for (
+            int index = segmentsStart, nextRunStart = segmentsStart;
+            index < segmentsEnd;
+            index = nextRunStart, aci.setIndex(index)
+           )  {
+            nextRunStart = aci.getRunLimit();
+            attributes = unpackAttributes(aci.getAttributes());
+
+            TextDecorator.Decoration d = TextDecorator.getDecoration(attributes);
+            decorations.put(new Integer(index), d);
+
+            // Find appropriate font or place GraphicAttribute there
+
+            // 1. Try to pick up CHAR_REPLACEMENT (compatibility)
+            Font value = (Font)attributes.get(TextAttribute.CHAR_REPLACEMENT);
+
+            if (value == null) {
+                // 2. Try to Get FONT
+                value = (Font)attributes.get(TextAttribute.FONT);
+
+                if (value == null) {
+                    // 3. Try to create font from FAMILY
+                    if (attributes.get(TextAttribute.FAMILY) != null) {
+                        value = Font.getFont(attributes);
+                    }
+
+                    if (value == null) {
+                        // 4. No attributes found, using default.
+                        if (forcedFontRunStartsList == null) {
+                            forcedFontRunStartsList = new ArrayList<Integer>();
+                        }
+                        FontFinder.findFonts(
+                                text,
+                                index,
+                                nextRunStart,
+                                forcedFontRunStartsList,
+                                fonts
+                        );
+                        value = fonts.get(new Integer(index));
+                    }
+                }
+            }
+
+            fonts.put(new Integer(index), value);
+        }
+
+        // We have added some default fonts, so we have some extra runs in text
+        if (forcedFontRunStartsList != null) {
+            forcedFontRunStarts = new int[forcedFontRunStartsList.size()];
+            for (int i=0; i<forcedFontRunStartsList.size(); i++) {
+                forcedFontRunStarts[i] =
+                        forcedFontRunStartsList.get(i).intValue();
+            }
+        }
+    }
+
+    /**
+     * Starting from the current position looks for the end of the text run with
+     * constant text attributes.
+     * @param runStart - start position
+     * @param maxPos - position where to stop if no run limit found
+     * @return style run limit
+     */
+    int getStyleRunLimit(int runStart, int maxPos) {
+        try {
+            aci.setIndex(runStart);
+        } catch(IllegalArgumentException e) { // Index out of bounds
+            if (runStart < segmentsStart) {
+                aci.first();
+            } else {
+                aci.last();
+            }
+        }
+
+        // If we have some extra runs we need to check for their limits
+        if (forcedFontRunStarts != null) {
+            for (int element : forcedFontRunStarts) {
+                if (element > runStart) {
+                    maxPos = Math.min(element, maxPos);
+                    break;
+                }
+            }
+        }
+
+        return Math.min(aci.getRunLimit(), maxPos);
+    }
+
+    /**
+     * Creates segments for the text run with
+     * constant decoration, font and bidi level
+     * @param runStart - run start
+     * @param runEnd - run end
+     */
+    public void createSegments(int runStart, int runEnd) {
+        int endStyleRun, endLevelRun;
+
+        // TODO - update levels
+
+        int pos = runStart, levelPos;
+
+        aci.setIndex(pos);
+        final int firstRunStart = aci.getRunStart();
+        Object tdd = decorations.get(new Integer(firstRunStart));
+        Object fontOrGAttr = fonts.get(new Integer(firstRunStart));
+
+        logical2segment = new int[runEnd - runStart];
+
+        do {
+            endStyleRun = getStyleRunLimit(pos, runEnd);
+
+            // runStart can be non-zero, but all arrays will be indexed from 0
+            int ajustedPos = pos - runStart;
+            int ajustedEndStyleRun = endStyleRun - runStart;
+            levelPos = ajustedPos;
+            do {
+                endLevelRun = getLevelRunLimit(levelPos, ajustedEndStyleRun);
+
+                if (fontOrGAttr instanceof GraphicAttribute) {
+                    runSegments.add(
+                        new TextRunSegmentImpl.TextRunSegmentGraphic(
+                                (GraphicAttribute)fontOrGAttr,
+                                endLevelRun - levelPos,
+                                levelPos + runStart)
+                    );
+                    Arrays.fill(logical2segment, levelPos, endLevelRun, runSegments.size()-1);
+                } else {
+                    TextRunSegmentImpl.TextSegmentInfo i =
+                            new TextRunSegmentImpl.TextSegmentInfo(
+                                    levels == null ? 0 : levels[ajustedPos],
+                                    (Font) fontOrGAttr,
+                                    frc,
+                                    text,
+                                    levelPos + runStart,
+                                    endLevelRun + runStart
+                            );
+
+                    runSegments.add(
+                            new TextRunSegmentImpl.TextRunSegmentCommon(
+                                    i,
+                                    (TextDecorator.Decoration) tdd
+                            )
+                    );
+                    Arrays.fill(logical2segment, levelPos, endLevelRun, runSegments.size()-1);
+                }
+
+                levelPos = endLevelRun;
+            } while (levelPos < ajustedEndStyleRun);
+
+            // Prepare next iteration
+            pos = endStyleRun;
+            tdd = decorations.get(new Integer(pos));
+            fontOrGAttr = fonts.get(new Integer(pos));
+        } while (pos < runEnd);
+    }
+
+    /**
+     * Checks if text run segments are up to date and creates the new segments if not.
+     */
+    public void createAllSegments() {
+        if ( !haveAllSegments &&
+            (logical2segment == null ||
+             logical2segment.length != segmentsEnd - segmentsStart)
+        ) { // Check if we don't have all segments yet
+            resetSegments();
+            createSegments(segmentsStart, segmentsEnd);
+        }
+
+        haveAllSegments = true;
+    }
+
+    /**
+     * Calculates position where line should be broken without
+     * taking into account word boundaries.
+     * @param start - start index
+     * @param maxAdvance - maximum advance, width of the line
+     * @return position where to break
+     */
+    public int getLineBreakIndex(int start, float maxAdvance) {
+        int breakIndex;
+        TextRunSegment s = null;
+
+        for (
+                int segmentIndex = logical2segment[start];
+                segmentIndex < runSegments.size();
+                segmentIndex++
+           ) {
+            s = runSegments.get(segmentIndex);
+            breakIndex = s.getCharIndexFromAdvance(maxAdvance, start);
+
+            if (breakIndex < s.getEnd()) {
+                return breakIndex;
+            }
+            maxAdvance -= s.getAdvanceDelta(start, s.getEnd());
+            start = s.getEnd();
+        }
+
+        return s.getEnd();
+    }
+
+    /**
+     * Inserts character into the managed text.
+     * @param newParagraph - new character iterator
+     * @param insertPos - insertion position
+     */
+    public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
+        aci = newParagraph;
+
+        char insChar = aci.setIndex(insertPos);
+
+        Integer key = new Integer(insertPos);
+
+        insertPos -= aci.getBeginIndex();
+
+        char newText[] = new char[text.length + 1];
+        System.arraycopy(text, 0, newText, 0, insertPos);
+        newText[insertPos] = insChar;
+        System.arraycopy(text, insertPos, newText, insertPos+1, text.length - insertPos);
+        text = newText;
+
+        if (aci.getRunStart() == key.intValue() && aci.getRunLimit() == key.intValue() + 1) {
+            createStyleRuns(); // We have to create one new run, could be optimized
+        } else {
+            shiftStyleRuns(key, 1);
+        }
+
+        resetSegments();
+
+        segmentsEnd++;
+    }
+
+    /**
+     * Deletes character from the managed text.
+     * @param newParagraph - new character iterator
+     * @param deletePos - deletion position
+     */
+    public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
+        aci = newParagraph;
+
+        Integer key = new Integer(deletePos);
+
+        deletePos -= aci.getBeginIndex();
+
+        char newText[] = new char[text.length - 1];
+        System.arraycopy(text, 0, newText, 0, deletePos);
+        System.arraycopy(text, deletePos+1, newText, deletePos, newText.length - deletePos);
+        text = newText;
+
+        if (fonts.get(key) != null) {
+            fonts.remove(key);
+        }
+
+        shiftStyleRuns(key, -1);
+
+        resetSegments();
+
+        segmentsEnd--;
+    }
+
+    /**
+     * Shift all runs after specified position, needed to perfom insertion
+     * or deletion in the managed text
+     * @param pos - position where to start
+     * @param shift - shift, could be negative
+     */
+    private void shiftStyleRuns(Integer pos, final int shift) {
+        ArrayList<Integer> keys = new ArrayList<Integer>();
+
+        Integer key, oldkey;
+        for (Iterator<Integer> it = fonts.keySet().iterator(); it.hasNext(); ) {
+            oldkey = it.next();
+            if (oldkey.intValue() > pos.intValue()) {
+                keys.add(oldkey);
+            }
+        }
+
+        for (int i=0; i<keys.size(); i++) {
+            oldkey = keys.get(i);
+            key = new Integer(shift + oldkey.intValue());
+            fonts.put(key, fonts.remove(oldkey));
+            decorations.put(key, decorations.remove(oldkey));
+        }
+    }
+
+    /**
+     * Resets state of the class
+     */
+    private void resetSegments() {
+        runSegments = new ArrayList<TextRunSegment>();
+        logical2segment = null;
+        segment2visual = null;
+        visual2segment = null;
+        levels = null;
+        haveAllSegments = false;
+    }
+
+    private class SegmentsInfo {
+        ArrayList<TextRunSegment> runSegments;
+        int logical2segment[];
+        int segment2visual[];
+        int visual2segment[];
+        byte levels[];
+        int segmentsStart;
+        int segmentsEnd;
+    }
+
+    /**
+     * Saves the internal state of the class
+     * @param newSegStart - new start index in the text
+     * @param newSegEnd - new end index in the text
+     */
+    public void pushSegments(int newSegStart, int newSegEnd) {
+        storedSegments = new SegmentsInfo();
+        storedSegments.runSegments = this.runSegments;
+        storedSegments.logical2segment = this.logical2segment;
+        storedSegments.segment2visual = this.segment2visual;
+        storedSegments.visual2segment = this.visual2segment;
+        storedSegments.levels = this.levels;
+        storedSegments.segmentsStart = segmentsStart;
+        storedSegments.segmentsEnd = segmentsEnd;
+
+        resetSegments();
+
+        segmentsStart = newSegStart;
+        segmentsEnd = newSegEnd;
+    }
+
+    /**
+     * Restores the internal state of the class
+     */
+    public void popSegments() {
+        if (storedSegments == null) {
+            return;
+        }
+
+        this.runSegments = storedSegments.runSegments;
+        this.logical2segment = storedSegments.logical2segment;
+        this.segment2visual = storedSegments.segment2visual;
+        this.visual2segment = storedSegments.visual2segment;
+        this.levels = storedSegments.levels;
+        this.segmentsStart = storedSegments.segmentsStart;
+        this.segmentsEnd = storedSegments.segmentsEnd;
+        storedSegments = null;
+
+        if (runSegments.size() == 0 && logical2segment == null) {
+            haveAllSegments = false;
+        } else {
+            haveAllSegments = true;
+        }
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            TextRunBreaker res = (TextRunBreaker) super.clone();
+            res.storedSegments = null;
+            ArrayList<TextRunSegment> newSegments = new ArrayList<TextRunSegment>(runSegments.size());
+            for (int i = 0; i < runSegments.size(); i++) {
+                TextRunSegment seg =  runSegments.get(i);
+                newSegments.add((TextRunSegment)seg.clone());
+            }
+            res.runSegments = newSegments;
+            return res;
+        } catch (CloneNotSupportedException e) {
+            // awt.3E=Clone not supported
+            throw new UnsupportedOperationException(Messages.getString("awt.3E")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof TextRunBreaker)) {
+            return false;
+        }
+
+        TextRunBreaker br = (TextRunBreaker) obj;
+
+        if (br.getACI().equals(aci) && br.frc.equals(frc)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCode.combine(aci.hashCode(), frc.hashCode());
+    }
+
+    /**
+     * Renders the managed text
+     * @param g2d - graphics where to render
+     * @param xOffset - offset in X direction to the upper left corner
+     * of the layout from the origin of the graphics
+     * @param yOffset - offset in Y direction to the upper left corner
+     * of the layout from the origin of the graphics
+     */
+    public void drawSegments(Graphics2D g2d, float xOffset, float yOffset) {
+        for (int i=0; i<runSegments.size(); i++) {
+            runSegments.get(i).draw(g2d, xOffset, yOffset);
+        }
+    }
+
+    /**
+     * Creates the black box bounds shape
+     * @param firstEndpoint - start position
+     * @param secondEndpoint - end position
+     * @return black box bounds shape
+     */
+    public Shape getBlackBoxBounds(int firstEndpoint, int secondEndpoint) {
+        GeneralPath bounds = new GeneralPath();
+
+        TextRunSegment segment;
+
+        for (int idx = firstEndpoint; idx < secondEndpoint; idx=segment.getEnd()) {
+            segment = runSegments.get(logical2segment[idx]);
+            bounds.append(segment.getCharsBlackBoxBounds(idx, secondEndpoint), false);
+        }
+
+        return bounds;
+    }
+
+    /**
+     * Creates visual bounds shape
+     * @return visual bounds rectangle
+     */
+    public Rectangle2D getVisualBounds() {
+        Rectangle2D bounds = null;
+
+        for (int i=0; i<runSegments.size(); i++) {
+            TextRunSegment s = runSegments.get(i);
+            if (bounds != null) {
+                Rectangle2D.union(bounds, s.getVisualBounds(), bounds);
+            } else {
+                bounds = s.getVisualBounds();
+            }
+        }
+
+        return bounds;
+    }
+
+    /**
+     * Creates logical bounds shape
+     * @return logical bounds rectangle
+     */
+    public Rectangle2D getLogicalBounds() {
+        Rectangle2D bounds = null;
+
+        for (int i=0; i<runSegments.size(); i++) {
+            TextRunSegment s = runSegments.get(i);
+            if (bounds != null) {
+                Rectangle2D.union(bounds, s.getLogicalBounds(), bounds);
+            } else {
+                bounds = s.getLogicalBounds();
+            }
+        }
+
+        return bounds;
+    }
+
+    public int getCharCount() {
+        return segmentsEnd - segmentsStart;
+    }
+
+    public byte getLevel(int idx) {
+        if (levels == null) {
+            return 0;
+        }
+        return levels[idx];
+    }
+
+    public int getBaseLevel() {
+        return 0;
+    }
+
+    public boolean isLTR() {
+        return true;
+    }
+
+    public char getChar(int index) {
+        return text[index];
+    }
+
+    public AttributedCharacterIterator getACI() {
+        return aci;
+    }
+
+    /**
+     * Creates outline shape for the managed text
+     * @return outline
+     */
+    public GeneralPath getOutline() {
+        GeneralPath outline = new GeneralPath();
+
+        TextRunSegment segment;
+
+        for (int i = 0; i < runSegments.size(); i++) {
+            segment = runSegments.get(i);
+            outline.append(segment.getOutline(), false);
+        }
+
+        return outline;
+    }
+
+    /**
+     * Calculates text hit info from the screen coordinates.
+     * Current implementation totally ignores Y coordinate.
+     * If X coordinate is outside of the layout boundaries, this
+     * method returns leftmost or rightmost hit.
+     * @param x - x coordinate of the hit
+     * @param y - y coordinate of the hit
+     * @return hit info
+     */
+    public TextHitInfo hitTest(float x, float y) {
+        TextRunSegment segment;
+
+        double endOfPrevSeg = -1;
+        for (int i = 0; i < runSegments.size(); i++) {
+            segment = runSegments.get(i);
+            Rectangle2D bounds = segment.getVisualBounds();
+            if ((bounds.getMinX() <= x && bounds.getMaxX() >= x) || // We are in the segment
+               (endOfPrevSeg < x && bounds.getMinX() > x)) { // We are somewhere between the segments
+                return segment.hitTest(x,y);
+            }
+            endOfPrevSeg = bounds.getMaxX();
+        }
+
+        return isLTR() ? TextHitInfo.trailing(text.length) : TextHitInfo.leading(0);
+    }
+
+    public float getJustification() {
+        return justification;
+    }
+
+    /**
+     * Calculates position of the last non whitespace character
+     * in the managed text.
+     * @return position of the last non whitespace character
+     */
+    public int getLastNonWhitespace() {
+        int lastNonWhitespace = text.length;
+
+        while (lastNonWhitespace >= 0) {
+            lastNonWhitespace--;
+            if (!Character.isWhitespace(text[lastNonWhitespace])) {
+                break;
+            }
+        }
+
+        return lastNonWhitespace;
+    }
+
+    /**
+     * Performs justification of the managed text by changing segment positions
+     * and positions of the glyphs inside of the segments.
+     * @param gap - amount of space which should be compensated by justification
+     */
+    public void justify(float gap) {
+        // Ignore trailing logical whitespace
+        int firstIdx = segmentsStart;
+        int lastIdx = getLastNonWhitespace() + segmentsStart;
+        JustificationInfo jInfos[] = new JustificationInfo[5];
+        float gapLeft = gap;
+
+        int highestPriority = -1;
+        // GlyphJustificationInfo.PRIORITY_KASHIDA is 0
+        // GlyphJustificationInfo.PRIORITY_NONE is 3
+        for (int priority = 0; priority <= GlyphJustificationInfo.PRIORITY_NONE + 1; priority++) {
+            JustificationInfo jInfo = new JustificationInfo();
+            jInfo.lastIdx = lastIdx;
+            jInfo.firstIdx = firstIdx;
+            jInfo.grow = gap > 0;
+            jInfo.gapToFill = gapLeft;
+
+            if (priority <= GlyphJustificationInfo.PRIORITY_NONE) {
+                jInfo.priority = priority;
+            } else {
+                jInfo.priority = highestPriority; // Last pass
+            }
+
+            for (int i = 0; i < runSegments.size(); i++) {
+                TextRunSegment segment = runSegments.get(i);
+                if (segment.getStart() <= lastIdx) {
+                    segment.updateJustificationInfo(jInfo);
+                }
+            }
+
+            if (jInfo.priority == highestPriority) {
+                jInfo.absorb = true;
+                jInfo.absorbedWeight = jInfo.weight;
+            }
+
+            if (jInfo.weight != 0) {
+                if (highestPriority < 0) {
+                    highestPriority = priority;
+                }
+                jInfos[priority] = jInfo;
+            } else {
+                continue;
+            }
+
+            gapLeft -= jInfo.growLimit;
+
+            if (((gapLeft > 0) ^ jInfo.grow) || gapLeft == 0) {
+                gapLeft = 0;
+                jInfo.gapPerUnit = jInfo.gapToFill/jInfo.weight;
+                break;
+            }
+            jInfo.useLimits = true;
+
+            if (jInfo.absorbedWeight > 0) {
+                jInfo.absorb = true;
+                jInfo.absorbedGapPerUnit =
+                        (jInfo.gapToFill-jInfo.growLimit)/jInfo.absorbedWeight;
+                break;
+            }
+        }
+
+        float currJustificationOffset = 0;
+        for (int i = 0; i < runSegments.size(); i++) {
+            TextRunSegment segment =
+                    runSegments.get(getSegmentFromVisualOrder(i));
+            segment.x += currJustificationOffset;
+            currJustificationOffset += segment.doJustification(jInfos);
+        }
+
+        justification = -1; // Make further justification impossible
+    }
+
+    /**
+     * This class represents the information collected before the actual
+     * justification is started and needed to perform the justification.
+     * This information is closely related to the information stored in the
+     * GlyphJustificationInfo for the text represented by glyph vectors.
+     */
+    class JustificationInfo {
+        boolean grow;
+        boolean absorb = false;
+        boolean useLimits = false;
+        int priority = 0;
+        float weight = 0;
+        float absorbedWeight = 0;
+        float growLimit = 0;
+
+        int lastIdx;
+        int firstIdx;
+
+        float gapToFill;
+
+        float gapPerUnit = 0; // Precalculated value, gapToFill / weight
+        float absorbedGapPerUnit = 0; // Precalculated value, gapToFill / weight
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java b/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java
new file mode 100644
index 0000000..1cd2c05
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java
@@ -0,0 +1,165 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.font.TextHitInfo;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Abstract class which represents the segment of the text with constant attributes
+ * running in one direction (i.e. constant level).
+ */
+public abstract class TextRunSegment implements Cloneable {
+    float x; // Calculated x location of this segment on the screen
+    float y; // Calculated y location of this segment on the screen
+
+    BasicMetrics metrics; // Metrics of this text run segment
+    TextDecorator.Decoration decoration; // Underline, srikethrough, etc.
+    Rectangle2D logicalBounds = null; // Logical bounding box for the segment
+    Rectangle2D visualBounds = null; // Visual bounding box for the segment
+
+    /**
+     * Returns start index of the segment
+     * @return start index
+     */
+    abstract int getStart();
+
+    /**
+     * Returns end index of the segment
+     * @return end index
+     */
+    abstract int getEnd();
+
+    /**
+     * Returns the number of characters in the segment
+     * @return number of characters
+     */
+    abstract int getLength();
+
+    /**
+     * Renders this text run segment
+     * @param g2d - graphics to render to
+     * @param xOffset - X offset from the graphics origin to the
+     * origin of the text layout
+     * @param yOffset - Y offset from the graphics origin to the
+     * origin of the text layout
+     */
+    abstract void draw(Graphics2D g2d, float xOffset, float yOffset);
+
+    /**
+     * Creates black box bounds shape for the specified range
+     * @param start - range sart
+     * @param limit - range end
+     * @return black box bounds shape
+     */
+    abstract Shape getCharsBlackBoxBounds(int start, int limit);
+
+    /**
+     * Returns the outline shape
+     * @return outline
+     */
+    abstract Shape getOutline();
+
+    /**
+     * Returns visual bounds of this segment
+     * @return visual bounds
+     */
+    abstract Rectangle2D getVisualBounds();
+
+    /**
+     * Returns logical bounds of this segment
+     * @return logical bounds
+     */
+    abstract Rectangle2D getLogicalBounds();
+
+    /**
+     * Calculates advance of the segment
+     * @return advance
+     */
+    abstract float getAdvance();
+
+    /**
+     * Calculates advance delta between two characters
+     * @param start - 1st position
+     * @param end - 2nd position
+     * @return advance increment between specified positions
+     */
+    abstract float getAdvanceDelta(int start, int end);
+
+    /**
+     * Calculates index of the character which advance is equal to
+     * the given. If the given advance is greater then the segment
+     * advance it returns the position after the last character.
+     * @param advance - given advance
+     * @param start - character, from which to start measuring advance
+     * @return character index
+     */
+    abstract int getCharIndexFromAdvance(float advance, int start);
+
+    /**
+     * Checks if the character doesn't contribute to the text advance
+     * @param index - character index
+     * @return true if the character has zero advance
+     */
+    abstract boolean charHasZeroAdvance(int index);
+
+    /**
+     * Calculates position of the character on the screen
+     * @param index - character index
+     * @return X coordinate of the character position
+     */
+    abstract float getCharPosition(int index);
+
+    /**
+     * Returns the advance of the individual character
+     * @param index - character index
+     * @return character advance
+     */
+    abstract float getCharAdvance(int index);
+
+    /**
+     * Creates text hit info from the hit position
+     * @param x - X coordinate relative to the origin of the layout
+     * @param y - Y coordinate relative to the origin of the layout
+     * @return hit info
+     */
+    abstract TextHitInfo hitTest(float x, float y);
+
+    /**
+     * Collects justification information into JustificationInfo object
+     * @param jInfo - JustificationInfo object
+     */
+    abstract void updateJustificationInfo(TextRunBreaker.JustificationInfo jInfo);
+
+    /**
+     * Performs justification of the segment.
+     * Updates positions of individual characters.
+     * @param jInfos - justification information, gathered by the previous passes
+     * @return amount of growth or shrink of the segment
+     */    
+    abstract float doJustification(TextRunBreaker.JustificationInfo jInfos[]);
+
+    @Override
+    public abstract Object clone();
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java b/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java
new file mode 100644
index 0000000..0ec2d05
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java
@@ -0,0 +1,979 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.*;
+import java.awt.font.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+// XXX - TODO - bidi not implemented yet
+//import java.text.Bidi;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * Date: Apr 25, 2005
+ * Time: 4:33:18 PM
+ *
+ * This class contains the implementation of the behavior of the
+ * text run segment with constant text attributes and direction.
+ */
+public class TextRunSegmentImpl {
+
+    /**
+     * This class contains basic information required for creation
+     * of the glyph-based text run segment.
+     */
+    public static class TextSegmentInfo {
+        // XXX - TODO - bidi not implemented yet
+        //Bidi bidi;
+
+        Font font;
+        FontRenderContext frc;
+
+        char text[];
+
+        int start;
+        int end;
+        int length;
+
+        int flags = 0;
+
+        byte level = 0;
+
+        TextSegmentInfo(
+                byte level,
+                Font font, FontRenderContext frc,
+                char text[], int start, int end
+        ) {
+            this.font = font;
+            this.frc = frc;
+            this.text = text;
+            this.start = start;
+            this.end = end;
+            this.level = level;
+            length = end - start;
+        }
+    }
+
+    /**
+     * This class represents a simple text segment backed by the glyph vector
+     */
+    public static class TextRunSegmentCommon extends TextRunSegment {
+        TextSegmentInfo info;
+        private GlyphVector gv;
+        private float advanceIncrements[];
+        private int char2glyph[];
+        private GlyphJustificationInfo gjis[]; // Glyph justification info
+
+        TextRunSegmentCommon(TextSegmentInfo i, TextDecorator.Decoration d) {
+            // XXX - todo - check support bidi
+            i.flags &= ~0x09; // Clear bidi flags
+
+            if ((i.level & 0x1) != 0) {
+                i.flags |= Font.LAYOUT_RIGHT_TO_LEFT;
+            }
+
+            info = i;
+            this.decoration = d;
+
+            LineMetrics lm = i.font.getLineMetrics(i.text, i.start, i.end, i.frc);
+            this.metrics = new BasicMetrics(lm, i.font);
+
+            if (lm.getNumChars() != i.length) { // XXX todo - This should be handled
+                // awt.41=Font returned unsupported type of line metrics. This case is known, but not supported yet.
+                throw new UnsupportedOperationException(
+                        Messages.getString("awt.41")); //$NON-NLS-1$
+            }
+        }
+
+        @Override
+        public Object clone() {
+            return new TextRunSegmentCommon(info, decoration);
+        }
+
+        /**
+         * Creates glyph vector from the managed text if needed
+         * @return glyph vector
+         */
+        private GlyphVector getGlyphVector() {
+            if (gv==null) {
+                gv = info.font.layoutGlyphVector(
+                        info.frc,
+                        info.text,
+                        info.start,
+                        info.end - info.start, // NOTE: This parameter violates
+                                               // spec, it is count,
+                                               // not limit as spec states
+                        info.flags
+                );
+            }
+
+            return gv;
+        }
+
+        /**
+         * Renders this text run segment
+         * @param g2d - graphics to render to
+         * @param xOffset - X offset from the graphics origin to the
+         * origin of the text layout
+         * @param yOffset - Y offset from the graphics origin to the
+         * origin of the text layout
+         */
+        @Override
+        void draw(Graphics2D g2d, float xOffset, float yOffset) {
+            if (decoration == null) {
+                g2d.drawGlyphVector(getGlyphVector(), xOffset + x, yOffset + y);
+            } else {
+                TextDecorator.prepareGraphics(this, g2d, xOffset, yOffset);
+                g2d.drawGlyphVector(getGlyphVector(), xOffset + x, yOffset + y);
+                TextDecorator.drawTextDecorations(this, g2d, xOffset, yOffset);
+                TextDecorator.restoreGraphics(decoration, g2d);
+            }
+        }
+
+        /**
+         * Returns visual bounds of this segment
+         * @return visual bounds
+         */
+        @Override
+        Rectangle2D getVisualBounds() {
+            if (visualBounds == null) {
+                visualBounds =
+                        TextDecorator.extendVisualBounds(
+                                this,
+                                getGlyphVector().getVisualBounds(),
+                                decoration
+                        );
+
+                visualBounds.setRect(
+                        x + visualBounds.getX(),
+                        y + visualBounds.getY(),
+                        visualBounds.getWidth(),
+                        visualBounds.getHeight()
+                );
+            }
+
+            return (Rectangle2D) visualBounds.clone();
+        }
+
+        /**
+         * Returns logical bounds of this segment
+         * @return logical bounds
+         */
+        @Override
+        Rectangle2D getLogicalBounds() {
+            if (logicalBounds == null) {
+                logicalBounds = getGlyphVector().getLogicalBounds();
+
+                logicalBounds.setRect(
+                        x + logicalBounds.getX(),
+                        y + logicalBounds.getY(),
+                        logicalBounds.getWidth(),
+                        logicalBounds.getHeight()
+                );
+            }
+
+            return (Rectangle2D) logicalBounds.clone();
+        }
+
+        @Override
+        float getAdvance() {
+            return (float) getLogicalBounds().getWidth();
+        }
+
+        /**
+         * Attemts to map each character to the corresponding advance increment
+         */
+        void initAdvanceMapping() {
+            GlyphVector gv = getGlyphVector();
+            int charIndicies[] = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
+            advanceIncrements = new float[info.length];
+
+            for (int i=0; i<charIndicies.length; i++) {
+                advanceIncrements[charIndicies[i]] = gv.getGlyphMetrics(i).getAdvance();
+            }
+        }
+
+        /**
+         * Calculates advance delta between two characters
+         * @param start - 1st position
+         * @param end - 2nd position
+         * @return advance increment between specified positions
+         */
+        @Override
+        float getAdvanceDelta(int start, int end) {
+            // Get coordinates in the segment context
+            start -= info.start;
+            end -= info.start;
+
+            if (advanceIncrements == null) {
+                initAdvanceMapping();
+            }
+
+            if (start < 0) {
+                start = 0;
+            }
+            if (end > info.length) {
+                end = info.length;
+            }
+
+            float sum = 0;
+            for (int i=start; i<end; i++) {
+                sum += advanceIncrements[i];
+            }
+
+            return sum;
+        }
+
+        /**
+         * Calculates index of the character which advance is equal to
+         * the given. If the given advance is greater then the segment
+         * advance it returns the position after the last character.
+         * @param advance - given advance
+         * @param start - character, from which to start measuring advance
+         * @return character index
+         */
+        @Override
+        int getCharIndexFromAdvance(float advance, int start) {
+            // XXX - todo - probably, possible to optimize
+            // Add check if the given advance is greater then
+            // the segment advance in the beginning. In this case
+            // we don't need to run through all increments
+            if (advanceIncrements == null) {
+                initAdvanceMapping();
+            }
+
+            start -= info.start;
+
+            if (start < 0) {
+                start = 0;
+            }
+
+            int i = start;
+            for (; i<info.length; i++) {
+                advance -= advanceIncrements[i];
+                if (advance < 0) {
+                    break;
+                }
+            }
+
+            return i + info.start;
+        }
+
+        @Override
+        int getStart() {
+            return info.start;
+        }
+
+        @Override
+        int getEnd() {
+            return info.end;
+        }
+
+        @Override
+        int getLength() {
+            return info.length;
+        }
+
+        /**
+         * Attemts to create mapping of the characters to glyphs in the glyph vector.
+         * @return array where for each character index stored corresponding glyph index
+         */
+        private int[] getChar2Glyph() {
+            if (char2glyph == null) {
+                GlyphVector gv = getGlyphVector();
+                char2glyph = new int[info.length];
+                Arrays.fill(char2glyph, -1);
+
+                // Fill glyph indicies for first characters corresponding to each glyph
+                int charIndicies[] = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
+                for (int i=0; i<charIndicies.length; i++) {
+                    char2glyph[charIndicies[i]] = i;
+                }
+
+                // If several characters corresponds to one glyph, create mapping for them
+                // Suppose that these characters are going all together
+                int currIndex = 0;
+                for (int i=0; i<char2glyph.length; i++) {
+                    if (char2glyph[i] < 0) {
+                        char2glyph[i] = currIndex;
+                    } else {
+                        currIndex = char2glyph[i];
+                    }
+                }
+            }
+
+            return char2glyph;
+        }
+
+        /**
+         * Creates black box bounds shape for the specified range
+         * @param start - range sart
+         * @param limit - range end
+         * @return black box bounds shape
+         */
+        @Override
+        Shape getCharsBlackBoxBounds(int start, int limit) {
+            start -= info.start;
+            limit -= info.start;
+
+            if (limit > info.length) {
+                limit = info.length;
+            }
+
+            GeneralPath result = new GeneralPath();
+
+            int glyphIndex = 0;
+
+            for (int i=start; i<limit; i++) {
+                glyphIndex = getChar2Glyph()[i];
+                result.append(getGlyphVector().getGlyphVisualBounds(glyphIndex), false);
+            }
+
+            // Shift to the segment's coordinates
+            result.transform(AffineTransform.getTranslateInstance(x, y));
+
+            return result;
+        }
+
+        /**
+         * Calculates position of the character on the screen
+         * @param index - character index
+         * @return X coordinate of the character position
+         */
+        @Override
+        float getCharPosition(int index) {
+            index -= info.start;
+
+            if (index > info.length) {
+                index = info.length;
+            }
+
+            float result = 0;
+
+            int glyphIndex = getChar2Glyph()[index];
+            result = (float) getGlyphVector().getGlyphPosition(glyphIndex).getX();
+
+            // Shift to the segment's coordinates
+            result += x;
+
+            return result;
+        }
+
+        /**
+         * Returns the advance of the individual character
+         * @param index - character index
+         * @return character advance
+         */
+        @Override
+        float getCharAdvance(int index) {
+            if (advanceIncrements == null) {
+                initAdvanceMapping();
+            }
+
+            return advanceIncrements[index - this.getStart()];
+        }
+
+        /**
+         * Returns the outline shape
+         * @return outline
+         */
+        @Override
+        Shape getOutline() {
+            AffineTransform t = AffineTransform.getTranslateInstance(x, y);
+            return t.createTransformedShape(
+                    TextDecorator.extendOutline(
+                            this,
+                            getGlyphVector().getOutline(),
+                            decoration
+                    )
+            );
+        }
+
+        /**
+         * Checks if the character doesn't contribute to the text advance
+         * @param index - character index
+         * @return true if the character has zero advance
+         */
+        @Override
+        boolean charHasZeroAdvance(int index) {
+            if (advanceIncrements == null) {
+                initAdvanceMapping();
+            }
+
+            return advanceIncrements[index - this.getStart()] == 0;
+        }
+
+        /**
+         * Creates text hit info from the hit position
+         * @param hitX - X coordinate relative to the origin of the layout
+         * @param hitY - Y coordinate relative to the origin of the layout
+         * @return hit info
+         */
+        @Override
+        TextHitInfo hitTest(float hitX, float hitY) {
+            hitX -= x;
+
+            float glyphPositions[] =
+                    getGlyphVector().getGlyphPositions(0, info.length+1, null);
+
+            int glyphIdx;
+            boolean leading = false;
+            for (glyphIdx = 1; glyphIdx <= info.length; glyphIdx++) {
+                if (glyphPositions[(glyphIdx)*2] >= hitX) {
+                    float advance =
+                            glyphPositions[(glyphIdx)*2] - glyphPositions[(glyphIdx-1)*2];
+                    leading = glyphPositions[(glyphIdx-1)*2] + advance/2 > hitX ? true : false;
+                    glyphIdx--;
+                    break;
+                }
+            }
+
+            if (glyphIdx == info.length) {
+                glyphIdx--;
+            }
+
+            int charIdx = getGlyphVector().getGlyphCharIndex(glyphIdx);
+
+            return (leading) ^ ((info.level & 0x1) == 0x1)?
+                    TextHitInfo.leading(charIdx + info.start) :
+                    TextHitInfo.trailing(charIdx + info.start);
+        }
+
+        /**
+         * Collects GlyphJustificationInfo objects from the glyph vector
+         * @return array of all GlyphJustificationInfo objects
+         */
+        private GlyphJustificationInfo[] getGlyphJustificationInfos() {
+            if (gjis == null) {
+                GlyphVector gv = getGlyphVector();
+                int nGlyphs = gv.getNumGlyphs();
+                int charIndicies[] = gv.getGlyphCharIndices(0, nGlyphs, null);
+                gjis = new GlyphJustificationInfo[nGlyphs];
+
+                // Patch: temporary patch, getGlyphJustificationInfo is not implemented
+                float fontSize = info.font.getSize2D();
+                GlyphJustificationInfo defaultInfo =
+                        new GlyphJustificationInfo(
+                                0, // weight
+                                false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0, // grow
+                                false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0); // shrink
+                GlyphJustificationInfo spaceInfo = new GlyphJustificationInfo(
+                        fontSize, // weight
+                        true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, fontSize, // grow
+                        true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, fontSize); // shrink
+
+                ////////
+                // Temporary patch, getGlyphJustificationInfo is not implemented
+                for (int i = 0; i < nGlyphs; i++) {
+                    //gjis[i] = getGlyphVector().getGlyphJustificationInfo(i);
+
+                    char c = info.text[charIndicies[i] + info.start];
+                    if (Character.isWhitespace(c)) {
+                        gjis[i] = spaceInfo;
+                    } else {
+                        gjis[i] = defaultInfo;
+                    }
+                    // End patch
+                }
+            }
+
+            return gjis;
+        }
+
+        /**
+         * Collects justification information into JustificationInfo object
+         * @param jInfo - JustificationInfo object
+         */
+        @Override
+        void updateJustificationInfo(TextRunBreaker.JustificationInfo jInfo) {
+            int lastChar = Math.min(jInfo.lastIdx, info.end) - info.start;
+            boolean haveFirst = info.start <= jInfo.firstIdx;
+            boolean haveLast = info.end >= (jInfo.lastIdx + 1);
+
+            int prevGlyphIdx = -1;
+            int currGlyphIdx;
+
+            if (jInfo.grow) { // Check how much we can grow/shrink on current priority level
+                for (int i=0; i<lastChar; i++) {
+                    currGlyphIdx = getChar2Glyph()[i];
+
+                    if (currGlyphIdx == prevGlyphIdx) {
+                        // Several chars could be represented by one glyph,
+                        // suppose they are contiguous
+                        continue;
+                    }
+                    prevGlyphIdx = currGlyphIdx;
+
+                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[currGlyphIdx];
+                    if (gji.growPriority == jInfo.priority) {
+                        jInfo.weight += gji.weight * 2;
+                        jInfo.growLimit += gji.growLeftLimit;
+                        jInfo.growLimit += gji.growRightLimit;
+                        if (gji.growAbsorb) {
+                            jInfo.absorbedWeight += gji.weight * 2;
+                        }
+                    }
+                }
+            } else {
+                for (int i=0; i<lastChar; i++) {
+                    currGlyphIdx = getChar2Glyph()[i];
+                    if (currGlyphIdx == prevGlyphIdx) {
+                        continue;
+                    }
+                    prevGlyphIdx = currGlyphIdx;
+
+                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[currGlyphIdx];
+                    if (gji.shrinkPriority == jInfo.priority) {
+                        jInfo.weight += gji.weight * 2;
+                        jInfo.growLimit -= gji.shrinkLeftLimit;
+                        jInfo.growLimit -= gji.shrinkRightLimit;
+                        if (gji.shrinkAbsorb) {
+                            jInfo.absorbedWeight += gji.weight * 2;
+                        }
+                    }
+                }
+            }
+
+            if (haveFirst) {  // Don't add padding before first char
+                GlyphJustificationInfo gji = getGlyphJustificationInfos()[getChar2Glyph()[0]];
+                jInfo.weight -= gji.weight;
+                if (jInfo.grow) {
+                    jInfo.growLimit -= gji.growLeftLimit;
+                    if (gji.growAbsorb) {
+                        jInfo.absorbedWeight -= gji.weight;
+                    }
+                } else {
+                    jInfo.growLimit += gji.shrinkLeftLimit;
+                    if (gji.shrinkAbsorb) {
+                        jInfo.absorbedWeight -= gji.weight;
+                    }
+                }
+            }
+
+            if (haveLast) {   // Don't add padding after last char
+                GlyphJustificationInfo gji =
+                        getGlyphJustificationInfos()[getChar2Glyph()[lastChar]];
+                jInfo.weight -= gji.weight;
+                if (jInfo.grow) {
+                    jInfo.growLimit -= gji.growRightLimit;
+                    if (gji.growAbsorb) {
+                        jInfo.absorbedWeight -= gji.weight;
+                    }
+                } else {
+                    jInfo.growLimit += gji.shrinkRightLimit;
+                    if (gji.shrinkAbsorb) {
+                        jInfo.absorbedWeight -= gji.weight;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Performs justification of the segment.
+         * Updates positions of individual characters.
+         * @param jInfos - justification information, gathered by the previous passes
+         * @return amount of growth or shrink of the segment
+         */
+        @Override
+        float doJustification(TextRunBreaker.JustificationInfo jInfos[]) {
+            int lastPriority =
+                    jInfos[jInfos.length-1] == null ?
+                    -1 : jInfos[jInfos.length-1].priority;
+
+            // Get the highest priority
+            int highestPriority = 0;
+            for (; highestPriority<jInfos.length; highestPriority++) {
+                if (jInfos[highestPriority] != null) {
+                    break;
+                }
+            }
+
+            if (highestPriority == jInfos.length) {
+                return 0;
+            }
+
+            TextRunBreaker.JustificationInfo firstInfo = jInfos[highestPriority];
+            TextRunBreaker.JustificationInfo lastInfo =
+                    lastPriority > 0 ? jInfos[lastPriority] : null;
+
+            boolean haveFirst = info.start <= firstInfo.firstIdx;
+            boolean haveLast = info.end >= (firstInfo.lastIdx + 1);
+
+            // Here we suppose that GLYPHS are ordered LEFT TO RIGHT
+            int firstGlyph = haveFirst ?
+                    getChar2Glyph()[firstInfo.firstIdx - info.start] :
+                    getChar2Glyph()[0];
+
+            int lastGlyph = haveLast ?
+                    getChar2Glyph()[firstInfo.lastIdx - info.start] :
+                    getChar2Glyph()[info.length - 1];
+            if (haveLast) {
+                lastGlyph--;
+            }
+
+            TextRunBreaker.JustificationInfo currInfo;
+            float glyphOffset = 0;
+            float positionIncrement = 0;
+            float sideIncrement = 0;
+
+            if (haveFirst) {  // Don't add padding before first char
+                GlyphJustificationInfo gji = getGlyphJustificationInfos()[firstGlyph];
+                currInfo = jInfos[gji.growPriority];
+                if (currInfo != null) {
+                    if (currInfo.useLimits) {
+                        if (currInfo.absorb) {
+                            glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
+                        } else if (
+                                lastInfo != null &&
+                                lastInfo.priority == currInfo.priority
+                        ) {
+                            glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
+                        }
+                        glyphOffset +=
+                                firstInfo.grow ?
+                                gji.growRightLimit :
+                                -gji.shrinkRightLimit;
+                    } else {
+                        glyphOffset += gji.weight * currInfo.gapPerUnit;
+                    }
+                }
+
+                firstGlyph++;
+            }
+
+            if (firstInfo.grow) {
+                for (int i=firstGlyph; i<=lastGlyph; i++) {
+                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
+                    currInfo = jInfos[gji.growPriority];
+                    if (currInfo == null) {
+                        // We still have to increment glyph position
+                        Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                        glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
+                        getGlyphVector().setGlyphPosition(i, glyphPos);
+
+                        continue;
+                    }
+
+                    if (currInfo.useLimits) {
+                        glyphOffset += gji.growLeftLimit;
+                        if (currInfo.absorb) {
+                            sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
+                            glyphOffset += sideIncrement;
+                            positionIncrement = glyphOffset;
+                            glyphOffset += sideIncrement;
+                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
+                            sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
+                            glyphOffset += sideIncrement;
+                            positionIncrement = glyphOffset;
+                            glyphOffset += sideIncrement;
+                        } else {
+                            positionIncrement = glyphOffset;
+                        }
+                        glyphOffset += gji.growRightLimit;
+                    } else {
+                        sideIncrement = gji.weight * currInfo.gapPerUnit;
+                        glyphOffset += sideIncrement;
+                        positionIncrement = glyphOffset;
+                        glyphOffset += sideIncrement;
+                    }
+
+                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                    glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
+                    getGlyphVector().setGlyphPosition(i, glyphPos);
+                }
+            } else {
+                for (int i=firstGlyph; i<=lastGlyph; i++) {
+                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
+                    currInfo = jInfos[gji.shrinkPriority];
+                    if (currInfo == null) {
+                        // We still have to increment glyph position
+                        Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                        glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
+                        getGlyphVector().setGlyphPosition(i, glyphPos);
+
+                        continue;
+                    }
+
+                    if (currInfo.useLimits) {
+                        glyphOffset -= gji.shrinkLeftLimit;
+                        if (currInfo.absorb) {
+                            sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
+                            glyphOffset += sideIncrement;
+                            positionIncrement = glyphOffset;
+                            glyphOffset += sideIncrement;
+                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
+                            sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
+                            glyphOffset += sideIncrement;
+                            positionIncrement = glyphOffset;
+                            glyphOffset += sideIncrement;
+                        } else {
+                            positionIncrement = glyphOffset;
+                        }
+                        glyphOffset -= gji.shrinkRightLimit;
+                    } else {
+                        sideIncrement =  gji.weight * currInfo.gapPerUnit;
+                        glyphOffset += sideIncrement;
+                        positionIncrement = glyphOffset;
+                        glyphOffset += sideIncrement;
+                    }
+
+                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                    glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
+                    getGlyphVector().setGlyphPosition(i, glyphPos);
+                }
+            }
+
+
+            if (haveLast) {   // Don't add padding after last char
+                lastGlyph++;
+
+                GlyphJustificationInfo gji = getGlyphJustificationInfos()[lastGlyph];
+                currInfo = jInfos[gji.growPriority];
+
+                if (currInfo != null) {
+                    if (currInfo.useLimits) {
+                        glyphOffset += firstInfo.grow ? gji.growLeftLimit : -gji.shrinkLeftLimit;
+                        if (currInfo.absorb) {
+                            glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
+                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
+                            glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
+                        }
+                    } else {
+                        glyphOffset += gji.weight * currInfo.gapPerUnit;
+                    }
+                }
+
+                // Ajust positions of all glyphs after last glyph
+                for (int i=lastGlyph; i<getGlyphVector().getNumGlyphs()+1; i++) {
+                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                    glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
+                    getGlyphVector().setGlyphPosition(i, glyphPos);
+                }
+            } else { // Update position after last glyph in glyph vector -
+                // to get correct advance for it
+                Point2D glyphPos = getGlyphVector().getGlyphPosition(lastGlyph+1);
+                glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
+                getGlyphVector().setGlyphPosition(lastGlyph+1, glyphPos);
+            }
+
+            gjis = null; // We don't need justification infos any more
+            // Also we have to reset cached bounds and metrics
+            this.visualBounds = null;
+            this.logicalBounds = null;
+
+            return glyphOffset; // How much our segment grown or shrunk
+        }
+    }
+
+    public static class TextRunSegmentGraphic extends TextRunSegment {
+        GraphicAttribute ga;
+        int start;
+        int length;
+        float fullAdvance;
+
+        TextRunSegmentGraphic(GraphicAttribute attr, int len, int start) {
+            this.start = start;
+            length = len;
+            ga = attr;
+            metrics = new BasicMetrics(ga);
+            fullAdvance = ga.getAdvance() * length;
+        }
+
+        @Override
+        public Object clone() {
+            return new TextRunSegmentGraphic(ga, length, start);
+        }
+
+        // Renders this text run segment
+        @Override
+        void draw(Graphics2D g2d, float xOffset, float yOffset) {
+            if (decoration != null) {
+                TextDecorator.prepareGraphics(this, g2d, xOffset, yOffset);
+            }
+
+            float xPos = x + xOffset;
+            float yPos = y + yOffset;
+
+            for (int i=0; i < length; i++) {
+                ga.draw(g2d, xPos, yPos);
+                xPos += ga.getAdvance();
+            }
+
+            if (decoration != null) {
+                TextDecorator.drawTextDecorations(this, g2d, xOffset, yOffset);
+                TextDecorator.restoreGraphics(decoration, g2d);
+            }
+        }
+
+        // Returns visual bounds of this segment
+        @Override
+        Rectangle2D getVisualBounds() {
+            if (visualBounds == null) {
+                Rectangle2D bounds = ga.getBounds();
+
+                // First and last chars can be out of logical bounds, so we calculate
+                // (bounds.getWidth() - ga.getAdvance()) which is exactly the difference
+                bounds.setRect(
+                        bounds.getMinX() + x,
+                        bounds.getMinY() + y,
+                        bounds.getWidth() - ga.getAdvance() + getAdvance(),
+                        bounds.getHeight()
+                );
+                visualBounds = TextDecorator.extendVisualBounds(this, bounds, decoration);
+            }
+
+            return (Rectangle2D) visualBounds.clone();
+        }
+
+        @Override
+        Rectangle2D getLogicalBounds() {
+            if (logicalBounds == null) {
+                logicalBounds =
+                        new Rectangle2D.Float(
+                                x, y - metrics.ascent,
+                                getAdvance(), metrics.ascent + metrics.descent
+                        );
+            }
+
+            return (Rectangle2D) logicalBounds.clone();
+        }
+
+        @Override
+        float getAdvance() {
+            return fullAdvance;
+        }
+
+        @Override
+        float getAdvanceDelta(int start, int end) {
+            return ga.getAdvance() * (end - start);
+        }
+
+        @Override
+        int getCharIndexFromAdvance(float advance, int start) {
+            start -= this.start;
+
+            if (start < 0) {
+                start = 0;
+            }
+
+            int charOffset = (int) (advance/ga.getAdvance());
+
+            if (charOffset + start > length) {
+                return length + this.start;
+            }
+            return charOffset + start + this.start;
+        }
+
+        @Override
+        int getStart() {
+            return start;
+        }
+
+        @Override
+        int getEnd() {
+            return start + length;
+        }
+
+        @Override
+        int getLength() {
+            return length;
+        }
+
+        @Override
+        Shape getCharsBlackBoxBounds(int start, int limit) {
+            start -= this.start;
+            limit -= this.start;
+
+            if (limit > length) {
+                limit = length;
+            }
+
+            Rectangle2D charBounds = ga.getBounds();
+            charBounds.setRect(
+                    charBounds.getX() + ga.getAdvance() * start + x,
+                    charBounds.getY() + y,
+                    charBounds.getWidth() + ga.getAdvance() * (limit - start),
+                    charBounds.getHeight()
+            );
+
+            return charBounds;
+        }
+
+        @Override
+        float getCharPosition(int index) {
+            index -= start;
+            if (index > length) {
+                index = length;
+            }
+
+            return ga.getAdvance() * index + x;
+        }
+
+        @Override
+        float getCharAdvance(int index) {
+            return ga.getAdvance();
+        }
+
+        @Override
+        Shape getOutline() {
+            AffineTransform t = AffineTransform.getTranslateInstance(x, y);
+            return t.createTransformedShape(
+                    TextDecorator.extendOutline(this, getVisualBounds(), decoration)
+            );
+        }
+
+        @Override
+        boolean charHasZeroAdvance(int index) {
+            return false;
+        }
+
+        @Override
+        TextHitInfo hitTest(float hitX, float hitY) {
+            hitX -= x;
+
+            float tmp = hitX / ga.getAdvance();
+            int hitIndex = Math.round(tmp);
+
+            if (tmp > hitIndex) {
+                return TextHitInfo.leading(hitIndex + this.start);
+            }
+            return TextHitInfo.trailing(hitIndex + this.start);
+        }
+
+        @Override
+        void updateJustificationInfo(TextRunBreaker.JustificationInfo jInfo) {
+            // Do nothing
+        }
+
+        @Override
+        float doJustification(TextRunBreaker.JustificationInfo jInfos[]) {
+            // Do nothing
+            return 0;
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java b/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java
new file mode 100644
index 0000000..f1d64fb
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java
@@ -0,0 +1,79 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.WritableRaster;
+
+import org.apache.harmony.awt.gl.CommonGraphics2D;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.render.JavaBlitter;
+import org.apache.harmony.awt.gl.render.NativeImageBlitter;
+
+/**
+ * BufferedImageGraphics2D is implementation of CommonGraphics2D for
+ * drawing on buffered images. 
+ */
+public class BufferedImageGraphics2D extends CommonGraphics2D {
+    private BufferedImage bi = null;
+    private Rectangle bounds = null;
+
+    public BufferedImageGraphics2D(BufferedImage bi) {
+        super();
+        this.bi = bi;
+        this.bounds = new Rectangle(0, 0, bi.getWidth(), bi.getHeight());
+        clip(bounds);
+        dstSurf = Surface.getImageSurface(bi);
+        if(dstSurf.isNativeDrawable()){
+            blitter = NativeImageBlitter.getInstance();
+        }else{
+            blitter = JavaBlitter.getInstance();
+        }
+    }
+
+    @Override
+    public void copyArea(int x, int y, int width, int height, int dx, int dy) {
+    }
+
+    @Override
+    public Graphics create() {
+        BufferedImageGraphics2D res = new BufferedImageGraphics2D(bi);
+        copyInternalFields(res);
+        return res;
+    }
+
+    @Override
+    public GraphicsConfiguration getDeviceConfiguration() {
+        return null;
+    }
+
+    public ColorModel getColorModel() {
+        return bi.getColorModel();
+    }
+
+    public WritableRaster getWritableRaster() {
+        return bi.getRaster();
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java b/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java
new file mode 100644
index 0000000..0fe25a2
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java
@@ -0,0 +1,136 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.awt.image.IndexColorModel;
+import java.awt.image.WritableRaster;
+import java.util.Hashtable;
+
+public class BufferedImageSource implements ImageProducer {
+
+    private Hashtable<?, ?> properties;
+    private ColorModel cm;
+    private WritableRaster raster;
+    private int width;
+    private int height;
+
+    private ImageConsumer ic;
+
+    public BufferedImageSource(BufferedImage image, Hashtable<?, ?> properties){
+        if(properties == null) {
+            this.properties = new Hashtable<Object, Object>();
+        } else {
+            this.properties = properties;
+        }
+
+        width = image.getWidth();
+        height = image.getHeight();
+        cm = image.getColorModel();
+        raster = image.getRaster();
+    }
+
+    public BufferedImageSource(BufferedImage image){
+        this(image, null);
+    }
+
+    public boolean isConsumer(ImageConsumer ic) {
+        return (this.ic == ic);
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+    }
+
+    public void removeConsumer(ImageConsumer ic) {
+        if (this.ic == ic) {
+            this.ic = null;
+        }
+    }
+
+    public void addConsumer(ImageConsumer ic) {
+        this.ic = ic;
+        startProduction();
+    }
+
+    private void startProduction(){
+        try {
+            ic.setDimensions(width, height);
+            ic.setProperties(properties);
+            ic.setColorModel(cm);
+            ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
+                    ImageConsumer.COMPLETESCANLINES |
+                    ImageConsumer.SINGLEFRAME |
+                    ImageConsumer.SINGLEPASS);
+            if(cm instanceof IndexColorModel &&
+                    raster.getTransferType() == DataBuffer.TYPE_BYTE ||
+                    cm instanceof ComponentColorModel &&
+                    raster.getTransferType() == DataBuffer.TYPE_BYTE &&
+                    raster.getNumDataElements() == 1){
+                DataBufferByte dbb = (DataBufferByte) raster.getDataBuffer();
+                byte data[] = dbb.getData();
+                int off = dbb.getOffset();
+                ic.setPixels(0, 0, width, height, cm, data, off, width);
+            }else if(cm instanceof DirectColorModel &&
+                    raster.getTransferType() == DataBuffer.TYPE_INT){
+                DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
+                int data[] = dbi.getData();
+                int off = dbi.getOffset();
+                ic.setPixels(0, 0, width, height, cm, data, off, width);
+            }else if(cm instanceof DirectColorModel &&
+                    raster.getTransferType() == DataBuffer.TYPE_BYTE){
+                DataBufferByte dbb = (DataBufferByte) raster.getDataBuffer();
+                byte data[] = dbb.getData();
+                int off = dbb.getOffset();
+                ic.setPixels(0, 0, width, height, cm, data, off, width);
+            }else{
+                ColorModel rgbCM = ColorModel.getRGBdefault();
+                int pixels[] = new int[width];
+                Object pix = null;
+                for(int y = 0; y < height; y++){
+                    for(int x = 0 ; x < width; x++){
+                        pix = raster.getDataElements(x, y, pix);
+                        pixels[x] = cm.getRGB(pix);
+                    }
+                    ic.setPixels(0, y, width, 1, rgbCM, pixels, 0, width);
+                }
+            }
+            ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
+        }catch (NullPointerException e){
+            if (ic != null) {
+                ic.imageComplete(ImageConsumer.IMAGEERROR);
+            }
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java
new file mode 100644
index 0000000..cc6d7cf
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java
@@ -0,0 +1,62 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 10.02.2005
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+public class ByteArrayDecodingImageSource extends DecodingImageSource {
+
+    byte imagedata[];
+    int imageoffset;
+    int imagelength;
+
+    public ByteArrayDecodingImageSource(byte imagedata[], int imageoffset,
+            int imagelength){
+        this.imagedata = imagedata;
+        this.imageoffset = imageoffset;
+        this.imagelength = imagelength;
+    }
+
+    public ByteArrayDecodingImageSource(byte imagedata[]){
+        this(imagedata, 0, imagedata.length);
+    }
+
+    @Override
+    protected boolean checkConnection() {
+        return true;
+    }
+
+    @Override
+    protected InputStream getInputStream() {
+        // BEGIN android-modified
+        // TODO: Why does a ByteArrayInputStream need to be buffered at all?
+        return new BufferedInputStream(new ByteArrayInputStream(imagedata,
+                        imageoffset, imagelength), 1024);
+        // END android-modified
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java b/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java
new file mode 100644
index 0000000..8793050
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 13.03.2006
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+public interface DataBufferListener {
+    
+    void dataChanged();
+    void dataTaken();
+    void dataReleased();
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java
new file mode 100644
index 0000000..958d691
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java
@@ -0,0 +1,261 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+ * Created on 18.01.2005
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This is an abstract class that encapsulates a main part of ImageProducer functionality
+ * for the images being decoded by the native decoders, like PNG, JPEG and GIF.
+ * It helps to integrate image decoders into producer/consumer model. It provides
+ * functionality for working with several decoder instances and several image consumers
+ * simultaneously.
+ */
+public abstract class DecodingImageSource implements ImageProducer {
+    List<ImageConsumer> consumers = new ArrayList<ImageConsumer>(5);
+    List<ImageDecoder> decoders = new ArrayList<ImageDecoder>(5);
+    boolean loading;
+
+    ImageDecoder decoder;
+
+    protected abstract boolean checkConnection();
+
+    protected abstract InputStream getInputStream();
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if (!checkConnection()) { // No permission for this consumer
+            ic.imageComplete(ImageConsumer.IMAGEERROR);
+            return;
+        }
+
+        ImageConsumer cons = findConsumer(consumers, ic);
+
+        if (cons == null) { // Try to look in the decoders
+            ImageDecoder d = null;
+
+            // Check for all existing decoders
+            for (Iterator<ImageDecoder> i = decoders.iterator(); i.hasNext();) {
+                d = i.next();
+                cons = findConsumer(d.consumers, ic);
+                if (cons != null) {
+                    break;
+                }
+            }
+        }
+
+        if (cons == null) { // Not found, add this consumer
+            consumers.add(ic);
+        }
+    }
+
+    /**
+     * This method stops sending data to the given consumer
+     * @param ic - consumer
+     */
+    private void abortConsumer(ImageConsumer ic) {
+        ic.imageComplete(ImageConsumer.IMAGEERROR);
+        consumers.remove(ic);
+    }
+
+    /**
+     * This method stops sending data to the list of consumers.
+     * @param consumersList - list of consumers
+     */
+    private void abortAllConsumers(List<ImageConsumer> consumersList) {
+        for (ImageConsumer imageConsumer : consumersList) {
+            abortConsumer(imageConsumer);
+        }
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        ImageDecoder d = null;
+
+        // Remove in all existing decoders
+        for (Iterator<ImageDecoder> i = decoders.iterator(); i.hasNext();) {
+            d = i.next();
+            removeConsumer(d.consumers, ic);
+            if (d.consumers.size() <= 0) {
+                d.terminate();
+            }
+        }
+
+        // Remove in the current queue of consumers
+        removeConsumer(consumers, ic);
+    }
+
+    /**
+     * Static implementation of removeConsumer method
+     * @param consumersList - list of consumers
+     * @param ic - consumer to be removed
+     */
+    private static void removeConsumer(List<ImageConsumer> consumersList, ImageConsumer ic) {
+        ImageConsumer cons = null;
+
+        for (Iterator<ImageConsumer> i = consumersList.iterator(); i.hasNext();) {
+            cons = i.next();
+            if (cons.equals(ic)) {
+                i.remove();
+            }
+        }
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer consumer) {
+        // Do nothing
+    }
+
+    public synchronized void startProduction(ImageConsumer ic) {
+        if (ic != null) {
+            addConsumer(ic);
+        }
+
+        if (!loading && consumers.size() > 0) {
+            ImageLoader.addImageSource(this);
+            loading = true;
+        }
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        ImageDecoder d = null;
+
+        // Check for all existing decoders
+        for (Iterator<ImageDecoder> i = decoders.iterator(); i.hasNext();) {
+            d = i.next();
+            if (findConsumer(d.consumers, ic) != null) {
+                return true;
+            }
+        }
+
+        // Check current queue of consumers
+        return findConsumer(consumers, ic) != null;
+    }
+
+    /**
+     * Checks if the consumer is in the list and returns it it is there
+     * @param consumersList - list of consumers
+     * @param ic - consumer
+     * @return consumer if found, null otherwise
+     */
+    private static ImageConsumer findConsumer(List<ImageConsumer> consumersList, ImageConsumer ic) {
+        ImageConsumer res = null;
+
+        for (Iterator<ImageConsumer> i = consumersList.iterator(); i.hasNext();) {
+            res = i.next();
+            if (res.equals(ic)) {
+                return res;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Use this method to finish decoding or lock the list of consumers
+     * for a particular decoder
+     * @param d - decoder
+     */
+    synchronized void lockDecoder(ImageDecoder d) {
+        if (d == decoder) {
+            decoder = null;
+            startProduction(null);
+        }
+    }
+
+    /**
+     * Tries to find an appropriate decoder for the input stream and adds it
+     * to the list of decoders
+     * @return created decoder
+     */
+    private ImageDecoder createDecoder() {
+        InputStream is = getInputStream();
+
+        ImageDecoder decoder;
+
+        if (is == null) {
+            decoder = null;
+        } else {
+            decoder = ImageDecoder.createDecoder(this, is);
+        }
+
+        if (decoder != null) {
+            synchronized (this) {
+                decoders.add(decoder);
+                this.decoder = decoder;
+                loading = false;
+                consumers = new ArrayList<ImageConsumer>(5); // Reset queue
+            }
+
+            return decoder;
+        }
+        // We were not able to find appropriate decoder
+        List<ImageConsumer> cs;
+        synchronized (this) {
+            cs = consumers;
+            consumers = new ArrayList<ImageConsumer>(5);
+            loading = false;
+        }
+        abortAllConsumers(cs);
+
+        return null;
+    }
+
+    /**
+     * Stop the given decoder and remove it from the list
+     * @param dr - decoder
+     */
+    private synchronized void removeDecoder(ImageDecoder dr) {
+        lockDecoder(dr);
+        decoders.remove(dr);
+    }
+
+    /**
+     * This method serves as an entry point.
+     * It starts the decoder and loads the image data.
+     */
+    public void load() {
+        synchronized (this) {
+            if (consumers.size() == 0) {
+                loading = false;
+                return;
+            }
+        }
+
+        ImageDecoder d = createDecoder();
+        if (d != null) {
+            try {
+                decoder.decodeImage();
+            } catch (IOException e) {
+                e.printStackTrace();
+            } finally {
+                removeDecoder(d);
+                abortAllConsumers(d.consumers);
+            }
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java
new file mode 100644
index 0000000..54d4664
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java
@@ -0,0 +1,68 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+ * Created on 20.01.2005
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+public class FileDecodingImageSource extends DecodingImageSource {
+  String filename;
+
+  public FileDecodingImageSource(String file) {
+    SecurityManager security = System.getSecurityManager();
+    if (security != null) {
+        security.checkRead(file);
+    }
+
+    filename = file;
+  }
+
+  @Override
+protected boolean checkConnection() {
+      SecurityManager security = System.getSecurityManager();
+      if (security != null) {
+          try {
+            security.checkRead(filename);
+          } catch (SecurityException e) {
+              return false;
+          }
+      }
+
+      return true;
+  }
+
+  @Override
+protected InputStream getInputStream() {
+    try {
+      // BEGIN android-modified
+      return new BufferedInputStream(new FileInputStream(filename), 8192);
+      // END android-modified
+    } catch (FileNotFoundException e) {
+      return null;
+    }
+  }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/GifDecoder.java b/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
new file mode 100644
index 0000000..7ecb15b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
@@ -0,0 +1,692 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+* Created on 27.01.2005
+*/
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.IndexColorModel;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+
+public class GifDecoder extends ImageDecoder {
+    // initializes proper field IDs
+    private static native void initIDs();
+
+    static {
+        System.loadLibrary("gl"); //$NON-NLS-1$
+        initIDs();
+    }
+
+    // ImageConsumer hints: common
+    private static final int baseHints =
+            ImageConsumer.SINGLEPASS | ImageConsumer.COMPLETESCANLINES |
+            ImageConsumer.SINGLEFRAME;
+    // ImageConsumer hints: interlaced
+    private static final int interlacedHints =
+            baseHints | ImageConsumer.RANDOMPIXELORDER;
+
+    // Impossible color value - no translucent pixels allowed
+    static final int IMPOSSIBLE_VALUE = 0x0FFFFFFF;
+
+    // I/O buffer
+    private static final int BUFFER_SIZE = 1024;
+    private byte buffer[] = new byte[BUFFER_SIZE];
+
+    GifDataStream gifDataStream = new GifDataStream();
+    GifGraphicBlock currBlock;
+
+    // Pointer to native structure which store decoding state
+    // between subsequent decoding/IO-suspension cycles
+    private long hNativeDecoder; // NULL initially
+
+    // Number of bytes eaten by the native decoder
+    private int bytesConsumed;
+
+    private boolean consumersPrepared;
+    private Hashtable<String, String> properties = new Hashtable<String, String>();
+
+    // Could be set up by java code or native method when
+    // transparent pixel index changes or local color table encountered
+    private boolean forceRGB;
+
+    private byte screenBuffer[];
+    private int screenRGBBuffer[];
+
+    public GifDecoder(DecodingImageSource src, InputStream is) {
+        super(src, is);
+    }
+
+    private static native int[] toRGB(byte imageData[], byte colormap[], int transparentColor);
+
+    private static native void releaseNativeDecoder(long hDecoder);
+
+    private native int decode(
+            byte input[],
+            int bytesInBuffer,
+            long hDecoder,
+            GifDataStream dataStream,
+            GifGraphicBlock currBlock
+            );
+
+    private int[] getScreenRGBBuffer() {
+        if (screenRGBBuffer == null) {
+            if (screenBuffer != null) {
+                int transparentColor =
+                        gifDataStream.logicalScreen.globalColorTable.cm.getTransparentPixel();
+                transparentColor = transparentColor > 0 ? transparentColor : IMPOSSIBLE_VALUE;
+                screenRGBBuffer =
+                        toRGB(
+                                screenBuffer,
+                                gifDataStream.logicalScreen.globalColorTable.colors,
+                                transparentColor
+                        );
+            } else {
+                int size = gifDataStream.logicalScreen.logicalScreenHeight *
+                        gifDataStream.logicalScreen.logicalScreenWidth;
+                screenRGBBuffer = new int[size];
+            }
+        }
+
+        return screenRGBBuffer;
+    }
+
+    private void prepareConsumers() {
+        GifLogicalScreen gls = gifDataStream.logicalScreen;
+        setDimensions(gls.logicalScreenWidth,
+                gls.logicalScreenHeight);
+        setProperties(properties);
+
+        currBlock = gifDataStream.graphicBlocks.get(0);
+        if (forceRGB) {
+            setColorModel(ColorModel.getRGBdefault());
+        } else {
+            setColorModel(gls.globalColorTable.getColorModel(currBlock.transparentColor));
+        }
+
+        // Fill screen buffer with the background or transparent color
+        if (forceRGB) {
+            int fillColor = 0xFF000000;
+            if (gls.backgroundColor != IMPOSSIBLE_VALUE) {
+                fillColor = gls.backgroundColor;
+            }
+
+            Arrays.fill(getScreenRGBBuffer(), fillColor);
+        } else {
+            int fillColor = 0;
+
+            if (gls.backgroundColor != IMPOSSIBLE_VALUE) {
+                fillColor = gls.backgroundColor;
+            } else {
+                fillColor = gls.globalColorTable.cm.getTransparentPixel();
+            }
+
+            screenBuffer = new byte[gls.logicalScreenHeight*gls.logicalScreenWidth];
+            Arrays.fill(screenBuffer, (byte) fillColor);
+        }
+
+        setHints(interlacedHints); // XXX - always random pixel order
+    }
+
+    @Override
+    public void decodeImage() throws IOException {
+        try {
+            int bytesRead = 0;
+            int needBytes, offset, bytesInBuffer = 0;
+            boolean eosReached = false;
+            GifGraphicBlock blockToDispose = null;
+
+            // Create new graphic block
+            if (currBlock == null) {
+                currBlock = new GifGraphicBlock();
+                gifDataStream.graphicBlocks.add(currBlock);
+            }
+
+            // Read from the input stream
+            for (;;) {
+                needBytes = BUFFER_SIZE - bytesInBuffer;
+                offset = bytesInBuffer;
+
+                bytesRead = inputStream.read(buffer, offset, needBytes);
+
+                if (bytesRead < 0) {
+                    eosReached = true;
+                    bytesRead = 0;
+                } // Don't break, maybe something left in buffer
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer += bytesRead;
+
+                // Here we pass number of new bytes read from the input stream (bytesRead)
+                // since native decoder uses java buffer and doesn't have its own
+                // buffer. So it adds this number to the number of bytes left
+                // in buffer from the previous call.
+                int numLines = decode(
+                        buffer,
+                        bytesRead,
+                        hNativeDecoder,
+                        gifDataStream,
+                        currBlock);
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer -= bytesConsumed;
+
+                if (
+                        !consumersPrepared &&
+                        gifDataStream.logicalScreen.completed &&
+                        gifDataStream.logicalScreen.globalColorTable.completed &&
+                        (currBlock.imageData != null || // Have transparent pixel filled
+                        currBlock.rgbImageData != null)
+                ) {
+                    prepareConsumers();
+                    consumersPrepared = true;
+                }
+
+                if (bytesConsumed < 0) {
+                    break; // Error exit
+                }
+
+                if (currBlock != null) {
+                    if (numLines != 0) {
+                        // Dispose previous image only before showing next
+                        if (blockToDispose != null) {
+                            blockToDispose.dispose();
+                            blockToDispose = null;
+                        }
+
+                        currBlock.sendNewData(this, numLines);
+                    }
+
+                    if (currBlock.completed && hNativeDecoder != 0) {
+                        blockToDispose = currBlock; // Dispose only before showing new pixels
+                        currBlock = new GifGraphicBlock();
+                        gifDataStream.graphicBlocks.add(currBlock);
+                    }
+                }
+
+                if (hNativeDecoder == 0) {
+                    break;
+                }
+
+                if (eosReached && numLines == 0) { // Maybe image is truncated...
+                    releaseNativeDecoder(hNativeDecoder);
+                    break;
+                }
+            }
+        } finally {
+            closeStream();
+        }
+
+        // Here all animation goes
+        // Repeat image loopCount-1 times or infinitely if loopCount = 0
+        if (gifDataStream.loopCount != 1) {
+            if (currBlock.completed == false) {
+                gifDataStream.graphicBlocks.remove(currBlock);
+            }
+
+            int numFrames = gifDataStream.graphicBlocks.size();
+            // At first last block will be disposed
+            GifGraphicBlock gb =
+                    gifDataStream.graphicBlocks.get(numFrames-1);
+
+            ImageLoader.beginAnimation();
+
+            while (gifDataStream.loopCount != 1) {
+                if (gifDataStream.loopCount != 0) {
+                    gifDataStream.loopCount--;
+                }
+
+                // Show all frames
+                for (int i=0; i<numFrames; i++) {
+                    gb.dispose();
+                    gb = gifDataStream.graphicBlocks.get(i);
+
+                    // Show one frame
+                    if (forceRGB) {
+                        setPixels(
+                                gb.imageLeft,
+                                gb.imageTop,
+                                gb.imageWidth,
+                                gb.imageHeight,
+                                ColorModel.getRGBdefault(),
+                                gb.getRgbImageData(),
+                                0,
+                                gb.imageWidth
+                        );
+                    } else {
+                        setPixels(
+                                gb.imageLeft,
+                                gb.imageTop,
+                                gb.imageWidth,
+                                gb.imageHeight,
+                                null,
+                                gb.imageData,
+                                0,
+                                gb.imageWidth
+                        );
+                    }
+                }
+            }
+            ImageLoader.endAnimation();
+        }
+
+        imageComplete(ImageConsumer.STATICIMAGEDONE);
+    }
+
+    void setComment(String newComment) {
+        Object currComment = properties.get("comment"); //$NON-NLS-1$
+
+        if (currComment == null) {
+            properties.put("comment", newComment); //$NON-NLS-1$
+        } else {
+            properties.put("comment", (String) currComment + "\n" + newComment); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        setProperties(properties);
+    }
+
+    class GifDataStream {
+        //  Indicates that reading of the whole data stream accomplished
+        boolean completed = false;
+
+        // Added to support Netscape 2.0 application
+        // extension block.
+        int loopCount = 1;
+
+        GifLogicalScreen logicalScreen = new GifLogicalScreen();
+        List<GifGraphicBlock> graphicBlocks = new ArrayList<GifGraphicBlock>(10); // Of GifGraphicBlocks
+
+        // Comments from the image
+        String comments[];
+    }
+
+    class GifLogicalScreen {
+        //  Indicates that reading of this block accomplished
+        boolean completed = false;
+
+        int logicalScreenWidth;
+        int logicalScreenHeight;
+
+        int backgroundColor = IMPOSSIBLE_VALUE;
+
+        GifColorTable globalColorTable = new GifColorTable();
+    }
+
+    class GifGraphicBlock {
+        //  Indicates that reading of this block accomplished
+        boolean completed = false;
+
+        final static int DISPOSAL_NONE = 0;
+        final static int DISPOSAL_NODISPOSAL = 1;
+        final static int DISPOSAL_BACKGROUND = 2;
+        final static int DISPOSAL_RESTORE = 3;
+
+        int disposalMethod;
+        int delayTime; // Multiplied by 10 already
+        int transparentColor = IMPOSSIBLE_VALUE;
+
+        int imageLeft;
+        int imageTop;
+        int imageWidth;
+        int imageHeight;
+
+        // Auxilliary variables to minimize computations
+        int imageRight;
+        int imageBottom;
+
+        boolean interlace;
+
+        // Don't need local color table - if it is specified
+        // image data are converted to RGB in the native code
+
+        byte imageData[] = null;
+        int rgbImageData[] = null;
+
+        private int currY = 0; // Current output scanline
+
+        int[] getRgbImageData() {
+            if (rgbImageData == null) {
+                rgbImageData =
+                        toRGB(
+                                imageData,
+                                gifDataStream.logicalScreen.globalColorTable.colors,
+                                transparentColor
+                        );
+                if (transparentColor != IMPOSSIBLE_VALUE) {
+                    transparentColor =
+                            gifDataStream.logicalScreen.globalColorTable.cm.getRGB(transparentColor);
+                    transparentColor &= 0x00FFFFFF;
+                }
+            }
+            return rgbImageData;
+        }
+
+        private void replaceTransparentPixels(int numLines) {
+            List<GifGraphicBlock> graphicBlocks = gifDataStream.graphicBlocks;
+            int prevBlockIndex = graphicBlocks.indexOf(this) - 1;
+
+            if (prevBlockIndex >= 0) {
+                int maxY = currY + numLines + imageTop;
+                int offset = currY * imageWidth;
+
+                // Update right and bottom coordinates
+                imageRight = imageLeft + imageWidth;
+                imageBottom = imageTop + imageHeight;
+
+                int globalWidth = gifDataStream.logicalScreen.logicalScreenWidth;
+                int pixelValue, imageOffset;
+                int rgbData[] = forceRGB ? getRgbImageData() : null;
+
+                for (int y = currY + imageTop; y < maxY; y++) {
+                    imageOffset = globalWidth * y + imageLeft;
+                    for (int x = imageLeft; x < imageRight; x++) {
+                        pixelValue = forceRGB ?
+                                rgbData[offset] :
+                                imageData[offset] & 0xFF;
+                        if (pixelValue == transparentColor) {
+                            if (forceRGB) {
+                                pixelValue = getScreenRGBBuffer() [imageOffset];
+                                rgbData[offset] = pixelValue;
+                            } else {
+                                pixelValue = screenBuffer [imageOffset];
+                                imageData[offset] = (byte) pixelValue;
+                            }
+                        }
+                        offset++;
+                        imageOffset++;
+                    } // for
+                } // for
+
+            } // if (prevBlockIndex >= 0)
+        }
+
+        public void sendNewData(GifDecoder decoder, int numLines) {
+            // Get values for transparent pixels
+            // from the perevious frames
+            if (transparentColor != IMPOSSIBLE_VALUE) {
+                replaceTransparentPixels(numLines);
+            }
+
+            if (forceRGB) {
+                decoder.setPixels(
+                        imageLeft,
+                        imageTop + currY,
+                        imageWidth,
+                        numLines,
+                        ColorModel.getRGBdefault(),
+                        getRgbImageData(),
+                        currY*imageWidth,
+                        imageWidth
+                );
+            } else {
+                decoder.setPixels(
+                        imageLeft,
+                        imageTop + currY,
+                        imageWidth,
+                        numLines,
+                        null,
+                        imageData,
+                        currY*imageWidth,
+                        imageWidth
+                );
+            }
+
+            currY += numLines;
+        }
+
+        public void dispose() {
+            imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+
+            // Show current frame until delayInterval will not elapse
+            if (delayTime > 0) {
+                try {
+                    Thread.sleep(delayTime);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                Thread.yield(); // Allow consumers to consume data
+            }
+
+            // Don't dispose if image is outside of the visible area
+            if (imageLeft > gifDataStream.logicalScreen.logicalScreenWidth ||
+                    imageTop > gifDataStream.logicalScreen.logicalScreenHeight) {
+                disposalMethod = DISPOSAL_NONE;
+            }
+
+            switch(disposalMethod) {
+                case DISPOSAL_BACKGROUND: {
+                    if (forceRGB) {
+                        getRgbImageData(); // Ensure that transparentColor is RGB, not index
+
+                        int data[] = new int[imageWidth*imageHeight];
+
+                        // Compatibility: Fill with transparent color if we have one
+                        if (transparentColor != IMPOSSIBLE_VALUE) {
+                            Arrays.fill(
+                                    data,
+                                    transparentColor
+                            );
+                        } else {
+                            Arrays.fill(
+                                    data,
+                                    gifDataStream.logicalScreen.backgroundColor
+                            );
+                        }
+
+                        setPixels(
+                                imageLeft,
+                                imageTop,
+                                imageWidth,
+                                imageHeight,
+                                ColorModel.getRGBdefault(),
+                                data,
+                                0,
+                                imageWidth
+                        );
+
+                        sendToScreenBuffer(data);
+                    } else {
+                        byte data[] = new byte[imageWidth*imageHeight];
+
+                        // Compatibility: Fill with transparent color if we have one
+                        if (transparentColor != IMPOSSIBLE_VALUE) {
+                            Arrays.fill(
+                                    data,
+                                    (byte) transparentColor
+                            );
+                        } else {
+                            Arrays.fill(
+                                    data,
+                                    (byte) gifDataStream.logicalScreen.backgroundColor
+                            );
+                        }
+
+                        setPixels(
+                                imageLeft,
+                                imageTop,
+                                imageWidth,
+                                imageHeight,
+                                null,
+                                data,
+                                0,
+                                imageWidth
+                        );
+
+                        sendToScreenBuffer(data);
+                    }
+                    break;
+                }
+                case DISPOSAL_RESTORE: {
+                    screenBufferToScreen();
+                    break;
+                }
+                case DISPOSAL_NONE:
+                case DISPOSAL_NODISPOSAL:
+                default: {
+                    // Copy transmitted data to the screen buffer
+                    Object data = forceRGB ? (Object) getRgbImageData() : imageData;
+                    sendToScreenBuffer(data);
+                    break;
+                }
+            }
+        }
+
+        private void sendToScreenBuffer(Object data) {
+            int dataInt[];
+            byte dataByte[];
+
+            int width = gifDataStream.logicalScreen.logicalScreenWidth;
+
+
+            if (forceRGB) {
+                dataInt = (int[]) data;
+
+                if (imageWidth == width) {
+                    System.arraycopy(dataInt,
+                            0,
+                            getScreenRGBBuffer(),
+                            imageLeft + imageTop*width,
+                            dataInt.length
+                    );
+                } else { // Each scanline
+                    copyScanlines(dataInt, getScreenRGBBuffer(), width);
+                }
+            } else {
+                dataByte = (byte[]) data;
+
+                if (imageWidth == width) {
+                    System.arraycopy(dataByte,
+                            0,
+                            screenBuffer,
+                            imageLeft + imageTop*width,
+                            dataByte.length
+                    );
+                } else { // Each scanline
+                    copyScanlines(dataByte, screenBuffer, width);
+                }
+            }
+        } // sendToScreenBuffer
+
+        private void copyScanlines(Object src, Object dst, int width) {
+            for (int i=0; i<imageHeight; i++) {
+                System.arraycopy(src,
+                        i*imageWidth,
+                        dst,
+                        imageLeft + i*width + imageTop*width,
+                        imageWidth
+                );
+            } // for
+        }
+
+        private void screenBufferToScreen() {
+            int width = gifDataStream.logicalScreen.logicalScreenWidth;
+
+            Object dst = forceRGB ?
+                    (Object) new int[imageWidth*imageHeight] :
+                    new byte[imageWidth*imageHeight];
+
+            Object src = forceRGB ?
+                    getScreenRGBBuffer() :
+                    (Object) screenBuffer;
+
+            int offset = 0;
+            Object toSend;
+
+            if (width == imageWidth) {
+                offset = imageWidth * imageTop;
+                toSend = src;
+            } else {
+                for (int i=0; i<imageHeight; i++) {
+                    System.arraycopy(src,
+                            imageLeft + i*width + imageTop*width,
+                            dst,
+                            i*imageWidth,
+                            imageWidth
+                    );
+                } // for
+                toSend = dst;
+            }
+
+            if (forceRGB) {
+                setPixels(
+                        imageLeft,
+                        imageTop,
+                        imageWidth,
+                        imageHeight,
+                        ColorModel.getRGBdefault(),
+                        (int [])toSend,
+                        offset,
+                        imageWidth
+                );
+            } else {
+                setPixels(
+                        imageLeft,
+                        imageTop,
+                        imageWidth,
+                        imageHeight,
+                        null,
+                        (byte [])toSend,
+                        offset,
+                        imageWidth
+                );
+            }
+        }
+    }
+
+    class GifColorTable {
+        //  Indicates that reading of this block accomplished
+        boolean completed = false;
+
+        IndexColorModel cm = null;
+        int size = 0; // Actual number of colors in the color table
+        byte colors[] = new byte[256*3];
+
+        IndexColorModel getColorModel(int transparentColor) {
+            if (cm != null) {
+                if (transparentColor != cm.getTransparentPixel()) {
+                    return cm = null; // Force default ARGB color model
+                }
+                return cm;
+            } else
+                if (completed && size > 0) {
+                    if (transparentColor == IMPOSSIBLE_VALUE) {
+                        return cm =
+                                new IndexColorModel(8, size, colors, 0, false);
+                    }
+
+                    if (transparentColor > size) {
+                        size = transparentColor + 1;
+                    }
+                    return cm =
+                            new IndexColorModel(8, size, colors, 0, false, transparentColor);
+                }
+
+            return cm = null; // Force default ARGB color model
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java b/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java
new file mode 100644
index 0000000..d16128e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java
@@ -0,0 +1,258 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+ * Created on 18.01.2005
+ */
+package org.apache.harmony.awt.gl.image;
+
+import com.android.internal.awt.AndroidImageDecoder;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ImageConsumer;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ConcurrentModificationException;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * This class contains common functionality for all image decoders.
+ */
+public abstract class ImageDecoder {
+    
+    /** Image types */
+    public static final int GENERIC_DECODER = 0;
+    public static final int JPG_DECODER = 1;
+    public static final int GIF_DECODER = 2;
+    public static final int PNG_DECODER = 3;
+    
+    private static final int MAX_BYTES_IN_SIGNATURE = 8;
+
+    protected List<ImageConsumer> consumers;
+    protected InputStream inputStream;
+    protected DecodingImageSource src;
+
+    protected boolean terminated;
+
+    /**
+     * Chooses appropriate image decoder by looking into input stream and checking
+     * the image signature.
+     * @param src - image producer, required for passing data to it from the
+     * created decoder via callbacks
+     * @param is - stream
+     * @return decoder
+     */
+    static ImageDecoder createDecoder(DecodingImageSource src, InputStream is) {
+        InputStream markable;
+
+        if (!is.markSupported()) {
+            // BEGIN android-modified
+            markable = new BufferedInputStream(is, 8192);
+            // END android-modified
+        } else {
+            markable = is;
+        }
+            
+        // Read the signature from the stream and then reset it back
+        try {
+            markable.mark(MAX_BYTES_IN_SIGNATURE);
+
+            byte[] signature = new byte[MAX_BYTES_IN_SIGNATURE];
+            markable.read(signature, 0, MAX_BYTES_IN_SIGNATURE);
+            markable.reset();
+
+            if ((signature[0] & 0xFF) == 0xFF &&
+                    (signature[1] & 0xFF) == 0xD8 &&
+                    (signature[2] & 0xFF) == 0xFF) { // JPEG
+                return loadDecoder(PNG_DECODER, src, is);
+            } else if ((signature[0] & 0xFF) == 0x47 && // G
+                    (signature[1] & 0xFF) == 0x49 && // I
+                    (signature[2] & 0xFF) == 0x46) { // F
+                return loadDecoder(GIF_DECODER, src, is);
+            } else if ((signature[0] & 0xFF) == 137 && // PNG signature: 137 80 78 71 13 10 26 10
+                    (signature[1] & 0xFF) == 80 &&
+                    (signature[2] & 0xFF) == 78 &&
+                    (signature[3] & 0xFF) == 71 &&
+                    (signature[4] & 0xFF) == 13 &&
+                    (signature[5] & 0xFF) == 10 &&
+                    (signature[6] & 0xFF) == 26 &&
+                    (signature[7] & 0xFF) == 10) {
+                return loadDecoder(JPG_DECODER, src, is);
+            }
+
+            return loadDecoder(GENERIC_DECODER, src, is);
+            
+        } catch (IOException e) { // Silently
+        }
+
+        return null;
+    }
+    
+    /*
+     * In the future, we might return different decoders for differen image types.
+     * But for now, we always return the generic one.
+     * Also: we could add a factory to load image decoder.
+     */
+    private static ImageDecoder loadDecoder(int type, DecodingImageSource src, 
+            InputStream is) {
+        return new AndroidImageDecoder(src, is);
+    }
+
+    protected ImageDecoder(DecodingImageSource _src, InputStream is) {
+        src = _src;
+        consumers = src.consumers;
+        inputStream = is;
+    }
+
+    public abstract void decodeImage() throws IOException;
+
+    public synchronized void closeStream() {
+        if (inputStream != null) {
+            try {
+                inputStream.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Stops the decoding by interrupting the current decoding thread.
+     * Used when all consumers are removed and there's no more need to
+     * run the decoder.
+     */
+    public void terminate() {
+        src.lockDecoder(this);
+        closeStream();
+
+        AccessController.doPrivileged(
+                new PrivilegedAction<Void>() {
+                    public Void run() {
+                        Thread.currentThread().interrupt();
+                        return null;
+                    }
+                }
+        );
+
+        terminated = true;
+    }
+
+    protected void setDimensions(int w, int h) {
+        if (terminated) {
+            return;
+        }
+
+        for (ImageConsumer ic : consumers) {
+            ic.setDimensions(w, h);
+        }
+    }
+
+    protected void setProperties(Hashtable<?, ?> props) {
+        if (terminated) {
+            return;
+        }
+
+        for (ImageConsumer ic : consumers) {
+            ic.setProperties(props);
+        }
+    }
+
+    protected void setColorModel(ColorModel cm) {
+        if (terminated) {
+            return;
+        }
+
+        for (ImageConsumer ic : consumers) {
+            ic.setColorModel(cm);
+        }
+    }
+
+    protected void setHints(int hints) {
+        if (terminated) {
+            return;
+        }
+
+        for (ImageConsumer ic : consumers) {
+            ic.setHints(hints);
+        }
+    }
+
+    protected void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model,
+            byte pix[],
+            int off, int scansize
+            ) {
+        if (terminated) {
+            return;
+        }
+
+        src.lockDecoder(this);
+
+        for (ImageConsumer ic : consumers) {
+            ic.setPixels(x, y, w, h, model, pix, off, scansize);
+        }
+    }
+
+    protected void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model,
+            int pix[],
+            int off, int scansize
+            ) {
+        if (terminated) {
+            return;
+        }
+
+        src.lockDecoder(this);
+
+        for (ImageConsumer ic : consumers) {
+            ic.setPixels(x, y, w, h, model, pix, off, scansize);
+        }
+    }
+
+    protected void imageComplete(int status) {
+        if (terminated) {
+            return;
+        }
+
+        src.lockDecoder(this);
+
+        ImageConsumer ic = null;
+
+        for (Iterator<ImageConsumer> i = consumers.iterator(); i.hasNext();) {
+            try {
+                ic = i.next();
+            } catch (ConcurrentModificationException e) {
+                i = consumers.iterator();
+                continue;
+            }
+            ic.imageComplete(status);
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/ImageLoader.java b/awt/org/apache/harmony/awt/gl/image/ImageLoader.java
new file mode 100644
index 0000000..5c7d180
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/ImageLoader.java
@@ -0,0 +1,208 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+ * Created on 18.01.2005
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This class provides functionality for simultaneous loading of
+ * several images and running animation.
+ */
+public class ImageLoader extends Thread {
+    // Contains ImageLoader objects
+    // and queue of image sources waiting to be loaded
+    static class ImageLoadersStorage {
+        private static final int MAX_THREADS = 5;
+        private static final int TIMEOUT = 4000;
+        static ImageLoadersStorage instance;
+
+        List<DecodingImageSource> queue = new LinkedList<DecodingImageSource>();
+        List<Thread> loaders = new ArrayList<Thread>(MAX_THREADS);
+
+        private int freeLoaders;
+
+        private ImageLoadersStorage() {}
+
+        static ImageLoadersStorage getStorage() {
+            if (instance == null) {
+                instance = new ImageLoadersStorage();
+            }
+
+            return instance;
+        }
+    }
+
+    ImageLoader() {
+        super();
+        setDaemon(true);
+    }
+
+    /**
+     * This method creates a new thread which is able to load an image
+     * or run animation (if the number of existing loader threads does not
+     * exceed the limit).
+     */
+    private static void createLoader() {
+        final ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+
+        synchronized(storage.loaders) {
+            if (storage.loaders.size() < ImageLoadersStorage.MAX_THREADS) {
+                AccessController.doPrivileged(
+                        new PrivilegedAction<Void>() {
+                            public Void run() {
+                                ImageLoader loader = new ImageLoader();
+                                storage.loaders.add(loader);
+                                loader.start();
+                                return null;
+                            }
+                        });
+            }
+        }
+    }
+
+    /**
+     * Adds a new image source to the queue and starts a new loader
+     * thread if required
+     * @param imgSrc - image source
+     */
+    public static void addImageSource(DecodingImageSource imgSrc) {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+        synchronized(storage.queue) {
+            if (!storage.queue.contains(imgSrc)) {
+                storage.queue.add(imgSrc);
+            }
+            if (storage.freeLoaders == 0) {
+                createLoader();
+            }
+
+            storage.queue.notify();
+        }
+    }
+
+    /**
+     * Waits for a new ImageSource until timout expires.
+     * Loader thread will terminate after returning from this method
+     * if timeout expired and image source was not picked up from the queue.
+     * @return image source picked up from the queue or null if timeout expired
+     */
+    private static DecodingImageSource getWaitingImageSource() {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+
+        synchronized(storage.queue) {
+            DecodingImageSource isrc = null;
+
+            if (storage.queue.size() == 0) {
+                try {
+                    storage.freeLoaders++;
+                    storage.queue.wait(ImageLoadersStorage.TIMEOUT);
+                } catch (InterruptedException e) {
+                    return null;
+                } finally {
+                    storage.freeLoaders--;
+                }
+            }
+
+            if (storage.queue.size() > 0) {
+                isrc = storage.queue.get(0);
+                storage.queue.remove(0);
+            }
+
+            return isrc;
+        }
+    }
+
+    /**
+     * Entry point of the loader thread. Picks up image sources and
+     * runs decoders for them while there are available image sources in the queue.
+     * If there are no and timeout expires it terminates.
+     */
+    @Override
+    public void run() {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+
+        try {
+            while (storage.loaders.contains(this)) {
+                Thread.interrupted(); // Reset the interrupted flag
+                DecodingImageSource isrc = getWaitingImageSource();
+                if (isrc != null) {
+                    try {
+                        isrc.load();
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                } else {
+                    break; // Don't wait if timeout expired - terminate loader
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            synchronized(storage.loaders) {
+                storage.loaders.remove(Thread.currentThread());
+            }
+        }
+    }
+
+    /**
+     * Removes current thread from loaders (so we are able
+     * to create more loaders) and decreases its priority.
+     */
+    static void beginAnimation() {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+        Thread currThread = Thread.currentThread();
+
+        synchronized(storage) {
+            storage.loaders.remove(currThread);
+
+            if (storage.freeLoaders < storage.queue.size()) {
+                createLoader();
+            }
+        }
+
+        currThread.setPriority(Thread.MIN_PRIORITY);
+    }
+
+    /**
+     * Sends the current thread to wait for the new images to load
+     * if there are free placeholders for loaders
+     */
+    static void endAnimation() {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+        Thread currThread = Thread.currentThread();
+
+        synchronized(storage) {
+            if (storage.loaders.size() < ImageLoadersStorage.MAX_THREADS &&
+                    !storage.loaders.contains(currThread)
+            ) {
+                storage.loaders.add(currThread);
+            }
+        }
+
+        currThread.setPriority(Thread.NORM_PRIORITY);
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java b/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java
new file mode 100644
index 0000000..2e64427
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java
@@ -0,0 +1,231 @@
+/*
+*  Licensed to the Apache Software Foundation (ASF) under one or more
+*  contributor license agreements.  See the NOTICE file distributed with
+*  this work for additional information regarding copyright ownership.
+*  The ASF licenses this file to You under the Apache License, Version 2.0
+*  (the "License"); you may not use this file except in compliance with
+*  the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*/
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.image.*;
+import java.awt.color.ColorSpace;
+import java.awt.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class JpegDecoder extends ImageDecoder {
+    // Only 2 output colorspaces expected. Others are converted into
+    // these ones.
+    // 1. Grayscale
+    public static final int JCS_GRAYSCALE = 1;
+    // 2. RGB
+    public static final int JCS_RGB = 2;
+
+    // Flags for the consumer, progressive JPEG
+    private static final int hintflagsProgressive =
+            ImageConsumer.SINGLEFRAME | // JPEG is a static image
+            ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
+            ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
+    // Flags for the consumer, singlepass JPEG
+    private static final int hintflagsSingle =
+            ImageConsumer.SINGLEPASS |
+            hintflagsProgressive;
+
+    // Buffer for the stream
+    private static final int BUFFER_SIZE = 1024;
+    private byte buffer[] = new byte[BUFFER_SIZE];
+
+    // 3 possible color models only
+    private static ColorModel cmRGB;
+    private static ColorModel cmGray;
+
+    // initializes proper field IDs
+    private static native void initIDs();
+
+    // Pointer to native structure which store decoding state
+    // between subsequent decoding/IO-suspension cycles
+    private long hNativeDecoder = 0; // NULL initially
+
+    private boolean headerDone = false;
+
+    // Next 4 members are filled by the native method (decompress).
+    // We can simply check if imageWidth is still negative to find
+    // out if they are already filled.
+    private int imageWidth = -1;
+    private int imageHeight = -1;
+    private boolean progressive = false;
+    private int jpegColorSpace = 0;
+
+    // Stores number of bytes consumed by the native decoder
+    private int bytesConsumed = 0;
+    // Stores current scanline returned by the decoder
+    private int currScanline = 0;
+
+    private ColorModel cm = null;
+
+    static {
+        System.loadLibrary("jpegdecoder"); //$NON-NLS-1$
+
+        cmGray = new ComponentColorModel(
+                ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                false, false,
+                Transparency.OPAQUE, DataBuffer.TYPE_BYTE
+        );
+
+        // Create RGB color model
+        cmRGB = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
+
+        initIDs();
+    }
+
+    public JpegDecoder(DecodingImageSource src, InputStream is) {
+        super(src, is);
+    }
+
+    /*
+    public JpegDecoder(InputStream iStream, ImageConsumer iConsumer) {
+    inputStream = iStream;
+    consumer = iConsumer;
+    }
+    */
+
+    /**
+     * @return - not NULL if call is successful
+     */
+    private native Object decode(
+            byte[] input,
+            int bytesInBuffer,
+            long hDecoder);
+
+    private static native void releaseNativeDecoder(long hDecoder);
+
+    @Override
+    public void decodeImage() throws IOException {
+        try {
+            int bytesRead = 0, dataLength = 0;
+            boolean eosReached = false;
+            int needBytes, offset, bytesInBuffer = 0;
+            byte byteOut[] = null;
+            int intOut[] = null;
+            // Read from the input stream
+            for (;;) {
+                needBytes = BUFFER_SIZE - bytesInBuffer;
+                offset = bytesInBuffer;
+
+                bytesRead = inputStream.read(buffer, offset, needBytes);
+
+                if (bytesRead < 0) {
+                    bytesRead = 0;//break;
+                    eosReached = true;
+                } // Don't break, maybe something left in buffer
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer += bytesRead;
+
+                // Here we pass overall number of bytes left in the java buffer
+                // (bytesInBuffer) since jpeg decoder has its own buffer and consumes
+                // as many bytes as it can. If there are any unconsumed bytes
+                // it didn't add them to its buffer...
+                Object arr = decode(
+                        buffer,
+                        bytesInBuffer,
+                        hNativeDecoder);
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer -= bytesConsumed;
+
+                if (!headerDone && imageWidth != -1) {
+                    returnHeader();
+                    headerDone = true;
+                }
+
+                if (bytesConsumed < 0) {
+                    break; // Error exit
+                }
+
+                if (arr instanceof byte[]) {
+                    byteOut = (byte[]) arr;
+                    dataLength = byteOut.length;
+                    returnData(byteOut, currScanline);
+                } else if (arr instanceof int[]) {
+                    intOut = (int[]) arr;
+                    dataLength = intOut.length;
+                    returnData(intOut, currScanline);
+                } else {
+                    dataLength = 0;
+                }
+
+                if (hNativeDecoder == 0) {
+                    break;
+                }
+
+                if (dataLength == 0 && eosReached) {
+                    releaseNativeDecoder(hNativeDecoder);
+                    break; // Probably image is truncated
+                }
+            }
+            imageComplete(ImageConsumer.STATICIMAGEDONE);
+        } catch (IOException e) {
+            throw e;
+        } finally {
+            closeStream();
+        }
+    }
+
+    public void returnHeader() {
+        setDimensions(imageWidth, imageHeight);
+
+        switch (jpegColorSpace) {
+            case JCS_GRAYSCALE: cm = cmGray; break;
+            case JCS_RGB: cm = cmRGB; break;
+            default: 
+                // awt.3D=Unknown colorspace
+                throw new IllegalArgumentException(Messages.getString("awt.3D")); //$NON-NLS-1$
+        }
+        setColorModel(cm);
+
+        setHints(progressive ? hintflagsProgressive : hintflagsSingle);
+
+        setProperties(new Hashtable<Object, Object>()); // Empty
+    }
+
+    // Send the data to the consumer
+    public void returnData(int data[], int currScanLine) {
+        // Send 1 or more scanlines to the consumer.
+        int numScanlines = data.length / imageWidth;
+        if (numScanlines > 0) {
+            setPixels(
+                    0, currScanLine - numScanlines,
+                    imageWidth, numScanlines,
+                    cm, data, 0, imageWidth
+            );
+        }
+    }
+
+    public void returnData(byte data[], int currScanLine) {
+        int numScanlines = data.length / imageWidth;
+        if (numScanlines > 0) {
+            setPixels(
+                    0, currScanLine - numScanlines,
+                    imageWidth, numScanlines,
+                    cm, data, 0, imageWidth
+            );
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java b/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java
new file mode 100644
index 0000000..3445f8e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java
@@ -0,0 +1,532 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 22.12.2004
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.IndexColorModel;
+import java.awt.image.WritableRaster;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * This class represent implementation of abstract Image class
+ */
+public class OffscreenImage extends Image implements ImageConsumer {
+
+    static final ColorModel rgbCM = ColorModel.getRGBdefault();
+    ImageProducer src;
+    BufferedImage image;
+    ColorModel cm;
+    WritableRaster raster;
+    boolean isIntRGB;
+    Hashtable<?, ?> properties;
+    Vector<ImageObserver> observers;
+    int width;
+    int height;
+    int imageState;
+    int hints;
+    private boolean producing;
+    private ImageSurface imageSurf;
+
+    public OffscreenImage(ImageProducer ip){
+        imageState = 0;
+        src = ip;
+        width = -1;
+        height = -1;
+        observers = new Vector<ImageObserver>();
+        producing = false;
+    }
+
+    @Override
+    public Object getProperty(String name, ImageObserver observer) {
+        if(name == null) {
+            // awt.38=Property name is not defined
+            throw new NullPointerException(Messages.getString("awt.38")); //$NON-NLS-1$
+        }
+        if(properties == null){
+            addObserver(observer);
+            startProduction();
+            if(properties == null) {
+                return null;
+            }
+        }
+        Object prop = properties.get(name);
+        if(prop == null) {
+            prop = UndefinedProperty;
+        }
+        return prop;
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return src;
+    }
+
+    @Override
+    public int getWidth(ImageObserver observer) {
+        if((imageState & ImageObserver.WIDTH) == 0){
+            addObserver(observer);
+            startProduction();
+            if((imageState & ImageObserver.WIDTH) == 0) {
+                return -1;
+            }
+        }
+        return width;
+    }
+
+    @Override
+    public int getHeight(ImageObserver observer) {
+        if((imageState & ImageObserver.HEIGHT) == 0){
+            addObserver(observer);
+            startProduction();
+            if((imageState & ImageObserver.HEIGHT) == 0) {
+                return -1;
+            }
+        }
+        return height;
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        // awt.39=This method is not implemented for image obtained from ImageProducer
+        throw new UnsupportedOperationException(Messages.getString("awt.39")); //$NON-NLS-1$
+    }
+
+    @Override
+    public void flush() {
+        stopProduction();
+        imageUpdate(this, ImageObserver.ABORT, -1, -1, -1, -1);
+        imageState &= ~ImageObserver.ERROR;
+        imageState = 0;
+        image = null;
+        cm = null;
+        raster = null;
+        hints = 0;
+        width = -1;
+        height = -1;
+    }
+
+    public void setProperties(Hashtable<?, ?> properties) {
+        this.properties = properties;
+        imageUpdate(this, ImageObserver.PROPERTIES, 0, 0, width, height);
+    }
+
+    public void setColorModel(ColorModel cm) {
+        this.cm = cm;
+    }
+
+    /*
+     * We suppose what in case loading JPEG image then image has DirectColorModel
+     * and for infill image Raster will use setPixels method with int array.
+     *
+     * In case loading GIF image, for raster infill, is used setPixels method with
+     * byte array and Color Model is IndexColorModel. But Color Model may
+     * be changed during this process. Then is called setPixels method with
+     * int array and image force to default color model - int ARGB. The rest
+     * pixels are sending in DirectColorModel.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            int[] pixels, int off, int scansize) {
+        if(raster == null){
+            if(cm == null){
+                if(model == null) {
+                    // awt.3A=Color Model is null
+                    throw new NullPointerException(Messages.getString("awt.3A")); //$NON-NLS-1$
+                }
+                cm = model;
+            }
+            createRaster();
+        }
+
+        if(model == null) {
+            model = cm;
+        }
+        if(cm != model){
+            forceToIntARGB();
+        }
+
+        if(cm == model && model.getTransferType() == DataBuffer.TYPE_INT &&
+                raster.getNumDataElements() == 1){
+
+            DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
+            int data[] = dbi.getData();
+            int scanline = raster.getWidth();
+            int rof = dbi.getOffset() + y * scanline + x;
+            for(int lineOff = off, line = y; line < y + h;
+                line++, lineOff += scansize, rof += scanline){
+
+                System.arraycopy(pixels, lineOff, data, rof, w);
+            }
+
+        }else if(isIntRGB){
+            int buff[] = new int[w];
+            DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
+            int data[] = dbi.getData();
+            int scanline = raster.getWidth();
+            int rof = dbi.getOffset() + y * scanline + x;
+            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize,
+                rof += scanline) {
+
+                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                    buff[idx] = model.getRGB(pixels[sOff + idx]);
+                }
+                System.arraycopy(buff, 0, data, rof, w);
+            }
+        }else{
+            Object buf = null;
+            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize) {
+                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                    int rgb = model.getRGB(pixels[sOff + idx]);
+                    buf = cm.getDataElements(rgb, buf);
+                    raster.setDataElements(sx, sy, buf);
+                }
+            }
+        }
+
+        if (imageSurf != null) {
+            imageSurf.invalidate();
+        }
+
+        imageUpdate(this, ImageObserver.SOMEBITS, 0, 0, width, height);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            byte[] pixels, int off, int scansize) {
+
+        if(raster == null){
+            if(cm == null){
+                if(model == null) {
+                    // awt.3A=Color Model is null
+                    throw new NullPointerException(Messages.getString("awt.3A")); //$NON-NLS-1$
+                }
+                cm = model;
+            }
+            createRaster();
+        }
+        if(model == null) {
+            model = cm;
+        }
+        if(model != cm){
+            forceToIntARGB();
+        }
+
+        if(isIntRGB){
+            int buff[] = new int[w];
+            IndexColorModel icm = (IndexColorModel) model;
+            int colorMap[] = new int[icm.getMapSize()];
+            icm.getRGBs(colorMap);
+            DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
+            int data[] = dbi.getData();
+            int scanline = raster.getWidth();
+            int rof = dbi.getOffset() + y * scanline + x;
+            if(model instanceof IndexColorModel){
+
+                for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize,
+                    rof += scanline) {
+                    for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                        buff[idx] = colorMap[pixels[sOff + idx] & 0xff];
+                    }
+                    System.arraycopy(buff, 0, data, rof, w);
+                }
+            }else{
+
+                for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize,
+                    rof += scanline) {
+                    for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                        buff[idx] = model.getRGB(pixels[sOff + idx] & 0xff);
+                    }
+                    System.arraycopy(buff, 0, data, rof, w);
+                }
+            }
+        }else if(model == cm && model.getTransferType() == DataBuffer.TYPE_BYTE &&
+                raster.getNumDataElements() == 1){
+
+            DataBufferByte dbb = (DataBufferByte)raster.getDataBuffer();
+            byte data[] = dbb.getData();
+            int scanline = raster.getWidth();
+            int rof = dbb.getOffset() + y * scanline + x;
+            for(int lineOff = off, line = y; line < y + h;
+                line++, lineOff += scansize, rof += scanline){
+                System.arraycopy(pixels, lineOff, data, rof, w);
+            }
+        // BEGIN android-added (taken from newer Harmony)
+        }else if(model == cm && model.getTransferType() == DataBuffer.TYPE_BYTE &&
+                cm instanceof ComponentColorModel){
+
+            int nc = cm.getNumComponents();
+            byte stride[] = new byte[scansize];
+            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize) {
+                System.arraycopy(pixels, sOff, stride, 0, scansize);
+                
+                raster.setDataElements(x, sy, w, 1, stride);
+            }
+        // END android-added
+        }else {
+            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize) {
+                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                    int rgb = model.getRGB(pixels[sOff + idx] & 0xff);
+                    raster.setDataElements(sx, sy, cm.getDataElements(rgb, null));
+                }
+            }
+        }
+
+        if (imageSurf != null) {
+            imageSurf.invalidate();
+        }
+
+        imageUpdate(this, ImageObserver.SOMEBITS, 0, 0, width, height);
+    }
+
+    public void setDimensions(int width, int height) {
+        if(width <= 0 || height <= 0){
+            imageComplete(ImageObserver.ERROR);
+            return;
+        }
+
+        this.width = width;
+        this.height = height;
+        imageUpdate(this, (ImageObserver.HEIGHT | ImageObserver.WIDTH),
+                0, 0, width, height);
+    }
+
+    public void setHints(int hints) {
+        this.hints = hints;
+    }
+
+    public void imageComplete(int state) {
+        int flag;
+        switch(state){
+        case IMAGEABORTED:
+            flag = ImageObserver.ABORT;
+            break;
+        case IMAGEERROR:
+            flag = ImageObserver.ERROR | ImageObserver.ABORT;
+            break;
+        case SINGLEFRAMEDONE:
+            flag = ImageObserver.FRAMEBITS;
+            break;
+        case STATICIMAGEDONE:
+            flag = ImageObserver.ALLBITS;
+            break;
+        default:
+            // awt.3B=Incorrect ImageConsumer completion status
+            throw new IllegalArgumentException(Messages.getString("awt.3B")); //$NON-NLS-1$
+        }
+        imageUpdate(this, flag, 0, 0, width, height);
+
+        if((flag & (ImageObserver.ERROR | ImageObserver.ABORT |
+                ImageObserver.ALLBITS)) != 0 ) {
+            stopProduction();
+            observers.removeAllElements();
+        }
+    }
+
+    public /*synchronized*/ BufferedImage getBufferedImage(){
+        if(image == null){
+            ColorModel model = getColorModel();
+            WritableRaster wr = getRaster();
+            if(model != null && wr != null) {
+                image = new BufferedImage(model, wr, model.isAlphaPremultiplied(), null);
+            }
+        }
+        return image;
+    }
+
+    public /*synchronized*/ int checkImage(ImageObserver observer){
+        addObserver(observer);
+        return imageState;
+    }
+
+    public /*synchronized*/ boolean prepareImage(ImageObserver observer){
+        if((imageState & ImageObserver.ERROR) != 0){
+            if(observer != null){
+                observer.imageUpdate(this, ImageObserver.ERROR |
+                        ImageObserver.ABORT, -1, -1, -1, -1);
+            }
+            return false;
+        }
+        if((imageState & ImageObserver.ALLBITS) != 0) {
+            return true;
+        }
+        addObserver(observer);
+        startProduction();
+        return ((imageState & ImageObserver.ALLBITS) != 0);
+    }
+
+    public /*synchronized*/ ColorModel getColorModel(){
+        if(cm == null) {
+            startProduction();
+        }
+        return cm;
+    }
+
+    public /*synchronized*/ WritableRaster getRaster(){
+        if(raster == null) {
+            startProduction();
+        }
+        return raster;
+    }
+
+    public int getState(){
+        return imageState;
+    }
+
+    private /*synchronized*/ void addObserver(ImageObserver observer){
+        if(observer != null){
+          if(observers.contains(observer)) {
+            return;
+        }
+          if((imageState & ImageObserver.ERROR) != 0){
+              observer.imageUpdate(this, ImageObserver.ERROR |
+                      ImageObserver.ABORT, -1, -1, -1, -1);
+              return;
+          }
+          if((imageState & ImageObserver.ALLBITS) != 0){
+              observer.imageUpdate(this, imageState, 0, 0, width, height);
+              return;
+          }
+          observers.addElement(observer);
+        }
+    }
+
+    private synchronized void startProduction(){
+        if(!producing){
+            imageState &= ~ImageObserver.ABORT;
+            producing = true;
+            src.startProduction(this);
+        }
+    }
+
+    private synchronized void stopProduction(){
+        producing = false;
+        src.removeConsumer(this);
+    }
+
+    private void createRaster(){
+        try{
+            raster = cm.createCompatibleWritableRaster(width, height);
+            isIntRGB = false;
+            if(cm instanceof DirectColorModel){
+                DirectColorModel dcm = (DirectColorModel) cm;
+                if(dcm.getTransferType() == DataBuffer.TYPE_INT &&
+                        dcm.getRedMask() == 0xff0000 &&
+                        dcm.getGreenMask() == 0xff00 &&
+                        dcm.getBlueMask() == 0xff){
+                    isIntRGB = true;
+                }
+            }
+        }catch(Exception e){
+            cm = ColorModel.getRGBdefault();
+            raster = cm.createCompatibleWritableRaster(width, height);
+            isIntRGB = true;
+        }
+    }
+
+    private /*synchronized*/ void imageUpdate(Image img, int infoflags, int x, int y,
+            int width, int height){
+
+        imageState |= infoflags;
+        for (ImageObserver observer : observers) {
+            observer.imageUpdate(this, infoflags, x, y, width, height);
+        }
+
+//            notifyAll();
+    }
+
+    private void forceToIntARGB(){
+
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        WritableRaster destRaster = rgbCM.createCompatibleWritableRaster(w, h);
+
+        Object obj = null;
+        int pixels[] = new int[w];
+
+        if(cm instanceof IndexColorModel){
+            IndexColorModel icm = (IndexColorModel) cm;
+            int colorMap[] = new int[icm.getMapSize()];
+            icm.getRGBs(colorMap);
+
+            for (int y = 0; y < h; y++) {
+                obj = raster.getDataElements(0, y, w, 1, obj);
+                byte ba[] = (byte[]) obj;
+                for (int x = 0; x < ba.length; x++) {
+                    pixels[x] = colorMap[ba[x] & 0xff];
+                }
+                destRaster.setDataElements(0, y, w, 1, pixels);
+            }
+
+        }else{
+            for(int y = 0; y < h; y++){
+                for(int x = 0; x < w; x++){
+                    obj = raster.getDataElements(x, y, obj);
+                    pixels[x] = cm.getRGB(obj);
+                }
+                destRaster.setDataElements(0, y, w, 1, pixels);
+            }
+        }
+
+        synchronized(this){
+            if(imageSurf != null){
+                imageSurf.dispose();
+                imageSurf = null;
+            }
+            if(image != null){
+                image.flush();
+                image = null;
+            }
+            cm = rgbCM;
+            raster = destRaster;
+            isIntRGB = true;
+        }
+    }
+
+    public ImageSurface getImageSurface() {
+        if (imageSurf == null) {
+            ColorModel model = getColorModel();
+            WritableRaster wr = getRaster();
+            if(model != null && wr != null) {
+                imageSurf = new ImageSurface(model, wr);
+            }
+        }
+        return imageSurf;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java b/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java
new file mode 100644
index 0000000..1748e1b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java
@@ -0,0 +1,153 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 30.09.2004
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+
+public class OrdinaryWritableRaster extends WritableRaster {
+
+    public OrdinaryWritableRaster(SampleModel sampleModel,
+            DataBuffer dataBuffer, Rectangle aRegion,
+            Point sampleModelTranslate, WritableRaster parent) {
+        super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
+    }
+
+    public OrdinaryWritableRaster(SampleModel sampleModel,
+            DataBuffer dataBuffer, Point origin) {
+        super(sampleModel, dataBuffer, origin);
+    }
+
+    public OrdinaryWritableRaster(SampleModel sampleModel, Point origin) {
+        super(sampleModel, origin);
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object inData) {
+        super.setDataElements(x, y, inData);
+    }
+
+    @Override
+    public void setDataElements(int x, int y, int w, int h, Object inData) {
+        super.setDataElements(x, y, w, h, inData);
+    }
+
+    @Override
+    public WritableRaster createWritableChild(int parentX, int parentY, int w,
+            int h, int childMinX, int childMinY, int[] bandList) {
+        return super.createWritableChild(parentX, parentY, w, h, childMinX,
+                childMinY, bandList);
+    }
+
+    @Override
+    public WritableRaster createWritableTranslatedChild(int childMinX,
+            int childMinY) {
+        return super.createWritableTranslatedChild(childMinX, childMinY);
+    }
+
+    @Override
+    public WritableRaster getWritableParent() {
+        return super.getWritableParent();
+    }
+
+    @Override
+    public void setRect(Raster srcRaster) {
+        super.setRect(srcRaster);
+    }
+
+    @Override
+    public void setRect(int dx, int dy, Raster srcRaster) {
+        super.setRect(dx, dy, srcRaster);
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Raster inRaster) {
+        super.setDataElements(x, y, inRaster);
+    }
+
+    @Override
+    public void setPixel(int x, int y, int[] iArray) {
+        super.setPixel(x, y, iArray);
+    }
+
+    @Override
+    public void setPixel(int x, int y, float[] fArray) {
+        super.setPixel(x, y, fArray);
+    }
+
+    @Override
+    public void setPixel(int x, int y, double[] dArray) {
+        super.setPixel(x, y, dArray);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int[] iArray) {
+        super.setPixels(x, y, w, h, iArray);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, float[] fArray) {
+        super.setPixels(x, y, w, h, fArray);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, double[] dArray) {
+        super.setPixels(x, y, w, h, dArray);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int[] iArray) {
+        super.setSamples(x, y, w, h, b, iArray);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, float[] fArray) {
+        super.setSamples(x, y, w, h, b, fArray);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, double[] dArray) {
+        super.setSamples(x, y, w, h, b, dArray);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s) {
+        super.setSample(x, y, b, s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s) {
+        super.setSample(x, y, b, s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s) {
+        super.setSample(x, y, b, s);
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/PngDecoder.java b/awt/org/apache/harmony/awt/gl/image/PngDecoder.java
new file mode 100644
index 0000000..7e85600
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/PngDecoder.java
@@ -0,0 +1,270 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Jul 22, 2005
+ */
+
+package org.apache.harmony.awt.gl.image;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.awt.color.ColorSpace;
+import java.awt.image.*;
+import java.awt.*;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class PngDecoder extends ImageDecoder {
+    // initializes proper field IDs
+    private static native void initIDs();
+
+    static {
+        System.loadLibrary("gl"); //$NON-NLS-1$
+        initIDs();
+    }
+
+    private static final int hintflags =
+            ImageConsumer.SINGLEFRAME | // PNG is a static image
+            ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
+            ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
+
+    // Each pixel is a grayscale sample.
+    private static final int PNG_COLOR_TYPE_GRAY = 0;
+    // Each pixel is an R,G,B triple.
+    private static final int PNG_COLOR_TYPE_RGB = 2;
+    // Each pixel is a palette index, a PLTE chunk must appear.
+    private static final int PNG_COLOR_TYPE_PLTE = 3;
+    // Each pixel is a grayscale sample, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
+    // Each pixel is an R,G,B triple, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_RGBA = 6;
+
+    private static final int INPUT_BUFFER_SIZE = 4096;
+    private byte buffer[] = new byte[INPUT_BUFFER_SIZE];
+
+    // Buffers for decoded image data
+    byte byteOut[];
+    int intOut[];
+
+    // Native pointer to png decoder data
+    private long hNativeDecoder;
+
+    int imageWidth, imageHeight;
+    int colorType;
+    int bitDepth;
+    byte cmap[];
+
+    boolean transferInts; // Is transfer type int?.. or byte?
+    int dataElementsPerPixel = 1;
+
+    ColorModel cm;
+
+    int updateFromScanline; // First scanline to update
+    int numScanlines; // Number of scanlines to update
+
+    private native long decode(byte[] input, int bytesInBuffer, long hDecoder);
+
+    private static native void releaseNativeDecoder(long hDecoder);
+
+    public PngDecoder(DecodingImageSource src, InputStream is) {
+        super(src, is);
+    }
+
+    @Override
+    public void decodeImage() throws IOException {
+        try {
+            int bytesRead = 0;
+            int needBytes, offset, bytesInBuffer = 0;
+            // Read from the input stream
+            for (;;) {
+                needBytes = INPUT_BUFFER_SIZE - bytesInBuffer;
+                offset = bytesInBuffer;
+
+                bytesRead = inputStream.read(buffer, offset, needBytes);
+
+                if (bytesRead < 0) { // Break, nothing to read from buffer, image truncated?
+                    releaseNativeDecoder(hNativeDecoder);
+                    break;
+                }
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer += bytesRead;
+                hNativeDecoder = decode(buffer, bytesInBuffer, hNativeDecoder);
+                // PNG decoder always consumes all bytes at once
+                bytesInBuffer = 0;
+
+                // if (bytesConsumed < 0)
+                //break; // Error exit
+
+                returnData();
+
+                // OK, we decoded all the picture in the right way...
+                if (hNativeDecoder == 0) {
+                    break;
+                }
+            }
+
+            imageComplete(ImageConsumer.STATICIMAGEDONE);
+        } catch (IOException e) {
+            throw e;
+        } catch (RuntimeException e) {
+            imageComplete(ImageConsumer.IMAGEERROR);
+            throw e;
+        } finally {
+            closeStream();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private void returnHeader() { // Called from native code
+        setDimensions(imageWidth, imageHeight);
+
+        switch (colorType) {
+            case PNG_COLOR_TYPE_GRAY: {
+                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                // Create gray color model
+                int numEntries = 1 << bitDepth;
+                int scaleFactor = 255 / (numEntries-1);
+                byte comps[] = new byte[numEntries];
+                for (int i = 0; i < numEntries; i++) {
+                    comps[i] = (byte) (i * scaleFactor);
+                }
+                cm = new IndexColorModel(/*bitDepth*/8, numEntries, comps, comps, comps);
+
+                transferInts = false;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_RGB: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
+
+                transferInts = true;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_PLTE: {
+                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = new IndexColorModel(/*bitDepth*/8, cmap.length / 3, cmap, 0, false);
+
+                transferInts = false;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_GRAY_ALPHA: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                        true, false,
+                        Transparency.TRANSLUCENT,
+                        DataBuffer.TYPE_BYTE);
+
+                transferInts = false;
+                dataElementsPerPixel = 2;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_RGBA: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = ColorModel.getRGBdefault();
+
+                transferInts = true;
+                break;
+            }
+            default:
+                // awt.3C=Unknown PNG color type
+                throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+        }
+
+        // Create output buffer
+        if (transferInts) {
+            intOut = new int[imageWidth * imageHeight];
+        } else {
+            byteOut = new byte[imageWidth * imageHeight * dataElementsPerPixel];
+        }
+
+        setColorModel(cm);
+
+        setHints(hintflags);
+        setProperties(new Hashtable<Object, Object>()); // Empty
+    }
+
+    // Send the data to the consumer
+    private void returnData() {
+        // Send 1 or more scanlines to the consumer.
+        if (numScanlines > 0) {
+            // Native decoder could have returned
+            // some data from the next pass, handle it here
+            int pass1, pass2;
+            if (updateFromScanline + numScanlines > imageHeight) {
+                pass1 = imageHeight - updateFromScanline;
+                pass2 = updateFromScanline + numScanlines - imageHeight;
+            } else {
+                pass1 = numScanlines;
+                pass2 = 0;
+            }
+
+            transfer(updateFromScanline, pass1);
+            if (pass2 != 0) {
+                transfer(0, pass2);
+            }
+        }
+    }
+
+    private void transfer(int updateFromScanline, int numScanlines) {
+        if (transferInts) {
+            setPixels(
+                    0, updateFromScanline,
+                    imageWidth, numScanlines,
+                    cm, intOut,
+                    updateFromScanline * imageWidth,
+                    imageWidth
+            );
+        } else {
+            setPixels(
+                    0, updateFromScanline,
+                    imageWidth, numScanlines,
+                    cm, byteOut,
+                    updateFromScanline * imageWidth * dataElementsPerPixel,
+                    imageWidth * dataElementsPerPixel
+            );
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java b/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java
new file mode 100644
index 0000000..46545f9
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java
@@ -0,0 +1,282 @@
+package org.apache.harmony.awt.gl.image;
+
+// A simple PNG decoder source code in Java.
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.zip.CRC32;
+import java.util.zip.InflaterInputStream;
+
+//import javax.swing.JFrame;
+
+public class PngDecoderJava {
+ 
+/*
+  public static void main(String[] args) throws Exception {
+    String name = "logo.png";
+    if (args.length > 0)
+      name = args[0];
+    InputStream in = PngDecoderJava.class.getResourceAsStream(name);
+    final BufferedImage image = PngDecoderJava.decode(in);
+    in.close();
+
+    JFrame f = new JFrame() {
+      public void paint(Graphics g) {
+        Insets insets = getInsets();
+        g.drawImage(image, insets.left, insets.top, null);
+      }
+    };
+    f.setVisible(true);
+    Insets insets = f.getInsets();
+    f.setSize(image.getWidth() + insets.left + insets.right, image
+        .getHeight()
+        + insets.top + insets.bottom);
+  }
+  */
+
+  public static BufferedImage decode(InputStream in) throws IOException {
+    DataInputStream dataIn = new DataInputStream(in);
+    readSignature(dataIn);
+    PNGData chunks = readChunks(dataIn);
+
+    long widthLong = chunks.getWidth();
+    long heightLong = chunks.getHeight();
+    if (widthLong > Integer.MAX_VALUE || heightLong > Integer.MAX_VALUE)
+      throw new IOException("That image is too wide or tall.");
+    int width = (int) widthLong;
+    int height = (int) heightLong;
+
+    ColorModel cm = chunks.getColorModel();
+    WritableRaster raster = chunks.getRaster();
+
+    BufferedImage image = new BufferedImage(cm, raster, false, null);
+
+    return image;
+  }
+
+  protected static void readSignature(DataInputStream in) throws IOException {
+    long signature = in.readLong();
+    if (signature != 0x89504e470d0a1a0aL)
+      throw new IOException("PNG signature not found!");
+  }
+
+  protected static PNGData readChunks(DataInputStream in) throws IOException {
+    PNGData chunks = new PNGData();
+
+    boolean trucking = true;
+    while (trucking) {
+      try {
+        // Read the length.
+        int length = in.readInt();
+        if (length < 0)
+          throw new IOException("Sorry, that file is too long.");
+        // Read the type.
+        byte[] typeBytes = new byte[4];
+        in.readFully(typeBytes);
+        // Read the data.
+        byte[] data = new byte[length];
+        in.readFully(data);
+        // Read the CRC.
+        long crc = in.readInt() & 0x00000000ffffffffL; // Make it
+        // unsigned.
+        if (verifyCRC(typeBytes, data, crc) == false)
+          throw new IOException("That file appears to be corrupted.");
+
+        PNGChunk chunk = new PNGChunk(typeBytes, data);
+        chunks.add(chunk);
+      } catch (EOFException eofe) {
+        trucking = false;
+      }
+    }
+    return chunks;
+  }
+
+  protected static boolean verifyCRC(byte[] typeBytes, byte[] data, long crc) {
+    CRC32 crc32 = new CRC32();
+    crc32.update(typeBytes);
+    crc32.update(data);
+    long calculated = crc32.getValue();
+    return (calculated == crc);
+  }
+}
+
+class PNGData {
+  private int mNumberOfChunks;
+
+  private PNGChunk[] mChunks;
+
+  public PNGData() {
+    mNumberOfChunks = 0;
+    mChunks = new PNGChunk[10];
+  }
+
+  public void add(PNGChunk chunk) {
+    mChunks[mNumberOfChunks++] = chunk;
+    if (mNumberOfChunks >= mChunks.length) {
+      PNGChunk[] largerArray = new PNGChunk[mChunks.length + 10];
+      System.arraycopy(mChunks, 0, largerArray, 0, mChunks.length);
+      mChunks = largerArray;
+    }
+  }
+
+  public long getWidth() {
+    return getChunk("IHDR").getUnsignedInt(0);
+  }
+
+  public long getHeight() {    return getChunk("IHDR").getUnsignedInt(4);
+  }
+
+  public short getBitsPerPixel() {
+    return getChunk("IHDR").getUnsignedByte(8);
+  }
+
+  public short getColorType() {
+    return getChunk("IHDR").getUnsignedByte(9);
+  }
+
+  public short getCompression() {
+    return getChunk("IHDR").getUnsignedByte(10);
+  }
+
+  public short getFilter() {
+    return getChunk("IHDR").getUnsignedByte(11);
+  }
+
+  public short getInterlace() {
+    return getChunk("IHDR").getUnsignedByte(12);
+  }
+
+  public ColorModel getColorModel() {
+    short colorType = getColorType();
+    int bitsPerPixel = getBitsPerPixel();
+
+    if (colorType == 3) {
+      byte[] paletteData = getChunk("PLTE").getData();
+      int paletteLength = paletteData.length / 3;
+      return new IndexColorModel(bitsPerPixel, paletteLength,
+          paletteData, 0, false);
+    }
+    System.out.println("Unsupported color type: " + colorType);
+    return null;
+  }
+
+  public WritableRaster getRaster() {
+    int width = (int) getWidth();
+    int height = (int) getHeight();
+    int bitsPerPixel = getBitsPerPixel();
+    short colorType = getColorType();
+
+    if (colorType == 3) {
+      byte[] imageData = getImageData();
+      //Orig: DataBuffer db = new DataBufferByte(imageData, imageData.length);
+      int len = Math.max(imageData.length, (width - 1) * (height -1));
+      DataBuffer db = new DataBufferByte(imageData, len);
+      WritableRaster raster = Raster.createPackedRaster(db, width,
+          height, bitsPerPixel, null);
+      return raster;
+    } else
+      System.out.println("Unsupported color type!");
+    return null;
+  }
+
+  public byte[] getImageData() {
+    try {
+      ByteArrayOutputStream out = new ByteArrayOutputStream();
+      // Write all the IDAT data into the array.
+      for (int i = 0; i < mNumberOfChunks; i++) {
+        PNGChunk chunk = mChunks[i];
+        if (chunk.getTypeString().equals("IDAT")) {
+          out.write(chunk.getData());
+        }
+      }
+      out.flush();
+      // Now deflate the data.
+      InflaterInputStream in = new InflaterInputStream(
+          new ByteArrayInputStream(out.toByteArray()));
+      ByteArrayOutputStream inflatedOut = new ByteArrayOutputStream();
+      int readLength;
+      byte[] block = new byte[8192];
+      while ((readLength = in.read(block)) != -1)
+        inflatedOut.write(block, 0, readLength);
+      inflatedOut.flush();
+      byte[] imageData = inflatedOut.toByteArray();
+      // Compute the real length.
+      int width = (int) getWidth();
+      int height = (int) getHeight();
+      int bitsPerPixel = getBitsPerPixel();
+      int length = width * height * bitsPerPixel / 8;
+
+      byte[] prunedData = new byte[length];
+
+      // We can only deal with non-interlaced images.
+      if (getInterlace() == 0) {
+        int index = 0;
+        for (int i = 0; i < length; i++) {
+          if ((i * 8 / bitsPerPixel) % width == 0) {
+            index++; // Skip the filter byte.
+          }
+          prunedData[i] = imageData[index++];
+        }
+      } else
+        System.out.println("Couldn't undo interlacing.");
+
+      return prunedData;
+    } catch (IOException ioe) {
+    }
+    return null;
+  }
+
+  public PNGChunk getChunk(String type) {
+    for (int i = 0; i < mNumberOfChunks; i++)
+      if (mChunks[i].getTypeString().equals(type))
+        return mChunks[i];
+    return null;
+  }
+}
+
+class PNGChunk {
+  private byte[] mType;
+
+  private byte[] mData;
+
+  public PNGChunk(byte[] type, byte[] data) {
+    mType = type;
+    mData = data;
+  }
+
+  public String getTypeString() {
+    try {
+      return new String(mType, "UTF8");
+    } catch (UnsupportedEncodingException uee) {
+      return "";
+    }
+  }
+
+  public byte[] getData() {
+    return mData;
+  }
+
+  public long getUnsignedInt(int offset) {
+    long value = 0;
+    for (int i = 0; i < 4; i++)
+      value += (mData[offset + i] & 0xff) << ((3 - i) * 8);
+    return value;
+  }
+
+  public short getUnsignedByte(int offset) {
+    return (short) (mData[offset] & 0x00ff);
+  }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java
new file mode 100644
index 0000000..a1899d6
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java
@@ -0,0 +1,77 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 10.02.2005
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.Permission;
+
+public class URLDecodingImageSource extends DecodingImageSource {
+
+    URL url;
+
+    public URLDecodingImageSource(URL url){
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkConnect(url.getHost(), url.getPort());
+            try {
+                Permission p = url.openConnection().getPermission();
+                security.checkPermission(p);
+            } catch (IOException e) {
+            }
+        }
+        this.url = url;
+    }
+
+    @Override
+    protected boolean checkConnection() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            try {
+                security.checkConnect(url.getHost(), url.getPort());
+                return true;
+            } catch (SecurityException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    protected InputStream getInputStream() {
+        try{
+            URLConnection uc = url.openConnection();
+            // BEGIN android-modified
+            return new BufferedInputStream(uc.getInputStream(), 8192);
+            // END android-modified
+        }catch(IOException e){
+            return null;
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/Blitter.java b/awt/org/apache/harmony/awt/gl/render/Blitter.java
new file mode 100644
index 0000000..3b8012e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/Blitter.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 14.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.geom.AffineTransform;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+
+/**
+ * The interface for objects which can drawing Images on other Images which have 
+ * Graphics or on the display.  
+ */
+public interface Blitter {
+
+    public abstract void blit(int srcX, int srcY, Surface srcSurf,
+            int dstX, int dstY, Surface dstSurf, int width, int height,
+            AffineTransform sysxform, AffineTransform xform,
+            Composite comp, Color bgcolor,
+            MultiRectArea clip);
+
+    public abstract void blit(int srcX, int srcY, Surface srcSurf,
+            int dstX, int dstY, Surface dstSurf, int width, int height,
+            AffineTransform sysxform, Composite comp, Color bgcolor,
+            MultiRectArea clip);
+
+    public abstract void blit(int srcX, int srcY, Surface srcSurf,
+            int dstX, int dstY, Surface dstSurf, int width, int height,
+            Composite comp, Color bgcolor, MultiRectArea clip);
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java b/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java
new file mode 100644
index 0000000..b643b41
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java
@@ -0,0 +1,502 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.render;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+
+public class JavaArcRasterizer {
+
+    /**
+     * Adds particular arc segment to mra 
+     */
+    static void addX0LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int x1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x2 = line[i];
+            int y = cy + (b - i);
+            if (x1 <= finish && x2 >= start) {
+                mra.addRect(cx + Math.max(x1, start), y, cx + Math.min(x2, finish), y);
+            }
+            x1 = x2 + 1;
+        }
+    }
+
+    static void addX1LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int x1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x2 = line[i];
+            int y = cy - (b - i);
+            if (x1 <= finish && x2 >= start) {
+                mra.addRect(cx + Math.max(x1, start), y, cx + Math.min(x2, finish), y);
+            }
+            x1 = x2 + 1;
+        }
+    }
+
+    static void addX2LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int x1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x2 = line[i];
+            int y = cy - (b - i);
+            if (x1 <= finish && x2 >= start) {
+                mra.addRect(cx - Math.min(x2, finish), y, cx - Math.max(x1, start), y);
+            }
+            x1 = x2 + 1;
+        }
+    }
+
+    static void addX3LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int x1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x2 = line[i];
+            int y = cy + (b - i);
+            if (x1 <= finish && x2 >= start) {
+                mra.addRect(cx - Math.min(x2, finish), y, cx - Math.max(x1, start), y);
+            }
+            x1 = x2 + 1;
+        }
+    }
+
+    static void addY0LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int y1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x = cx + (b - i);
+            int y2 = line[i];
+            if (y1 <= finish && y2 >= start) {
+                mra.addRect(x, cy + Math.max(y1, start), x, cy + Math.min(y2, finish));
+            }
+            y1 = y2 + 1;
+        }
+    }
+
+    static void addY1LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int y1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x = cx - (b - i);
+            int y2 = line[i];
+            if (y1 <= finish && y2 >= start) {
+                mra.addRect(x, cy + Math.max(y1, start), x, cy + Math.min(y2, finish));
+            }
+            y1 = y2 + 1;
+        }
+    }
+
+    static void addY2LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int y1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x = cx - (b - i);
+            int y2 = line[i];
+            if (y1 <= finish && y2 >= start) {
+                mra.addRect(x, cy - Math.min(y2, finish), x, cy - Math.max(y1, start));
+            }
+            y1 = y2 + 1;
+        }
+    }
+
+    static void addY3LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int y1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x = cx + (b - i);
+            int y2 = line[i];
+            if (y1 <= finish && y2 >= start) {
+                mra.addRect(x, cy - Math.min(y2, finish), x, cy - Math.max(y1, start));
+            }
+            y1 = y2 + 1;
+        }
+    }
+
+    static void addX0Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx + prev, cy + (b - i), cx + line[i], cy + (b - i));
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addX1Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx + prev, cy - (b - i), cx + line[i], cy - (b - i));
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addX2Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx - line[i], cy - (b - i), cx - prev, cy - (b - i));
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addX3Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx - line[i], cy + (b - i), cx - prev, cy + (b - i));
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addY0Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx + (a - i), cy + prev, cx + (a - i), cy + line[i]);
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addY1Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx - (a - i), cy + prev, cx - (a - i), cy + line[i]);
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addY2Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx - (a - i), cy - line[i], cx - (a - i), cy - prev);
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addY3Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx + (a - i), cy - line[i], cx + (a - i), cy - prev);
+            prev = line[i] + 1;
+        }
+    }
+
+    /**
+     * Returns normalized angle (from 0 to 360 degrees)
+     */
+    static double getNormAngle(double angle) {
+        angle -= Math.floor(angle / 360) * 360;
+        if (angle < 0) {
+            angle += 360;
+        }
+        return angle;
+    }
+
+    /**
+     * Creates arc lookup table
+     */
+    static int[] createLine(int a, int b, int xcount, int ycount) {
+        int[] buf = new int[b - ycount + 1];
+        int d = a * a + 2 * b * b - 2 * a * a * b;
+        int x = 0;
+        int y = b;
+        while (y >= ycount) {
+            if (d < 0) {
+                d = d + b * b * (4 * x + 6);
+            } else {
+                buf[b - y] = x;
+                d = d + b * b * (4 * x + 6) + 4 * a * a * (1 - y);
+                y--;
+            }
+            x++;
+        }
+        return buf;
+    }
+
+    /**
+     * Adds head/tail arc segment to MultiRectArea
+     */
+    static void addSeg(MultiRectArea mra, int cx1, int cy1, int cx2, int cy2, int a, int b, int[] xline, int[] yline, int[] bounds) {
+        switch(bounds[0]) {
+        case 0:
+            addY3LineSeg(mra, yline, cx2, cy1, a, bounds[1], bounds[2]);
+            break;
+        case 1:
+            addX1LineSeg(mra, xline, cx2, cy1, b, bounds[1], bounds[2]);
+            break;
+        case 2:
+            addX2LineSeg(mra, xline, cx1, cy1, b, bounds[1], bounds[2]);
+            break;
+        case 3:
+            addY2LineSeg(mra, yline, cx1, cy1, a, bounds[1], bounds[2]);
+            break;
+        case 4:
+            addY1LineSeg(mra, yline, cx1, cy2, a, bounds[1], bounds[2]);
+            break;
+        case 5:
+            addX3LineSeg(mra, xline, cx1, cy2, b, bounds[1], bounds[2]);
+            break;
+        case 6:
+            addX0LineSeg(mra, xline, cx2, cy2, b, bounds[1], bounds[2]);
+            break;
+        case 7:
+            addY0LineSeg(mra, yline, cx2, cy2, a, bounds[1], bounds[2]);
+            break;
+        }
+    }
+
+    /**
+     * Returns bounds for non quadratic arc head
+     */
+    static int[] getSegment1(double angle, int ax, int ay, int xcount, int ycount) {
+        int[] bounds = new int[3];
+        switch((int)(angle / 90)) {
+        case 0:
+            if (xcount <  ax) {
+                bounds[0] = 0; // Y3
+                bounds[1] = -ay;
+                bounds[2] = ycount;
+            } else {
+                bounds[0] = 1; // X1
+                bounds[1] = 0;
+                bounds[2] = ax;
+            }
+            break;
+        case 1:
+            if (xcount > -ax) {
+                bounds[0] = 2; // X2
+                bounds[1] = -ax;
+                bounds[2] = xcount;
+            } else {
+                bounds[0] = 3; // Y2
+                bounds[1] = 0;
+                bounds[2] = -ay;
+            }
+            break;
+        case 2:
+            if (xcount < -ax) {
+                bounds[0] = 4; // Y1
+                bounds[1] = ay;
+                bounds[2] = ycount;
+            } else {
+                bounds[0] = 5; // X3
+                bounds[1] = 0;
+                bounds[2] = -ax;
+            }
+            break;
+        case 3:
+            if (xcount >  ax) {
+                bounds[0] = 6; // X0
+                bounds[1] = ax;
+                bounds[2] = xcount;
+            } else {
+                bounds[0] = 7; // Y0
+                bounds[1] = 0;
+                bounds[2] = ay;
+            }
+            break;
+        }
+        return bounds;
+    }
+
+    /**
+     * Returns bounds for non quadratic arc tail
+     */
+    static int[] getSegment2(double angle, int ax, int ay, int xcount, int ycount) {
+        int[] bounds = new int[3];
+        switch((int)(angle / 90)) {
+        case 0:
+            if (xcount <  ax) {
+                bounds[0] = 0; // Y3
+                bounds[1] = 0;
+                bounds[2] = -ay;
+            } else {
+                bounds[0] = 1; // X1
+                bounds[1] = ax;
+                bounds[2] = xcount;
+            }
+            break;
+        case 1:
+            if (xcount > -ax) {
+                bounds[0] = 2; // X2
+                bounds[1] = 0;
+                bounds[2] = -ax;
+            } else {
+                bounds[0] = 3; // Y2
+                bounds[1] = -ay;
+                bounds[2] = ycount;
+            }
+            break;
+        case 2:
+            if (xcount < -ax) {
+                bounds[0] = 4; // Y1
+                bounds[1] = 0;
+                bounds[2] = ay;
+            } else {
+                bounds[0] = 5; // X3
+                bounds[1] = -ax;
+                bounds[2] = xcount;
+            }
+            break;
+        case 3:
+            if (xcount >  ax) {
+                bounds[0] = 6; // X0
+                bounds[1] = 0;
+                bounds[2] = ax;
+            } else {
+                bounds[0] = 7; // Y0
+                bounds[1] = ay;
+                bounds[2] = ycount;
+            }
+            break;
+        }
+        return bounds;
+    }
+
+    /**
+     * Rasterizes arc using clippind and dashing style
+     * @param x1 - the x coordinate of the left-upper corner of the arc bounds
+     * @param y1 - the y coordinate of the left-upper corner of the arc bounds
+     * @param width - the width of the arc bounds
+     * @param height - the height of the arc bounds
+     * @param angleStart - the start angle of the arc in degrees
+     * @param angleExtent - the angle extent in degrees
+     * @param clip - the MultiRectArea object of clipping area
+     * @return a MultiRectArea of rasterizer arc
+     */
+    public static MultiRectArea rasterize(int x, int y, int width, int height, double angleStart, double angleExtent, MultiRectArea clip) {
+
+        MultiRectArea mra = new MultiRectArea(false);
+
+        int cx1, cx2, cy1, cy2;
+        cx1 = cx2 = x + width / 2;
+        cy1 = cy2 = y + height / 2;
+
+        if (width % 2 == 0) {
+            cx2--;
+        }
+
+        if (height % 2 == 0) {
+            cy2--;
+        }
+
+        int a = width / 2;
+        int b = height / 2;
+        double c = Math.sqrt(a * a + b * b);
+
+        int xcount, ycount;
+        if (a < b) {
+            xcount = (int)Math.ceil(a * a / c);
+            ycount = (int)Math.floor(b * b / c);
+        } else {
+            xcount = (int)Math.floor(a * a / c);
+            ycount = (int)Math.ceil(b * b / c);
+        }
+
+        int[] xline = createLine(a, b, xcount, ycount);
+        int[] yline = createLine(b, a, ycount, xcount);
+
+        // Correct lines
+        int i = xline.length;
+        while(xline[--i] > xcount) {
+            xline[i] = xcount;
+        }
+
+        i = yline.length;
+        while(yline[--i] > ycount) {
+            yline[i] = ycount;
+        }
+
+        if (Math.abs(angleExtent) >= 360) {
+            // Rasterize CIRCLE
+            addX0Line(mra, xline, cx2, cy2, b);
+            addX1Line(mra, xline, cx2, cy1, b);
+            addX2Line(mra, xline, cx1, cy1, b);
+            addX3Line(mra, xline, cx1, cy2, b);
+            addY0Line(mra, yline, cx2, cy2, a);
+            addY1Line(mra, yline, cx1, cy2, a);
+            addY2Line(mra, yline, cx1, cy1, a);
+            addY3Line(mra, yline, cx2, cy1, a);
+        } else {
+            // Rasterize ARC
+            angleStart = getNormAngle(angleStart);
+            double angleFinish = getNormAngle(angleStart + angleExtent);
+
+            if (angleExtent < 0) {
+                double tmp = angleStart;
+                angleStart = angleFinish;
+                angleFinish = tmp;
+            }
+
+            double radStart = -Math.toRadians(angleStart);
+            double radFinish = -Math.toRadians(angleFinish);
+            int ax1 = (int)(a * Math.cos(radStart));
+            int ay1 = (int)(b * Math.sin(radStart));
+            int ax2 = (int)(a * Math.cos(radFinish));
+            int ay2 = (int)(b * Math.sin(radFinish));
+
+            int[] seg1 = getSegment1(angleStart, ax1, ay1, xcount, ycount);
+            int[] seg2 = getSegment2(angleFinish, ax2, ay2, xcount, ycount);
+
+            // Start and Finish located in the same quater
+            if (angleStart < angleFinish && seg1[0] == seg2[0]) {
+                if (seg1[0] % 2 == 0) {
+                    seg1[2] = seg2[2];
+                } else {
+                    seg1[1] = seg2[1];
+                }
+                addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg1);
+                return mra;
+            }
+
+            addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg1);
+            addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg2);
+
+            int startSeg = (seg1[0] + 1) % 8;
+            int finishSeg = seg2[0];
+
+            while (startSeg != finishSeg) {
+                switch(startSeg) {
+                case 0:
+                    addY3Line(mra, yline, cx2, cy1, a);
+                    break;
+                case 1:
+                    addX1Line(mra, xline, cx2, cy1, b);
+                    break;
+                case 2:
+                    addX2Line(mra, xline, cx1, cy1, b);
+                    break;
+                case 3:
+                    addY2Line(mra, yline, cx1, cy1, a);
+                    break;
+                case 4:
+                    addY1Line(mra, yline, cx1, cy2, a);
+                    break;
+                case 5:
+                    addX3Line(mra, xline, cx1, cy2, b);
+                    break;
+                case 6:
+                    addX0Line(mra, xline, cx2, cy2, b);
+                    break;
+                case 7:
+                    addY0Line(mra, yline, cx2, cy2, a);
+                    break;
+                }
+                startSeg = (startSeg + 1) % 8;
+            }
+        }
+
+        if (clip != null) {
+            mra.intersect(clip);
+        }
+
+        return mra;
+    }
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java b/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java
new file mode 100644
index 0000000..67e0a59
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java
@@ -0,0 +1,611 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 18.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.XORComposite;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * Java implenetation of the Blitter interface. Using when we can't 
+ * draw images natively.
+ */
+public class JavaBlitter implements Blitter {
+
+    /**
+     * Instead of multiplication and division we are using values from
+     * Lookup tables.
+     */
+    static byte mulLUT[][]; // Lookup table for multiplication
+    static byte divLUT[][]; // Lookup table for division
+
+    static{
+        mulLUT = new byte[256][256];
+        for(int i = 0; i < 256; i++){
+            for(int j = 0; j < 256; j++){
+                mulLUT[i][j] = (byte)((float)(i * j)/255 + 0.5f);
+            }
+        }
+        divLUT = new byte[256][256];
+        for(int i = 1; i < 256; i++){
+            for(int j = 0; j < i; j++){
+                divLUT[i][j] = (byte)(((float)j / 255) / ((float)i/ 255) * 255 + 0.5f);
+            }
+            for(int j = i; j < 256; j++){
+                divLUT[i][j] = (byte)255;
+            }
+        }
+    }
+
+    final static int AlphaCompositeMode = 1;
+    final static int XORMode = 2;
+
+    final static JavaBlitter inst = new JavaBlitter();
+
+    public static JavaBlitter getInstance(){
+        return inst;
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            AffineTransform xform, Composite comp, Color bgcolor,
+            MultiRectArea clip) {
+
+        if(xform == null){
+            blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }else{
+            double scaleX = xform.getScaleX();
+            double scaleY = xform.getScaleY();
+            double scaledX = dstX / scaleX;
+            double scaledY = dstY / scaleY;
+            AffineTransform at = new AffineTransform();
+            at.setToTranslation(scaledX, scaledY);
+            xform.concatenate(at);
+            sysxform.concatenate(xform);
+            blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }
+
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            Composite comp, Color bgcolor, MultiRectArea clip) {
+
+        if(sysxform == null) {
+            sysxform = new AffineTransform();
+        }
+        int type = sysxform.getType();
+        switch(type){
+            case AffineTransform.TYPE_TRANSLATION:
+                dstX += sysxform.getTranslateX();
+                dstY += sysxform.getTranslateY();
+            case AffineTransform.TYPE_IDENTITY:
+                 blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
+                        width, height, comp, bgcolor, clip);
+                break;
+            default:
+                int srcW = srcSurf.getWidth();
+                int srcH = srcSurf.getHeight();
+
+                int w = srcX + width < srcW ? width : srcW - srcX;
+                int h = srcY + height < srcH ? height : srcH - srcY;
+
+                ColorModel srcCM = srcSurf.getColorModel();
+                Raster srcR = srcSurf.getRaster().createChild(srcX, srcY,
+                        w, h, 0, 0, null);
+
+                ColorModel dstCM = dstSurf.getColorModel();
+                WritableRaster dstR = dstSurf.getRaster();
+
+                transformedBlit(srcCM, srcR, 0, 0, dstCM, dstR, dstX, dstY, w, h,
+                        sysxform, comp, bgcolor, clip);
+
+        }
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+
+        javaBlt(srcX, srcY, srcSurf.getWidth(), srcSurf.getHeight(),
+                srcSurf.getColorModel(), srcSurf.getRaster(), dstX, dstY,
+                dstSurf.getWidth(), dstSurf.getHeight(),
+                dstSurf.getColorModel(), dstSurf.getRaster(),
+                width, height, comp, bgcolor, clip);
+
+    }
+    public void javaBlt(int srcX, int srcY, int srcW, int srcH,
+            ColorModel srcCM, Raster srcRast, int dstX, int dstY,
+            int dstW, int dstH, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, Composite comp, Color bgcolor,
+            MultiRectArea clip){
+
+        int srcX2 = srcW - 1;
+        int srcY2 = srcH - 1;
+        int dstX2 = dstW - 1;
+        int dstY2 = dstH - 1;
+
+        if(srcX < 0){
+            width += srcX;
+            srcX = 0;
+        }
+        if(srcY < 0){
+            height += srcY;
+            srcY = 0;
+        }
+
+        if(dstX < 0){
+            width += dstX;
+            srcX -= dstX;
+            dstX = 0;
+        }
+        if(dstY < 0){
+            height += dstY;
+            srcY -= dstY;
+            dstY = 0;
+        }
+
+        if(srcX > srcX2 || srcY > srcY2) {
+            return;
+        }
+        if(dstX > dstX2 || dstY > dstY2) {
+            return;
+        }
+
+        if(srcX + width > srcX2) {
+            width = srcX2 - srcX + 1;
+        }
+        if(srcY + height > srcY2) {
+            height = srcY2 - srcY + 1;
+        }
+        if(dstX + width > dstX2) {
+            width = dstX2 - dstX + 1;
+        }
+        if(dstY + height > dstY2) {
+            height = dstY2 - dstY + 1;
+        }
+
+        if(width <= 0 || height <= 0) {
+            return;
+        }
+
+        int clipRects[];
+        if(clip != null) {
+            clipRects = clip.rect;
+        } else {
+            clipRects = new int[]{5, 0, 0, dstW - 1, dstH - 1};
+        }
+
+        boolean isAlphaComp = false;
+        int rule = 0;
+        float alpha = 0;
+        boolean isXORComp = false;
+        Color xorcolor = null;
+        CompositeContext cont = null;
+
+        if(comp instanceof AlphaComposite){
+            isAlphaComp = true;
+            AlphaComposite ac = (AlphaComposite) comp;
+            rule = ac.getRule();
+            alpha = ac.getAlpha();
+        }else if(comp instanceof XORComposite){
+            isXORComp = true;
+            XORComposite xcomp = (XORComposite) comp;
+            xorcolor = xcomp.getXORColor();
+        }else{
+            cont = comp.createContext(srcCM, dstCM, null);
+        }
+
+        for(int i = 1; i < clipRects[0]; i += 4){
+            int _sx = srcX;
+            int _sy = srcY;
+
+            int _dx = dstX;
+            int _dy = dstY;
+
+            int _w = width;
+            int _h = height;
+
+            int cx = clipRects[i];          // Clipping left top X
+            int cy = clipRects[i + 1];      // Clipping left top Y
+            int cx2 = clipRects[i + 2];     // Clipping right bottom X
+            int cy2 = clipRects[i + 3];     // Clipping right bottom Y
+
+            if(_dx > cx2 || _dy > cy2 || dstX2 < cx || dstY2 < cy) {
+                continue;
+            }
+
+            if(cx > _dx){
+                int shx = cx - _dx;
+                _w -= shx;
+                _dx = cx;
+                _sx += shx;
+            }
+
+            if(cy > _dy){
+                int shy = cy - _dy;
+                _h -= shy;
+                _dy = cy;
+                _sy += shy;
+            }
+
+            if(_dx + _w > cx2 + 1){
+                _w = cx2 - _dx + 1;
+            }
+
+            if(_dy + _h > cy2 + 1){
+                _h = cy2 - _dy + 1;
+            }
+
+            if(_sx > srcX2 || _sy > srcY2) {
+                continue;
+            }
+
+            if(isAlphaComp){
+                alphaCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
+                        dstCM, dstRast, _w, _h, rule, alpha, bgcolor);
+            }else if(isXORComp){
+                xorCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
+                        dstCM, dstRast, _w, _h, xorcolor);
+            }else{
+                Raster sr = srcRast.createChild(_sx, _sy, _w, _h, 0, 0, null);
+                WritableRaster dr = dstRast.createWritableChild(_dx, _dy,
+                        _w, _h, 0, 0, null);
+                cont.compose(sr, dr, dr);
+            }
+        }
+    }
+
+    void alphaCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
+            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, int rule, float alpha, Color bgcolor){
+
+        Object srcPixel, dstPixel;
+        int srcConstAllpha = (int)(alpha * 255 + 0.5f);
+        int srcRGB, dstRGB = 0;
+
+        if(bgcolor != null){
+            dstRGB = bgcolor.getRGB();
+        }
+
+        for(int sy = srcY, dy = dstY, srcYMax = srcY + height; sy < srcYMax; sy++, dy++){
+            for(int sx = srcX, dx = dstX, srcXMax = srcX + width; sx < srcXMax; sx++, dx++){
+                srcPixel = srcRast.getDataElements(sx, sy, null);
+                srcRGB = srcCM.getRGB(srcPixel);
+                if(bgcolor == null){
+                    dstPixel = dstRast.getDataElements(dx, dy, null);
+                    dstRGB = dstCM.getRGB(dstPixel);
+                }
+
+                dstRGB = compose(srcRGB, srcCM.isAlphaPremultiplied(),
+                        dstRGB, dstCM.hasAlpha(), dstCM.isAlphaPremultiplied(),
+                        rule, srcConstAllpha);
+
+                dstPixel = dstCM.getDataElements(dstRGB, null);
+                dstRast.setDataElements(dx,dy,dstPixel);
+            }
+        }
+    }
+
+    void xorCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
+            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, Color xorcolor){
+
+        Object srcPixel, dstPixel;
+        int xorRGB = xorcolor.getRGB();
+        int srcRGB, dstRGB;
+
+        for(int sy = srcY, dy = dstY, srcYMax = srcY + height; sy < srcYMax; sy++, dy++){
+            for(int sx = srcX, dx = dstX, srcXMax = srcX + width; sx < srcXMax; sx++, dx++){
+                srcPixel = srcRast.getDataElements(sx, sy, null);
+                dstPixel = dstRast.getDataElements(dx, dy, null);
+
+                srcRGB = srcCM.getRGB(srcPixel);
+                dstRGB = dstCM.getRGB(dstPixel);
+                dstRGB = srcRGB ^ xorRGB ^ dstRGB;
+
+                dstRGB = 0xff000000 | dstRGB;
+                dstPixel = dstCM.getDataElements(dstRGB, dstPixel);
+                dstRast.setDataElements(dx,dy,dstPixel);
+
+            }
+        }
+
+    }
+
+    private void transformedBlit(ColorModel srcCM, Raster srcR, int srcX, int srcY,
+            ColorModel dstCM, WritableRaster dstR, int dstX, int dstY,
+            int width, int height, AffineTransform at, Composite comp,
+            Color bgcolor,MultiRectArea clip) {
+
+        Rectangle srcBounds = new Rectangle(width, height);
+        Rectangle dstBlitBounds = new Rectangle(dstX, dstY, srcR.getWidth(), srcR.getHeight());
+
+        Rectangle transSrcBounds = getBounds2D(at, srcBounds).getBounds();
+        Rectangle transDstBlitBounds = getBounds2D(at, dstBlitBounds).getBounds();
+
+        int translateX = transDstBlitBounds.x - transSrcBounds.x;
+        int translateY = transDstBlitBounds.y - transSrcBounds.y;
+
+        AffineTransform inv = null;
+        try {
+             inv = at.createInverse();
+        } catch (NoninvertibleTransformException e) {
+            return;
+        }
+
+        double[] m = new double[6];
+        inv.getMatrix(m);
+
+        int clipRects[];
+        if(clip != null) {
+            clipRects = clip.rect;
+        } else {
+            clipRects = new int[]{5, 0, 0, dstR.getWidth(), dstR.getHeight()};
+        }
+
+        int compType = 0;
+        int srcConstAlpha = 0;
+        int rule = 0;
+        int bgRGB = bgcolor == null ? 0 : bgcolor.getRGB();
+        int srcRGB = 0, dstRGB = 0;
+        Object srcVal = null, dstVal = null;
+        if(comp instanceof AlphaComposite){
+            compType = AlphaCompositeMode;
+            AlphaComposite ac = (AlphaComposite) comp;
+            rule = ac.getRule();
+            srcConstAlpha = (int)(ac.getAlpha() * 255 + 0.5f);
+        }else if(comp instanceof XORComposite){
+            compType = XORMode;
+            XORComposite xor = (XORComposite) comp;
+            bgRGB = xor.getXORColor().getRGB();
+        }
+
+        for(int i = 1; i < clipRects[0]; i += 4){
+            Rectangle dstBounds = new Rectangle(clipRects[i], clipRects[i + 1], 0, 0);
+            dstBounds.add(clipRects[i + 2] + 1, clipRects[i + 1]);
+            dstBounds.add(clipRects[i + 2] + 1, clipRects[i + 3] + 1);
+            dstBounds.add(clipRects[i], clipRects[i + 3] + 1);
+
+            Rectangle bounds = dstBounds.intersection(transDstBlitBounds);
+
+            int minSrcX = srcBounds.x;
+            int minSrcY = srcBounds.y;
+            int maxSrcX = minSrcX + srcBounds.width;
+            int maxSrcY = minSrcY + srcBounds.height;
+
+            int minX = bounds.x;
+            int minY = bounds.y;
+            int maxX = minX + bounds.width;
+            int maxY = minY + bounds.height;
+
+            int hx = (int)((m[0] * 256) + 0.5);
+            int hy = (int)((m[1] * 256) + 0.5);
+            int vx = (int)((m[2] * 256) + 0.5);
+            int vy = (int)((m[3] * 256) + 0.5);
+            int sx = (int)((m[4] + m[0] * (bounds.x - translateX) + m[2] * (bounds.y - translateY)) * 256 + 0.5);
+            int sy = (int)((m[5] + m[1] * (bounds.x - translateX) + m[3] * (bounds.y - translateY)) * 256 + 0.5);
+
+            vx -= hx * bounds.width;
+            vy -= hy * bounds.width;
+
+            for(int y = minY; y < maxY; y++) {
+                for(int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        switch(compType){
+                            case AlphaCompositeMode:
+                                srcVal = srcR.getDataElements(px , py , null);
+                                srcRGB = srcCM.getRGB(srcVal);
+                                if(bgcolor != null){
+                                    dstRGB = bgRGB;
+                                }else{
+                                    dstVal = dstR.getDataElements(x, y, null);
+                                    dstRGB = dstCM.getRGB(dstVal);
+                                }
+                                dstRGB = compose(srcRGB, srcCM.isAlphaPremultiplied(),
+                                        dstRGB, dstCM.hasAlpha(), dstCM.isAlphaPremultiplied(),
+                                        rule, srcConstAlpha);
+                                dstVal = dstCM.getDataElements(dstRGB, null);
+                                dstR.setDataElements(x, y, dstVal);
+                                break;
+
+                            case XORMode:
+                                srcVal = srcR.getDataElements(px , py , null);
+                                srcRGB = srcCM.getRGB(srcVal);
+                                dstVal = dstR.getDataElements(x, y, null);
+                                dstRGB = dstCM.getRGB(dstVal);
+                                dstRGB = srcRGB ^ bgRGB;
+
+                                dstRGB = 0xff000000 | dstRGB;
+                                dstVal = dstCM.getDataElements(dstRGB, null);
+                                dstR.setDataElements(x, y, dstVal);
+                                break;
+
+                            default:
+                                // awt.37=Unknown  composite type {0}
+                                throw new IllegalArgumentException(Messages.getString("awt.37", //$NON-NLS-1$
+                                        comp.getClass()));
+                        }
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        }
+
+    }
+
+    private Rectangle2D getBounds2D(AffineTransform at, Rectangle r) {
+        int x = r.x;
+        int y = r.y;
+        int width = r.width;
+        int height = r.height;
+
+        float[] corners = {
+            x, y,
+            x + width, y,
+            x + width, y + height,
+            x, y + height
+        };
+
+        at.transform(corners, 0, corners, 0, 4);
+
+        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
+        bounds.add(corners[2], corners[3]);
+        bounds.add(corners[4], corners[5]);
+        bounds.add(corners[6], corners[7]);
+
+        return bounds;
+    }
+
+    private int compose(int srcRGB, boolean isSrcAlphaPre,
+            int dstRGB, boolean dstHasAlpha, boolean isDstAlphaPre,
+            int rule, int srcConstAlpha){
+
+        int sa, sr, sg, sb, da, dr, dg, db;
+
+        sa = (srcRGB >> 24) & 0xff;
+        sr = (srcRGB >> 16) & 0xff;
+        sg = (srcRGB >> 8) & 0xff;
+        sb = srcRGB & 0xff;
+
+        if(isSrcAlphaPre){
+            sa = mulLUT[srcConstAlpha][sa] & 0xff;
+            sr = mulLUT[srcConstAlpha][sr] & 0xff;
+            sg = mulLUT[srcConstAlpha][sg] & 0xff;
+            sb = mulLUT[srcConstAlpha][sb] & 0xff;
+        }else{
+            sa = mulLUT[srcConstAlpha][sa] & 0xff;
+            sr = mulLUT[sa][sr] & 0xff;
+            sg = mulLUT[sa][sg] & 0xff;
+            sb = mulLUT[sa][sb] & 0xff;
+        }
+
+        da = (dstRGB >> 24) & 0xff;
+        dr = (dstRGB >> 16) & 0xff;
+        dg = (dstRGB >> 8) & 0xff;
+        db = dstRGB & 0xff;
+
+        if(!isDstAlphaPre){
+            dr = mulLUT[da][dr] & 0xff;
+            dg = mulLUT[da][dg] & 0xff;
+            db = mulLUT[da][db] & 0xff;
+        }
+
+        int Fs = 0;
+        int Fd = 0;
+        switch(rule){
+        case AlphaComposite.CLEAR:
+            break;
+
+        case AlphaComposite.DST:
+            Fd = 255;
+            break;
+
+        case AlphaComposite.DST_ATOP:
+            Fs = 255 - da;
+            Fd = sa;
+            break;
+
+        case AlphaComposite.DST_IN:
+            Fd = sa;
+            break;
+
+        case AlphaComposite.DST_OUT:
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.DST_OVER:
+            Fs = 255 - da;
+            Fd = 255;
+            break;
+
+        case AlphaComposite.SRC:
+            Fs = 255;
+            break;
+
+        case AlphaComposite.SRC_ATOP:
+            Fs = da;
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.SRC_IN:
+            Fs = da;
+            break;
+
+        case AlphaComposite.SRC_OUT:
+            Fs = 255 - da;
+            break;
+
+        case AlphaComposite.SRC_OVER:
+            Fs = 255;
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.XOR:
+            Fs = 255 - da;
+            Fd = 255 - sa;
+            break;
+        }
+        dr = (mulLUT[sr][Fs] & 0xff) + (mulLUT[dr][Fd] & 0xff);
+        dg = (mulLUT[sg][Fs] & 0xff) + (mulLUT[dg][Fd] & 0xff);
+        db = (mulLUT[sb][Fs] & 0xff) + (mulLUT[db][Fd] & 0xff);
+
+        da = (mulLUT[sa][Fs] & 0xff) + (mulLUT[da][Fd] & 0xff);
+
+        if(!isDstAlphaPre){
+            if(da != 255){
+                dr = divLUT[da][dr] & 0xff;
+                dg = divLUT[da][dg] & 0xff;
+                db = divLUT[da][db] & 0xff;
+            }
+        }
+        if(!dstHasAlpha) {
+            da = 0xff;
+        }
+        dstRGB = (da << 24) | (dr << 16) | (dg << 8) | db;
+
+        return dstRGB;
+
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java b/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java
new file mode 100644
index 0000000..eb6f7b5
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java
@@ -0,0 +1,760 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.render;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+
+
+public class JavaLineRasterizer {
+
+    /**
+     *  LineDasher class provides dashing for particular dash style
+     */
+    public static class LineDasher {
+
+        int index;
+        float pos;
+        float phase;
+        float dash[];
+        float inv[];
+        boolean visible;
+
+        public LineDasher() {
+        }
+
+        public LineDasher(float dash[], float phase) {
+            this.dash = dash;
+            this.phase = phase;
+
+            inv = new float[dash.length];
+            int j = dash.length;
+            for (float element : dash) {
+                inv[--j] = element;
+            }
+            index = 0;
+            while (phase > dash[index]) {
+                phase -= dash[index];
+                index = (index + 1) % dash.length;
+            }
+            visible = index % 2 == 0;
+        }
+
+        void move(float step) { // main dasher
+            pos += step;
+            step += phase;
+            while(step >= dash[index]) {
+                step -= dash[index];
+                index = (index + 1) % dash.length;
+                visible = !visible;
+            }
+            phase = step;
+        }
+
+        float nextDash() {
+            phase = 0.0f;
+            index = (index + 1) % dash.length;
+            visible = !visible;
+            return dash[index];
+        }
+
+        LineDasher createDiagonal(double k, float length, boolean invert) {
+            LineDasher local = new LineDasher();
+            local.dash = new float[dash.length];
+            if (invert) { // inverted dasher
+                move(length);
+                local.phase = (float)((dash[index] - phase) * k);
+                local.visible = visible;
+                local.index = inv.length - index - 1;
+                for(int i = 0; i < inv.length; i++) {
+                    local.dash[i] = (float)(inv[i] * k);
+                }
+            } else {
+                local.phase = (float)(phase * k);
+                local.visible = visible;
+                local.index = index;
+                for(int i = 0; i < dash.length; i++) {
+                    local.dash[i] = (float)(dash[i] * k);
+                }
+                move(length);
+            }
+            return local;
+        }
+
+        LineDasher createOrtogonal(float length, boolean invert) {
+            LineDasher local = new LineDasher();
+            local.dash = new float[dash.length];
+            if (invert) { // inverted dasher
+                move(length);
+                local.phase = dash[index] - phase;
+                local.visible = visible;
+                local.index = inv.length - index - 1;
+                local.dash = inv;
+            } else {
+                local.phase = phase;
+                local.visible = visible;
+                local.index = index;
+                local.dash = dash;
+                move(length);
+            }
+            return local;
+        }
+
+        LineDasher createChild(float start) {
+            LineDasher child = new LineDasher();
+            child.phase = phase;
+            child.visible = visible;
+            child.index = index;
+            child.dash = dash;
+            child.move(start);
+            return child;
+        }
+
+    }
+
+    /**
+     * Line class provides rasterization for different line types
+     */
+    abstract static class Line {
+
+        int x1, y1, x2, y2;
+        int x, y;
+        MultiRectArea dst;
+
+        Line(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+            this.dst = dst;
+        }
+
+        static abstract class Diag extends Line {
+            int dx, dy, adx, ady, sx, sy;
+            int eBase, ePos, eNeg;
+            int xcount;
+            int e;
+
+            Diag(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                super(x1, y1, x2, y2, dst);
+                dx = x2 - x1;
+                dy = y2 - y1;
+                sy = 1;
+                if (dx > 0) {
+                    adx = dx;
+                    sx = 1;
+                } else {
+                    adx = -dx;
+                    sx = -1;
+                }
+                ady = dy;
+            }
+
+            float getLength() {
+                return (float)Math.sqrt(dx * dx + dy * dy);
+            }
+
+            static class Hor extends Diag {
+
+                Hor(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                    super(x1, y1, x2, y2, dst);
+                    eBase = ady + ady - adx;
+                    ePos = 2 * (ady - adx);
+                    eNeg = ady + ady;
+                    xcount = adx;
+                }
+
+                @Override
+                void rasterize() {
+                    e = eBase;
+                    x = x1;
+                    y = y1;
+                    rasterize(xcount);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
+                    e = eBase + 2 * (ady * Math.abs(nx1 - x1) - adx * Math.abs(ny1 - y1));
+                    x = nx1;
+                    y = ny1;
+                    rasterize(dx > 0 ? nx2 - nx1 : nx1 - nx2);
+                }
+
+                @Override
+                void rasterize(int count) {
+                    int px = x;
+                    while (count-- > 0) {
+                        if (e >= 0) {
+                            if (sx > 0) {
+                                dst.addRect(px, y, x, y);
+                            } else {
+                                dst.addRect(x, y, px, y);
+                            }
+                            x += sx;
+                            y += sy;
+                            e += ePos;
+                            px = x;
+                        } else {
+                            e += eNeg;
+                            x += sx;
+                        }
+                    }
+                    if (sx > 0) {
+                        dst.addRect(px, y, x, y);
+                    } else {
+                        dst.addRect(x, y, px, y);
+                    }
+                }
+
+                @Override
+                void skip(int count) {
+                    while (count-- > 0) {
+                        x += sx;
+                        if (e >= 0) {
+                            y += sy;
+                            e += ePos;
+                        } else {
+                            e += eNeg;
+                        }
+                    }
+                }
+
+            }
+
+            static class Ver extends Diag {
+
+                Ver(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                    super(x1, y1, x2, y2, dst);
+                    eBase = adx + adx - ady;
+                    ePos = 2 * (adx - ady);
+                    eNeg = adx + adx;
+                    xcount = ady;
+                }
+
+                @Override
+                void rasterize() {
+                    e = eBase;
+                    x = x1;
+                    y = y1;
+                    rasterize(xcount);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
+                    e = eBase + 2 * (adx * Math.abs(ny1 - y1) - ady * Math.abs(nx1 - x1));
+                    x = nx1;
+                    y = ny1;
+                    rasterize(ny2 - ny1);
+                }
+
+                @Override
+                void rasterize(int count) {
+                    int py = y;
+                    while (count-- > 0) {
+                        if (e >= 0) {
+                            dst.addRect(x, py, x, y);
+                            x += sx;
+                            y += sy;
+                            e += ePos;
+                            py = y;
+                        } else {
+                            y += sy;
+                            e += eNeg;
+                        }
+                    }
+                    dst.addRect(x, py, x, y);
+                }
+
+                @Override
+                void skip(int count) {
+                    while (count-- > 0) {
+                        y += sy;
+                        if (e >= 0) {
+                            x += sx;
+                            e += ePos;
+                        } else {
+                            e += eNeg;
+                        }
+                    }
+                }
+
+            }
+
+            static class HorDashed extends Hor {
+
+                LineDasher local;
+
+                HorDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher, boolean invert) {
+                    super(x1, y1, x2, y2, dst);
+                    float length = getLength();
+                    local = dasher.createDiagonal(xcount / length, length, invert);
+                }
+
+                @Override
+                void rasterize() {
+                    e = eBase;
+                    x = x1;
+                    y = y1;
+                    rasterizeDash(xcount, local);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
+                    e = eBase + 2 * (ady * Math.abs(nx1 - x1) - adx * Math.abs(ny1 - y1));
+                    x = nx1;
+                    y = ny1;
+                    rasterizeDash(Math.abs(nx2 - nx1), local.createChild(Math.abs(nx1 - x1)));
+                }
+
+            }
+
+            static class VerDashed extends Ver {
+
+                LineDasher local;
+
+                VerDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher, boolean invert) {
+                    super(x1, y1, x2, y2, dst);
+                    float length = getLength();
+                    local = dasher.createDiagonal(xcount / length, length, invert);
+                }
+
+                @Override
+                void rasterize() {
+                    e = eBase;
+                    x = x1;
+                    y = y1;
+                    rasterizeDash(xcount, local);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
+                    e = eBase + 2 * (adx * Math.abs(ny1 - y1) - ady * Math.abs(nx1 - x1));
+                    x = nx1;
+                    y = ny1;
+                    rasterizeDash(ny2 - ny1, local.createChild(ny1 - y1));
+                }
+
+            }
+
+            @Override
+            void rasterize(int[] clip, int index) {
+                int cx1 = clip[index + 0];
+                int cy1 = clip[index + 1];
+                int cx2 = clip[index + 2] + 1;
+                int cy2 = clip[index + 3] + 1;
+
+                int code1 =
+                    (x1 < cx1 ? 1 : 0) | (x1 >= cx2 ? 2 : 0) |
+                    (y1 < cy1 ? 8 : 0) | (y1 >= cy2 ? 4 : 0);
+                int code2 =
+                    (x2 < cx1 ? 1 : 0) | (x2 >= cx2 ? 2 : 0) |
+                    (y2 < cy1 ? 8 : 0) | (y2 >= cy2 ? 4 : 0);
+
+                // Outside
+                if ((code1 & code2) != 0) {
+                    return;
+                }
+
+                // Inside
+                if (code1 == 0 && code2 == 0) {
+                    rasterize();
+                    return;
+                }
+
+                // Clip
+                int nx1 = x1;
+                int ny1 = y1;
+                int nx2 = x2;
+                int ny2 = y2;
+                // need to clip
+                cx1 -= x1; cx2 -= x1;
+                cy1 -= y1; cy2 -= y1;
+//                int d;
+                int newx1 = 0, newy1 = 0, newx2 = 0, newy2 = 0;
+                if (code1 != 0) {
+                    newx1 = Integer.MAX_VALUE;
+                    if ((code1 & 8) != 0) {
+                        // clip point 1 with top clip bound
+                        newy1 = cy1;
+                        newx1 = clipY(dx, dy, newy1, true);
+
+                    } else if ((code1 & 4) != 0) {
+                        // clip point 1 with bottom clip bound
+                        newy1 = cy2 - 1;
+                        newx1 = clipY(dx, dy, newy1, false);
+                    }
+                    if ((code1 & 1) != 0 && (cx1 > newx1 || newx1 == Integer.MAX_VALUE)) {
+                        // clip point 1 with left clip bound
+                        newx1 = cx1;
+                        newy1 = clipX(dx, dy, newx1, false);
+                    } else if ((code1 & 2) != 0 && (newx1 >= cx2 || newx1 == Integer.MAX_VALUE)) {
+                        // clip point 1 with right clip bound
+                        newx1 = cx2 - 1;
+                        newy1 = clipX(dx, dy, newx1, false);
+                    }
+                    if (newx1 < cx1 || newx1 >= cx2 || newy1 < cy1 || newy1 >= cy2) {
+                        return;
+                    }
+//                    d = 2 * (ady * Math.abs(newx1) - adx * Math.abs(newy1)) + 2 * ady - adx;
+                } else {
+//                    d = (ady << 1) - adx;
+                }
+
+                if (code2 != 0) {
+                    newx2=Integer.MAX_VALUE;
+                    if ((code2 & 8) != 0) {
+                        // clip point 2 with top clip bound
+                        newy2 = cy1;
+                        newx2 = clipY(dx, dy, newy2, true);
+                    } else if ((code2 & 4) != 0) {
+                        // clip point 2 with bottom clip bound
+                        newy2 = cy2 - 1;
+                        newx2 = clipY(dx, dy, newy2, false);
+                    }
+                    if ((code2 & 1) != 0 && (cx1 > newx2 || newx2 == Integer.MAX_VALUE)) {
+                        // clip point 2 with left clip bound
+                        newx2 = cx1;
+                        newy2 = clipX(dx, dy, newx2, false);
+                    } else if ((code2 & 2) != 0 && (newx2 >= cx2 || newx2 == Integer.MAX_VALUE)) {
+                        // clip point 2 with right clip bound
+                        newx2 = cx2 - 1;
+                        newy2 = clipX(dx, dy, newx2, false);
+                    }
+                    if (newx2 < cx1 || newx2 >= cx2 || newy2 < cy1 || newy2 >= cy2) {
+                        return;
+                    }
+                    nx2 = x1 + newx2;
+                    ny2 = y1 + newy2;
+                }
+                nx1 = x1 + newx1;
+                ny1 = y1 + newy1;
+
+                rasterizeClipped(nx1, ny1, nx2, ny2);
+            }
+
+            abstract void rasterizeClipped(int nx1, int ny1, int nx2, int ny2);
+
+        }
+
+        static abstract class Ortog extends Line {
+
+            Ortog(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                super(x1, y1, x2, y2, dst);
+            }
+
+            static class Hor extends Ortog {
+
+                int dx;
+
+                Hor(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                    super(x1, y1, x2, y2, dst);
+                    dx = x2 - x1;
+                }
+
+                @Override
+                void rasterize() {
+                    if (dx > 0) {
+                        dst.addRect(x1, y1, x2, y2);
+                    } else {
+                        dst.addRect(x2, y2, x1, y1);
+                    }
+                }
+
+                @Override
+                void rasterize(int step) {
+                    int px = x;
+                    if (dx > 0) {
+                        x += step;
+                        dst.addRect(px, y1, x - 1, y2);
+                    } else {
+                        x -= step;
+                        dst.addRect(x + 1, y2, px, y1);
+                    }
+                }
+
+                @Override
+                void skip(int step) {
+                    if (dx > 0) {
+                        x += step;
+                    } else {
+                        x -= step;
+                    }
+                }
+
+                void rasterizeClipped(int nx1, int nx2) {
+                    if (nx1 < nx2) {
+                        dst.addRect(nx1, y1, nx2, y1);
+                    } else {
+                        dst.addRect(nx2, y1, nx1, y1);
+                    }
+                }
+
+                @Override
+                void rasterize(int[] clip, int index) {
+                    if (y1 >= clip[index + 1] && y1 <= clip[index + 3]) {
+                        int cx1 = clip[index + 0];
+                        int cx2 = clip[index + 2];
+                        if (x1 <= cx2 && x2 >= cx1) {
+                            int nx1, nx2;
+                            if (dx > 0) {
+                                nx1 = Math.max(x1, cx1);
+                                nx2 = Math.min(x2, cx2);
+                            } else {
+                                nx2 = Math.max(x2, cx1);
+                                nx1 = Math.min(x1, cx2);
+                            }
+                            rasterizeClipped(nx1, nx2);
+                        }
+                    }
+                }
+
+            }
+
+            static class Ver extends Ortog {
+
+                int dy;
+
+                Ver(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                    super(x1, y1, x2, y2, dst);
+                    dy = y2 - y1;
+                }
+
+                @Override
+                void rasterize() {
+                    dst.addRect(x1, y1, x2, y2);
+                }
+
+                @Override
+                void rasterize(int step) {
+                    int py = y;
+                    y += step;
+                    dst.addRect(x1, py, x2, y - 1);
+                }
+
+                @Override
+                void skip(int step) {
+                    y += step;
+                }
+
+                void rasterizeClipped(int ny1, int ny2) {
+                    dst.addRect(x1, ny1, x1, ny2);
+                }
+
+                @Override
+                void rasterize(int[] clip, int index) {
+                    if (x1 >= clip[index] && x1 <= clip[index + 2]) {
+                        int cy1 = clip[index + 1];
+                        int cy2 = clip[index + 3];
+                        if (y1 <= cy2 && y2 >= cy1) {
+                            rasterizeClipped(Math.max(y1, cy1), Math.min(y2, cy2));
+                        }
+                    }
+                }
+
+            }
+
+            static class HorDashed extends Hor {
+
+                LineDasher local;
+
+                HorDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher) {
+                    super(x1, y1, x2, y2, dst);
+                    dx = x2 - x1;
+                    local = dasher.createOrtogonal(Math.abs(dx), false);
+                }
+
+                @Override
+                void rasterize() {
+                    x = x1;
+                    y = y1;
+                    rasterizeDash(Math.abs(dx), local);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int nx2) {
+                    x = nx1;
+                    y = y1;
+                    rasterizeDash(Math.abs(nx2 - nx1), local.createChild(Math.abs(nx1 - x1)));
+                }
+
+            }
+
+            static class VerDashed extends Ver {
+
+                LineDasher local;
+
+                VerDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher, boolean invert) {
+                    super(x1, y1, x2, y2, dst);
+                    dy = y2 - y1;
+                    local = dasher.createOrtogonal(dy, invert);
+                }
+
+                @Override
+                void rasterize() {
+                    x = x1;
+                    y = y1;
+                    rasterizeDash(dy, local);
+                }
+
+                @Override
+                void rasterizeClipped(int ny1, int ny2) {
+                    x = x1;
+                    y = ny1;
+                    rasterizeDash(ny2 - ny1, local.createChild(ny1));
+                }
+
+            }
+
+        }
+
+        abstract void rasterize();
+        abstract void rasterize(int[] clip, int index);
+        abstract void rasterize(int count);
+        abstract void skip(int count);
+
+        void rasterizeDash(int count, LineDasher dasher) {
+            float delta = dasher.dash[dasher.index] - dasher.phase;
+            int step = (int)delta;
+            delta -= step;
+            while(count > step) {
+                if (dasher.visible) {
+                    rasterize(step);
+                } else {
+                    skip(step);
+                }
+                count -= step;
+                delta += dasher.nextDash();
+                step = (int)delta;
+                delta -= step;
+            }
+            if (count > 0 && dasher.visible) {
+                rasterize(count);
+                dasher.move(count);
+            }
+        }
+
+    }
+
+    /**
+     * Common clipping method
+     */
+    static int clip(int dX1, int dX2, int cX, boolean top) {
+        int adX1 = dX1 < 0 ? -dX1 : dX1;
+        int adX2 = dX2 < 0 ? -dX2 : dX2;
+        if (adX1 <= adX2) {
+            // obtuse intersection angle
+            return ((dX1 << 1) * cX + (dX1 > 0 ? dX2 : -dX2)) / (dX2 << 1);
+        }
+        int k;
+        if (top) {
+            k = -dX1 + (dX2 < 0 ? 0 : dX1 > 0 ? (dX2 << 1) : -(dX2 << 1));
+        } else {
+            k = dX1 + (dX2 > 0 ? 0 : dX1 > 0 ? (dX2 << 1) : -(dX2 << 1));
+        }
+
+        k += dX1 > 0 == dX2 > 0 ? -1 : 1;
+        return ((dX1 << 1) * cX + k) / (dX2 << 1);
+    }
+
+    /**
+     * Clipping along X axis
+     */
+    static int clipX(int dx, int dy, int cy, boolean top) {
+        return clip(dy, dx, cy, top);
+    }
+
+    /**
+     * Clipping along Y axis
+     */
+    static int clipY(int dx, int dy, int cx, boolean top) {
+        return clip(dx, dy, cx, top);
+    }
+
+    /**
+     * Rasterizes line using clippind and dashing style
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param clip - the MultiRectArea object of clipping area
+     * @param dasher - the dasher style
+     * @param invert - the invert indicator, always false
+     * @return a MultiRectArea of rasterizer line
+     */
+    public static MultiRectArea rasterize(int x1, int y1, int x2, int y2, MultiRectArea clip, LineDasher dasher, boolean invert) {
+
+        MultiRectArea dst = new MultiRectArea(false);
+        int dx = x2 - x1;
+        int dy = y2 - y1;
+
+        // Point
+        if (dx == 0 && dy == 0) {
+            if ((clip == null || clip.contains(x1, y1)) && (dasher == null || dasher.visible)) {
+                dst = new MultiRectArea(x1, y1, x1, y1);
+            }
+            return dst;
+        }
+
+        if (dy < 0) {
+            return rasterize(x2, y2, x1, y1, clip, dasher, true);
+        }
+
+        Line line;
+        if (dasher == null) {
+            if (dx == 0) {
+                line = new Line.Ortog.Ver(x1, y1, x2, y2, dst);
+            } else
+                if (dy == 0) {
+                    line = new Line.Ortog.Hor(x1, y1, x2, y2, dst);
+                } else {
+                    if (dy < Math.abs(dx)) {
+                        line = new Line.Diag.Hor(x1, y1, x2, y2, dst);
+                    } else {
+                        line = new Line.Diag.Ver(x1, y1, x2, y2, dst);
+                    }
+                }
+        } else {
+            if (dx == 0) {
+                line = new Line.Ortog.VerDashed(x1, y1, x2, y2, dst, dasher, invert);
+            } else
+                if (dy == 0) {
+                    line = new Line.Ortog.HorDashed(x1, y1, x2, y2, dst, dasher);
+                } else {
+                    if (dy < Math.abs(dx)) {
+                        line = new Line.Diag.HorDashed(x1, y1, x2, y2, dst, dasher, invert);
+                    } else {
+                        line = new Line.Diag.VerDashed(x1, y1, x2, y2, dst, dasher, invert);
+                    }
+                }
+        }
+
+
+        if (clip == null || clip.isEmpty()) {
+            line.rasterize();
+        } else {
+            for(int i = 1; i < clip.rect[0]; i += 4) {
+                line.rasterize(clip.rect, i);
+            }
+        }
+
+        return dst;
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java b/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java
new file mode 100644
index 0000000..dbaaf53
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java
@@ -0,0 +1,475 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.Shape;
+import java.awt.geom.PathIterator;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class JavaShapeRasterizer {
+
+    static final int POINT_CAPACITY = 16;
+
+    int edgesCount;
+    int edgeCur;
+    int[] edgesX;
+    int[] edgesY;
+    int[] edgesYS; // Y coordinate of edge START point
+    int[] edgesN;
+    int[] edgesDY;
+    int[] bounds;
+    int boundCount;
+    boolean[] edgesExt; // Extremal points
+
+    int activeCount;
+    float[] activeX;
+    int[] activeYEnd;
+    float[] activeXStep;
+    int[] activeDY;
+    boolean[] activeExt;
+
+    int[] crossX;
+    int[] crossDY;
+
+    Filler filler;
+
+    /**
+     * Rasterization filler for different path rules
+     */
+    static abstract class Filler {
+
+        static class NonZero extends Filler {
+            @Override
+            void add(MultiRectArea.LineCash rect, int[] points, int[] orient, int length, int y) {
+
+                int[] dst = new int[length];
+                int dstLength = 1;
+                dst[0] = points[0];
+                int count = 0;
+                boolean inside = true;
+                for(int i = 0; i < length; i++) {
+                    count += orient[i] > 0 ? 1 : -1;
+                    if (count == 0) {
+                        dst[dstLength++] = points[i];
+                        inside = false;
+                    } else {
+                        if (!inside) {
+                            dst[dstLength++] = points[i];
+                            inside = true;
+                        }
+                    }
+
+                }
+
+                for(int i = 1; i < dstLength; i += 2) {
+                    dst[i]--;
+                }
+
+                dstLength = excludeEmpty(dst, dstLength);
+//              System.out.println("test");
+
+                dstLength = union(dst, dstLength);
+
+                rect.addLine(dst, dstLength);
+            }
+        }
+
+        static class EvenOdd extends Filler {
+            @Override
+            void add(MultiRectArea.LineCash rect, int[] points, int[] orient, int length, int y) {
+    /*
+                int[] buf = new int[length];
+                int j = 0;
+                for(int i = 0; i < length - 1; i++) {
+                    if (points[i] != points[i + 1]) {
+                        buf[j++] = points[i];
+                    }
+                }
+    */
+                for(int i = 1; i < length; i += 2) {
+                    points[i]--;
+                }
+
+                length = excludeEmpty(points, length);
+//              System.out.println("test");
+
+                length = union(points, length);
+                rect.addLine(points, length);
+    /*
+                for(int i = 0; i < length;) {
+                    rect.add(points[i++], y, points[i++], y);
+                }
+    */
+            }
+        }
+
+        abstract void add(MultiRectArea.LineCash rect, int[] points, int[] orient, int length, int y);
+
+        static int excludeEmpty(int[] points, int length) {
+            int i = 0;
+            while(i < length) {
+                if (points[i] <= points[i + 1]) {
+                    i += 2;
+                } else {
+                    length -= 2;
+                    System.arraycopy(points, i + 2, points, i, length - i);
+                }
+            }
+            return length;
+        }
+
+        static int union(int[] points, int length) {
+            int i = 1;
+            while(i < length - 1) {
+                if (points[i] < points[i - 1]) {
+                    System.arraycopy(points, i + 1, points, i - 1, length - i - 1);
+                    length -= 2;
+                } else
+                if (points[i] >= points[i + 1] - 1) {
+                    System.arraycopy(points, i + 2, points, i, length - i - 2);
+                    length -= 2;
+                } else {
+                    i += 2;
+                }
+            }
+            return length;
+        }
+
+    }
+
+    public JavaShapeRasterizer() {
+    }
+
+    /**
+     * Checks buffer size and realloc if necessary
+     */
+    int[] checkBufSize(int[] buf, int size) {
+        if (size == buf.length) {
+            int[] tmp;
+            tmp = new int[size + POINT_CAPACITY];
+            System.arraycopy(buf, 0, tmp, 0, buf.length);
+            buf = tmp;
+        }
+        return buf;
+    }
+
+    /**
+     * Adds to the buffers new edge 
+     */
+    void addEdge(int x, int y, int num) {
+        edgesX = checkBufSize(edgesX, edgesCount);
+        edgesY = checkBufSize(edgesY, edgesCount);
+        edgesN = checkBufSize(edgesN, edgesCount);
+        edgesX[edgesCount] = x;
+        edgesY[edgesCount] = y;
+        edgesN[edgesCount] = (num << 16) | edgesCount;
+        edgesCount++;
+    }
+
+    /**
+     * Prepare all buffers and variable to rasterize shape 
+     */
+    void makeBuffer(PathIterator path, double flatness) {
+        edgesX = new int[POINT_CAPACITY];
+        edgesY = new int[POINT_CAPACITY];
+        edgesN = new int[POINT_CAPACITY];
+        bounds = new int[POINT_CAPACITY];
+        boundCount = 0;
+        edgesCount = 0;
+
+        if (path.getWindingRule() == PathIterator.WIND_EVEN_ODD) {
+            filler = new Filler.EvenOdd();
+        } else {
+            filler = new Filler.NonZero();
+        }
+        float[] coords = new float[2];
+        boolean closed = true;
+        while (!path.isDone()) {
+            switch(path.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (!closed) {
+                    boundCount++;
+                    bounds = checkBufSize(bounds, boundCount);
+                    bounds[boundCount] = edgesCount;
+                }
+                addEdge((int)coords[0], (int)coords[1], boundCount);
+                closed = false;
+                break;
+            case PathIterator.SEG_LINETO:
+                addEdge((int)coords[0], (int)coords[1], boundCount);
+                break;
+            case PathIterator.SEG_CLOSE:
+                boundCount++;
+                bounds = checkBufSize(bounds, boundCount);
+                bounds[boundCount] = edgesCount;
+                closed = true;
+                break;
+            default:
+                // awt.36=Wrong segment
+                throw new RuntimeException(Messages.getString("awt.36")); //$NON-NLS-1$
+            }
+            path.next();
+        }
+        if (!closed) {
+            boundCount++;
+            bounds = checkBufSize(bounds, boundCount);
+            bounds[boundCount] = edgesCount;
+        }
+    }
+
+    /**
+     * Sort buffers
+     */
+    void sort(int[] master, int[] slave, int length) {
+        for(int i = 0; i < length - 1; i++) {
+            int num = i;
+            int min = master[num];
+            for(int j = i + 1; j < length; j++) {
+                if (master[j] < min) {
+                    num = j;
+                    min = master[num];
+                }
+            }
+            if (num != i) {
+                master[num] = master[i];
+                master[i] = min;
+                min = slave[num];
+                slave[num] = slave[i];
+                slave[i] = min;
+            }
+        }
+    }
+
+    int getNext(int cur) {
+        int n = edgesN[cur];
+        int bound = n >> 16;
+        int num = (n & 0xFFFF) + 1;
+        if (num == bounds[bound + 1]) {
+            return bounds[bound];
+        }
+        return num;
+    }
+
+    int getPrev(int cur) {
+        int n = edgesN[cur];
+        int bound = n >> 16;
+        int num = (n & 0xFFFF) - 1;
+        if (num < bounds[bound]) {
+            return bounds[bound + 1] - 1;
+        }
+        return num;
+    }
+
+    int getNextShape(int cur) {
+        int bound = edgesN[cur] >> 16;
+        return bounds[bound + 1];
+    }
+
+    void init() {
+
+        edgesYS = new int[edgesCount];
+        System.arraycopy(edgesY, 0, edgesYS, 0, edgesCount);
+        // Create edgesDY
+        edgesDY = new int[edgesCount];
+        for(int i = 0; i < edgesCount; i++) {
+            int dy = edgesY[getNext(i)] - edgesY[i];
+            edgesDY[i] = dy;
+        }
+
+        // Create edgesExt
+        edgesExt = new boolean[edgesCount];
+        int prev = -1;
+        int i = 0;
+        int pos = 0;
+        while(i < edgesCount) {
+
+            TOP: {
+                do {
+                    if (edgesDY[i] > 0) {
+                        break TOP;
+                    }
+                    i = getNext(i);
+                } while (i != pos);
+                i = pos = getNextShape(i);
+                continue;
+            }
+
+            BOTTOM: {
+                do {
+                    if (edgesDY[i] < 0) {
+                        break BOTTOM;
+                    }
+                    if (edgesDY[i] > 0) {
+                        prev = i;
+                    }
+                    i = getNext(i);
+                } while (i != pos);
+                i = pos = getNextShape(i);
+                continue;
+            }
+
+            if (prev != -1) {
+                edgesExt[prev] = true;
+            }
+            edgesExt[i] = true;
+        }
+
+        // Sort edgesY and edgesN
+        sort(edgesYS, edgesN, edgesCount);
+
+        edgeCur = 0;
+        activeCount = 0;
+        activeX = new float[edgesCount];
+        activeYEnd = new int[edgesCount];
+        activeXStep = new float[edgesCount];
+        activeDY = new int[edgesCount];
+        activeExt = new boolean[edgesCount];
+
+        crossX = new int[edgesCount];
+        crossDY = new int[edgesCount];
+    }
+
+    /**
+     * Marks edge as active
+     */
+    void addActiveEdge(int levelY, int start, int end, boolean back) {
+        int dy = back ? -edgesDY[end] : edgesDY[start];
+        if (dy <= 0) {
+            return;
+        }
+        int x1 = edgesX[start];
+        int dx = edgesX[end] - x1;
+        activeX[activeCount] = x1;
+        activeYEnd[activeCount] = edgesY[end];
+        activeXStep[activeCount] = dx / (float)dy;
+        activeDY[activeCount] = back ? -dy : dy;
+        activeExt[activeCount] = back ? edgesExt[end] : edgesExt[start];
+        activeCount++;
+    }
+
+    /**
+     * Find new active edges
+     */
+    int findActiveEdges(int levelY) {
+
+        int edgeActive = edgeCur;
+        while (edgeActive < edgesCount && edgesYS[edgeActive] == levelY) {
+            edgeActive++;
+        }
+
+        int activeNext = edgeActive;
+
+        while (edgeActive > edgeCur) {
+            edgeActive--;
+            int num = edgesN[edgeActive] & 0xFFFF;
+            addActiveEdge(levelY, num, getPrev(edgeActive), true);
+            addActiveEdge(levelY, num, getNext(edgeActive), false);
+        }
+
+        edgeCur = activeNext;
+
+        if (activeNext == edgesCount) {
+            return edgesY[edgesCount - 1];
+        }
+        return edgesYS[activeNext];
+    }
+
+    /**
+     * Rasterizes shape with particular flatness
+     * @param shape - the souze Shape to be rasterized
+     * @param flatness - the rasterization flatness
+     * @return a MultiRectArea of rasterized shape
+     */
+    public MultiRectArea rasterize(Shape shape, double flatness) {
+
+        PathIterator path = shape.getPathIterator(null, flatness);
+
+        // Shape is empty
+        if (path.isDone()) {
+            return new MultiRectArea();
+        }
+
+        makeBuffer(path, flatness);
+
+        init();
+
+        int y = edgesYS[0];
+        int nextY = y;
+        int crossCount;
+
+        MultiRectArea.LineCash rect = new MultiRectArea.LineCash(edgesCount);
+        rect.setLine(y);
+
+        while(y <= nextY) {
+
+            crossCount = 0;
+
+            if (y == nextY) {
+
+                int i = activeCount;
+                while(i > 0) {
+                    i--;
+                    if (activeYEnd[i] == y) {
+
+                        activeCount--;
+                        int length = activeCount - i;
+                        if (length != 0) {
+                            int pos = i + 1;
+                            System.arraycopy(activeX, pos, activeX, i, length);
+                            System.arraycopy(activeYEnd, pos, activeYEnd, i, length);
+                            System.arraycopy(activeXStep, pos, activeXStep, i, length);
+                            System.arraycopy(activeDY, pos, activeDY, i, length);
+                            System.arraycopy(activeExt, pos, activeExt, i, length);
+                        }
+                    }
+                }
+
+                nextY = findActiveEdges(y);
+            }
+
+            // Get X crossings
+            for(int i = 0; i < activeCount; i++) {
+                crossX[crossCount] = (int)Math.ceil(activeX[i]);
+                crossDY[crossCount] = activeDY[i];
+                crossCount++;
+            }
+
+            if (crossCount == 0) {
+                rect.skipLine();
+            } else {
+                // Sort X crossings
+                sort(crossX, crossDY, crossCount);
+                filler.add(rect, crossX, crossDY, crossCount, y);
+            }
+
+            for(int i = 0; i < activeCount; i++) {
+                activeX[i] += activeXStep[i];
+            }
+
+            y++;
+        }
+
+        return rect;
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java b/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java
new file mode 100644
index 0000000..322ba57
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java
@@ -0,0 +1,263 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.*;
+import java.awt.image.*;
+
+
+import java.awt.font.GlyphMetrics;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+
+import org.apache.harmony.awt.gl.TextRenderer;
+import org.apache.harmony.awt.gl.font.CommonGlyphVector;
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.Glyph;
+import org.apache.harmony.awt.gl.image.BufferedImageGraphics2D;
+
+public class JavaTextRenderer extends TextRenderer {
+
+    public static final JavaTextRenderer inst = new JavaTextRenderer();
+
+    @Override
+    public void drawGlyphVector(Graphics2D g, GlyphVector glyphVector,
+            float x, float y) {
+
+        AffineTransform at = g.getTransform();
+        Rectangle c = g.getClipBounds();
+        if (at != null){
+            int atType = at.getType();
+            if (atType == AffineTransform.TYPE_TRANSLATION) {
+                c.translate((int)Math.round(at.getTranslateX()), (int)Math.round(at.getTranslateY()));
+            }
+        }
+
+        WritableRaster wr = ((BufferedImageGraphics2D)g).getWritableRaster();
+        ColorModel cm = ((BufferedImageGraphics2D)g).getColorModel();
+
+        Rectangle rBounds = wr.getBounds();
+
+        Object color = cm.getDataElements(g.getColor().getRGB(), null);
+
+        drawClipGlyphVector(wr, color, glyphVector, (int)Math.round(x + at.getTranslateX()), (int)Math.round(y + at.getTranslateY()),
+        Math.max(c.x,rBounds.x),
+        Math.max(c.y,rBounds.y),
+        Math.min((int)Math.round(c.getMaxX()), (int)Math.round(rBounds.getMaxX())),
+        Math.min((int)Math.round(c.getMaxY()), (int)Math.round(rBounds.getMaxY())));
+
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void drawString(Graphics2D g, String str, float x, float y) {
+        AffineTransform at = g.getTransform();
+        Rectangle c = g.getClipBounds();
+        if (at != null){
+            int atType = at.getType();
+            if (atType == AffineTransform.TYPE_TRANSLATION) {
+                c.translate((int)Math.round(at.getTranslateX()), (int)Math.round(at.getTranslateY()));
+            }
+        }
+        WritableRaster wr = ((BufferedImageGraphics2D)g).getWritableRaster();
+        ColorModel cm = ((BufferedImageGraphics2D)g).getColorModel();
+        Rectangle rBounds = wr.getBounds();
+
+        Object color = cm.getDataElements(g.getColor().getRGB(), null);
+
+        drawClipString(wr, color, str, (FontPeerImpl) (g.getFont().getPeer()),
+                (int)Math.round(x + at.getTranslateX()), (int)Math.round(y + at.getTranslateY()),
+                Math.max(c.x,rBounds.x),
+                Math.max(c.y,rBounds.y),
+                Math.min((int)Math.round(c.getMaxX()), (int)Math.round(rBounds.getMaxX())),
+                Math.min((int)Math.round(c.getMaxY()), (int)Math.round(rBounds.getMaxY())));
+
+    }
+
+    /**
+     * 
+     * Draws string on specified raster at desired position.
+     *  
+     * @param raster specified WritableRaster to draw at
+     * @param color color of the text
+     * @param glyphVector GlyphVector object to draw
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     * @param cMinX minimum x of the raster area to draw
+     * @param cMinY minimum y of the raster area to draw
+     * @param cMaxX maximum x of the raster area to draw
+     * @param cMaxY maximum y of the raster area to draw
+     */
+    public void drawClipGlyphVector(WritableRaster raster, Object color,
+            GlyphVector glyphVector, int x, int y,
+            int cMinX, int cMinY, int cMaxX, int cMaxY) {
+        // TODO: implement complex clipping
+
+        int xSrcSurf, ySrcSurf; // Start point in String rectangle
+        int xDstSurf, yDstSurf; // Start point in Surface rectangle
+        int clWidth, clHeight;
+
+        for (int i = 0; i < glyphVector.getNumGlyphs(); i++) {
+            Glyph gl = ((CommonGlyphVector) glyphVector).vector[i];
+
+            if (gl.getPointWidth() == 0) {
+                continue;
+            }
+
+            byte[] data = gl.getBitmap();
+            if (data != null) {
+                Point2D pos = glyphVector.getGlyphPosition(i);
+
+                xSrcSurf = 0;//gl.bmp_left;
+                ySrcSurf = 0;//gl.bmp_rows - gl.bmp_top;
+
+                xDstSurf = x + (int)pos.getX() + (int) gl.getGlyphPointMetrics().getLSB();// + gl.bmp_left;
+                yDstSurf = y - gl.bmp_top/*getPointHeight()*/  + (int) pos.getY();// - (gl.bmp_rows-gl.bmp_top);
+
+                int textWidth = gl.bmp_width;
+                int textHeight = gl.getPointHeight();
+
+                // if Regions don't intersect
+                if ((xDstSurf > cMaxX) || (yDstSurf > cMaxY) || (xDstSurf + textWidth < cMinX)
+                        || (yDstSurf + textHeight < cMinY)) {
+                    // Nothing to do
+                } else {
+                    if (xDstSurf >= cMinX) {
+                        clWidth = Math.min(textWidth, cMaxX - xDstSurf);
+                    } else {
+                        xSrcSurf += cMinX - xDstSurf;
+                        clWidth = Math.min(cMaxX - cMinX, textWidth - (cMinX - xDstSurf));
+                        xDstSurf = cMinX;
+                    }
+                    if (yDstSurf >= cMinY) {
+                        clHeight = Math.min(textHeight, cMaxY - yDstSurf);
+                    } else {
+                        ySrcSurf += cMinY - yDstSurf;
+                        clHeight = Math.min(cMaxY - cMinY, textHeight - (cMinY - yDstSurf));
+                        yDstSurf = cMinY;
+                    }
+                    //     Drawing on the Raster
+                    for (int h=0; h<clHeight; h++){
+                        for (int w=0; w < clWidth ; w++) {
+                            byte currByte = data[(ySrcSurf + h)*gl.bmp_pitch + (xSrcSurf+w)/8];
+                            boolean emptyByte = ((currByte & (1 << (7 - ((xSrcSurf+w) % 8)))) != 0);
+                            if (emptyByte) {
+                                raster.setDataElements(xDstSurf+w, yDstSurf+h, color);
+                            } else {
+                                // Nothing to do
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    /**
+     * Draws string on specified raster at desired position.
+     *  
+     * @param raster specified WritableRaster to draw at
+     * @param color color of the text
+     * @param str text to draw
+     * @param font font peer to use for drawing text
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     * @param cMinX minimum x of the raster area to draw
+     * @param cMinY minimum y of the raster area to draw
+     * @param cMaxX maximum x of the raster area to draw
+     * @param cMaxY maximum y of the raster area to draw
+     */    
+    public void drawClipString(WritableRaster raster, Object color, String str,
+            FontPeerImpl font, int x, int y, int cMinX, int cMinY, int cMaxX,
+            int cMaxY) {
+        // TODO: implement complex clipping
+
+        int xSrcSurf, ySrcSurf; // Start point in String rectangle
+        int xDstSurf, yDstSurf; // Start point in Surface rectangle
+        int clWidth, clHeight;
+
+        char[] chars = str.toCharArray();
+
+        int xBaseLine = x;
+        int yBaseLine = y;
+
+        for (char element : chars) {
+            Glyph gl = font.getGlyph(element);
+            GlyphMetrics pointMetrics = gl.getGlyphPointMetrics();
+            if (gl.getWidth() == 0) {
+                xBaseLine += pointMetrics.getAdvanceX();
+                continue;
+            }
+
+            byte[] data = gl.getBitmap();
+            if (data == null) {
+                xBaseLine += pointMetrics.getAdvanceX();
+            } else {
+
+                xSrcSurf = 0;
+                ySrcSurf = 0;
+
+                xDstSurf = Math.round(xBaseLine + gl.getGlyphPointMetrics().getLSB());
+                yDstSurf = yBaseLine - gl.bmp_top;
+
+                int textWidth = gl.bmp_width;
+                int textHeight = gl.getPointHeight();
+
+                // if Regions don't intersect
+                if ((xDstSurf > cMaxX) || (yDstSurf > cMaxY) || (xDstSurf + textWidth < cMinX)
+                        || (yDstSurf + textHeight < cMinY)) {
+                    // Nothing to do
+                } else {
+                    if (xDstSurf >= cMinX) {
+                        clWidth = Math.min(textWidth, cMaxX - xDstSurf);
+                    } else {
+                        xSrcSurf += cMinX - xDstSurf;
+                        clWidth = Math.min(cMaxX - cMinX, textWidth - (cMinX - xDstSurf));
+                        xDstSurf = cMinX;
+                    }
+                    if (yDstSurf >= cMinY) {
+                        clHeight = Math.min(textHeight, cMaxY - yDstSurf);
+                    } else {
+                        ySrcSurf += cMinY - yDstSurf;
+                        clHeight = Math.min(cMaxY - cMinY, textHeight - (cMinY - yDstSurf));
+                        yDstSurf = cMinY;
+                    }
+
+                    // Drawing on the Raster
+                    for (int h=0; h<clHeight; h++){
+                        for (int w=0; w < clWidth ; w++) {
+                            byte currByte = data[(ySrcSurf + h)*gl.bmp_pitch + (xSrcSurf+w)/8];
+                            boolean emptyByte = ((currByte & (1 << (7 - ((xSrcSurf+w) % 8)))) != 0);
+                            if (emptyByte) {
+                                raster.setDataElements(xDstSurf+w, yDstSurf+h, color);
+                            } else {
+                                // Nothing to do
+                            }
+                        }
+                    }
+                }
+                xBaseLine += pointMetrics.getAdvanceX();
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java b/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java
new file mode 100644
index 0000000..b0ebc97
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java
@@ -0,0 +1,218 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 26.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.XORComposite;
+
+/**
+ * This kind of blitters is intended for drawing one image on the buffered
+ * or volatile image. For the moment we can blit natively Buffered Images which 
+ * have sRGB, Linear_RGB, Linear_Gray Color Space and type different 
+ * from BufferedImage.TYPE_CUSTOM, Volatile Images and Images which received 
+ * using Toolkit and Component classes.
+ */
+public class NativeImageBlitter implements Blitter {
+
+
+    final static NativeImageBlitter inst = new NativeImageBlitter();
+
+    public static NativeImageBlitter getInstance(){
+        return inst;
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            AffineTransform xform, Composite comp, Color bgcolor,
+            MultiRectArea clip) {
+
+        if(!srcSurf.isNativeDrawable()){
+            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    sysxform, xform, comp, bgcolor, clip);
+        }else{
+            if(xform == null){
+                blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                        sysxform, comp, bgcolor, clip);
+            }else{
+                double scaleX = xform.getScaleX();
+                double scaleY = xform.getScaleY();
+                double scaledX = dstX / scaleX;
+                double scaledY = dstY / scaleY;
+                AffineTransform at = new AffineTransform();
+                at.setToTranslation(scaledX, scaledY);
+                xform.concatenate(at);
+                sysxform.concatenate(xform);
+                blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
+                        sysxform, comp, bgcolor, clip);
+            }
+        }
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            Composite comp, Color bgcolor, MultiRectArea clip) {
+
+        if(!srcSurf.isNativeDrawable()){
+            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }else{
+            int type = sysxform.getType();
+            switch(type){
+                case AffineTransform.TYPE_TRANSLATION:
+                    dstX += sysxform.getTranslateX();
+                    dstY += sysxform.getTranslateY();
+                case AffineTransform.TYPE_IDENTITY:
+                    blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
+                            width, height, comp, bgcolor, clip);
+                    break;
+                default:
+                    // TODO Need to realize Affine Transformation
+                    if(srcSurf instanceof ImageSurface){
+                        JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, 
+                                dstSurf, width, height,
+                                sysxform, comp, bgcolor, clip);
+                    }else{
+                        int w = srcSurf.getWidth();
+                        int h = srcSurf.getHeight();
+                        BufferedImage tmp = new BufferedImage(w, h, 
+                                BufferedImage.TYPE_INT_RGB);
+                        Surface tmpSurf = Surface.getImageSurface(tmp);
+                        blit(0, 0, srcSurf, 0, 0, tmpSurf,
+                                w, h, AlphaComposite.SrcOver, null, null);
+                        JavaBlitter.inst.blit(srcX, srcY, tmpSurf, dstX, dstY, 
+                                dstSurf, width, height,
+                                sysxform, comp, bgcolor, clip);
+                    }
+            }
+        }
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+
+        if(!srcSurf.isNativeDrawable()){
+            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    comp, bgcolor, clip);
+        }else{
+            long dstSurfStruct = dstSurf.getSurfaceDataPtr();
+            Object dstData = dstSurf.getData();
+            int clipRects[];
+            if(clip != null){
+                clipRects = clip.rect;
+            }else{
+                clipRects = new int[]{5, 0, 0, dstSurf.getWidth(),
+                        dstSurf.getHeight()};
+            }
+
+            if(!(srcSurf instanceof ImageSurface)){
+                srcSurf = srcSurf.getImageSurface();
+                if(bgcolor != null){
+                    bgcolor = null;
+                }
+            }
+
+            long srcSurfStruct = srcSurf.getSurfaceDataPtr();
+            Object srcData = srcSurf.getData();
+            if(comp instanceof AlphaComposite){
+                AlphaComposite ac = (AlphaComposite) comp;
+                int compType = ac.getRule();
+                float alpha = ac.getAlpha();
+                if(bgcolor != null){
+                    bltBG(srcX, srcY, srcSurfStruct, srcData,
+                            dstX, dstY, dstSurfStruct, dstData,
+                            width, height, bgcolor.getRGB(),
+                            compType, alpha, clipRects, srcSurf.invalidated());
+                    dstSurf.invalidate();
+                    srcSurf.validate();
+                }else{
+                    blt(srcX, srcY, srcSurfStruct, srcData,
+                            dstX, dstY, dstSurfStruct, dstData,
+                            width, height, compType, alpha,
+                            clipRects, srcSurf.invalidated());
+                    dstSurf.invalidate();
+                    srcSurf.validate();
+                }
+            }else if(comp instanceof XORComposite){
+                XORComposite xcomp = (XORComposite) comp;
+                xor(srcX, srcY, srcSurfStruct, srcData,
+                        dstX, dstY, dstSurfStruct, dstData,
+                        width, height, xcomp.getXORColor().getRGB(),
+                        clipRects, srcSurf.invalidated());
+                dstSurf.invalidate();
+                srcSurf.validate();
+            }else{
+                if(srcSurf instanceof ImageSurface){
+                    JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, 
+                            dstSurf, width, height,
+                            comp, bgcolor, clip);
+                }else{
+                    int w = srcSurf.getWidth();
+                    int h = srcSurf.getHeight();
+                    BufferedImage tmp = new BufferedImage(w, h, 
+                            BufferedImage.TYPE_INT_RGB);
+                    Surface tmpSurf = Surface.getImageSurface(tmp);
+                    long tmpSurfStruct = tmpSurf.getSurfaceDataPtr();
+                    Object tmpData = tmpSurf.getData();
+                    int tmpClip[] = new int[]{5, 0, 0, srcSurf.getWidth(),
+                            srcSurf.getHeight()};
+                    
+                    blt(0, 0, srcSurfStruct, srcData, 0, 0,
+                            tmpSurfStruct, tmpData, w, h, 
+                            AlphaComposite.SRC_OVER,
+                            1.0f, tmpClip, srcSurf.invalidated());
+                    srcSurf.validate();
+                    JavaBlitter.inst.blit(srcX, srcY, tmpSurf, dstX, dstY, 
+                            dstSurf, width, height,
+                            comp, bgcolor, clip);
+                }
+            }
+        }
+
+    }
+
+    private native void bltBG(int srcX, int srcY, long srsSurfDataPtr,
+            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
+            Object dstData, int width, int height, int bgcolor,
+            int compType, float alpha, int clip[], boolean invalidated);
+
+    private native void blt(int srcX, int srcY, long srsSurfDataPtr,
+            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
+            Object dstData, int width, int height, int compType,
+            float alpha, int clip[], boolean invalidated);
+
+    private native void xor(int srcX, int srcY, long srsSurfDataPtr,
+            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
+            Object dstData, int width, int height, int xorcolor,
+            int clip[], boolean invalidated);
+
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/NullBlitter.java b/awt/org/apache/harmony/awt/gl/render/NullBlitter.java
new file mode 100644
index 0000000..9032e4e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/NullBlitter.java
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 07.12.2005
+ *
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.geom.AffineTransform;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+
+
+public class NullBlitter implements Blitter {
+
+    static Blitter inst = new NullBlitter();
+    public static Blitter getInstance(){
+        return inst;
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            AffineTransform xform, Composite comp, Color bgcolor,
+            MultiRectArea clip) {
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            Composite comp, Color bgcolor, MultiRectArea clip) {
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/im/InputMethodContext.java b/awt/org/apache/harmony/awt/im/InputMethodContext.java
new file mode 100644
index 0000000..45ed11f
--- /dev/null
+++ b/awt/org/apache/harmony/awt/im/InputMethodContext.java
@@ -0,0 +1,563 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.im;
+
+//???AWT
+import java.awt.AWTEvent;
+import java.awt.Component;
+//import java.awt.KeyboardFocusManager;
+import java.awt.Rectangle;
+//import java.awt.Window;
+import java.awt.event.FocusEvent;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.KeyEvent;
+import java.awt.font.TextHitInfo;
+import java.awt.im.InputContext;
+import java.awt.im.InputMethodRequests;
+import java.awt.im.spi.InputMethod;
+import java.awt.im.spi.InputMethodDescriptor;
+import java.lang.Character.Subset;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+//???AWT
+//import javax.swing.JFrame;
+
+import org.apache.harmony.awt.wtk.NativeIM;
+
+/**
+ * Implementation of InputMethodContext
+ * interface, also provides all useful
+ * functionality of InputContext
+ * 
+ */
+public class InputMethodContext extends InputContext implements
+        java.awt.im.spi.InputMethodContext {    
+
+    //???AWT
+    private InputMethod inputMethod; // current IM
+    private Component client; // current "active" client component
+    //???AWT: private CompositionWindow composeWindow; // composition Window    
+    private final Map<InputMethodDescriptor, InputMethod> imInstances; // Map<InputMethodDescriptor, InputMethod>
+    private final Map<Locale, InputMethod> localeIM; // Map<Locale, InputMethod> last user-selected IM for locale
+    private final Set<InputMethod> notifyIM; // set of IMs to notify of client window bounds changes
+    
+    /**
+     * a flag indicating that IM should be notified of client window
+     * position/visibility changes as soon as it is activated(new client
+     * appears)
+     */    
+    private boolean pendingClientNotify;
+    private Component nextComp; // component to gain focus after endComposition()
+    //???AWT: private final Set<Window> imWindows; // set of all IM windows created by this instance
+    private final NativeIM nativeIM;
+    
+
+ 
+    public InputMethodContext() {
+        notifyIM = new HashSet<InputMethod>();
+//???AWT:        imWindows = new HashSet<Window>();
+        imInstances = new HashMap<InputMethodDescriptor, InputMethod>();
+        localeIM = new HashMap<Locale, InputMethod>();
+        selectInputMethod(Locale.US); // not default?
+        nativeIM = (NativeIM) inputMethod;
+    }
+
+    //???AWT
+    /*
+    @Override
+    public void dispatchEvent(AWTEvent event) {
+        int id = event.getID(); 
+        if ((id >= FocusEvent.FOCUS_FIRST) && (id <=FocusEvent.FOCUS_LAST)) {
+            dispatchFocusEvent((FocusEvent) event);
+        } else {
+            // handle special KEY_PRESSED
+            // event to show IM selection menu
+            if (id == KeyEvent.KEY_PRESSED) {
+                KeyEvent ke = (KeyEvent) event;
+                IMManager.selectIM(ke, this, 
+                                   IMManager.getWindow(ke.getComponent()));
+            }
+            // dispatch all input events to the current IM:
+            if (inputMethod != null) {
+                inputMethod.dispatchEvent(event);
+            }
+        }
+    }
+    
+    private void dispatchFocusEvent(FocusEvent fe) {
+        switch (fe.getID()) {
+        case FocusEvent.FOCUS_LOST:            
+            if (inputMethod != null) {
+                inputMethod.deactivate(fe.isTemporary());                
+            }
+            break;
+        case FocusEvent.FOCUS_GAINED:
+            
+            Component comp = fe.getComponent();
+            if (imWindows.contains(comp)) {
+                // prevent activating when IM windows
+                // attached to this context gain focus                
+                return;
+            }
+            InputMethodContext lastActive = IMManager.getLastActiveIMC();
+            if ((lastActive != this) && (lastActive != null)) {
+                lastActive.hideWindows();
+            }
+            if (inputMethod != null) {
+                activateIM(inputMethod);
+                if (!getCompositionWindow().isEmpty()) {
+                    IMManager.showCompositionWindow(composeWindow);
+                }
+                if (client == comp) {
+                    if (nextComp != null) {
+                        // temporarily got focus to
+                        // end composition
+                        endComposition();
+
+                        // transfer focus to new client
+                        client = nextComp;
+                        nextComp = null;
+                        client.requestFocusInWindow();
+                    }
+                } else if ((client != null) && getCompositionWindow().isVisible()) {
+                    // temporarily return focus back
+                    // to previous client to be able
+                    // to end composition
+                    nextComp = comp;
+                    client.requestFocusInWindow();
+                } else {
+                    client = comp;
+                }
+            }
+            if (pendingClientNotify) {
+                notifyClientWindowChange(IMManager.getWindow(comp).getBounds());
+            }
+            break;
+        }
+
+    }
+
+    private void activateIM(InputMethod im) {
+        im.activate();
+        if ((nativeIM != null) && (im != nativeIM)) {
+            // when Java IM is active
+            // native input method editor must be
+            // explicitly disabled
+            nativeIM.disableIME();
+        }
+        IMManager.setLastActiveIMC(this);
+    }
+
+    @SuppressWarnings("deprecation")
+    private void hideWindows() {
+        if (inputMethod != null) {
+            inputMethod.hideWindows();
+        }
+        if (composeWindow != null) {
+            composeWindow.hide();
+        }
+    }
+
+    private void createCompositionWindow() {
+        composeWindow = new CompositionWindow(client);        
+    }
+    
+    private CompositionWindow getCompositionWindow() {
+        if (composeWindow == null) {
+            createCompositionWindow();
+        }
+        composeWindow.setClient(client);
+        return composeWindow;        
+    }
+    */
+    
+    /**
+     * Gets input method requests for the current client
+     * irrespective of input style.
+     * @return input method requests of composition window if
+     * client is passive,
+     * otherwise input method requests of client
+     */
+    private InputMethodRequests getIMRequests() {
+        InputMethodRequests imRequests = null;
+    
+        if (client != null) {
+            imRequests = client.getInputMethodRequests();
+            //???AWT
+            /*
+            if (imRequests == null) {                
+                imRequests = getCompositionWindow().getInputMethodRequests();
+            }
+            */
+        }
+        
+        return imRequests;
+    }
+    
+    /**
+     * Gets input method requests for the current client & input style.
+     * @return input method requests of composition window if
+     * input style is "below-the-spot"(or client is passive),
+     * otherwise client input method requests
+     */
+    private InputMethodRequests getStyleIMRequests() {
+        //???AWT
+        /*
+        if (IMManager.belowTheSpot()) {
+            return getCompositionWindow().getInputMethodRequests();
+        }
+        */
+        return getIMRequests();
+    }
+    
+    @Override
+    public void dispose() {
+        if (inputMethod != null) {
+            closeIM(inputMethod);
+            inputMethod.dispose();
+        }
+        notifyIM.clear();
+        super.dispose();
+    }
+
+    @Override
+    public void endComposition() {
+        if (inputMethod != null) {
+            inputMethod.endComposition();
+        }
+        super.endComposition();
+    }
+
+    @Override
+    public Object getInputMethodControlObject() {
+        if (inputMethod != null) {
+            return inputMethod.getControlObject();
+        }
+        return super.getInputMethodControlObject();
+    }
+
+    @Override
+    public Locale getLocale() {
+        if (inputMethod != null) {
+            return inputMethod.getLocale();
+        }
+        return super.getLocale();
+    }
+
+    @Override
+    public boolean isCompositionEnabled() {
+        if (inputMethod != null) {
+            return inputMethod.isCompositionEnabled();
+        }
+        return super.isCompositionEnabled();
+    }
+
+    @Override
+    public void reconvert() {
+        if (inputMethod != null) {
+            inputMethod.reconvert();
+        }
+        super.reconvert();
+    }
+
+    //???AWT
+    /*
+    @Override
+    public void removeNotify(Component client) {
+        if ((inputMethod != null) && (client == this.client)) {
+            inputMethod.removeNotify();
+            client = null;
+            // set flag indicating that IM should be notified
+            // as soon as it is activated(new client appears)
+            pendingClientNotify = true;
+        }
+        
+        super.removeNotify(client);
+    }
+    */
+
+    @Override
+    public boolean selectInputMethod(Locale locale) {        
+        
+        if ((inputMethod != null) && inputMethod.setLocale(locale)) {
+            return true;
+        }
+        // first
+        // take last user-selected IM for locale            
+        InputMethod newIM = localeIM.get(locale);
+        
+        // if not found search through IM descriptors
+        // and take already created instance if exists
+        // or create, store new IM instance in descriptor->instance map
+        //???AWT
+        /*
+        if (newIM == null) {
+            try {
+                newIM = getIMInstance(IMManager.getIMDescriptors().iterator(),
+                                      locale);
+            } catch (Exception e) {
+                // ignore exceptions - just return false
+            }
+        }
+        */
+        
+        return switchToIM(locale, newIM);
+    }
+
+    private boolean switchToIM(Locale locale, InputMethod newIM) {
+        //???AWT
+        /*
+        if (newIM != null) {
+            closeIM(inputMethod);
+            client = KeyboardFocusManager.
+            getCurrentKeyboardFocusManager().getFocusOwner();
+            initIM(newIM, locale);
+            inputMethod = newIM;
+            
+            return true;
+        }
+        */
+        return false;
+    }
+    
+    /**
+     * Is called when IM is selected from UI
+     */
+    void selectIM(InputMethodDescriptor imd, Locale locale) {
+        try {
+            switchToIM(locale, getIMInstance(imd));            
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Gets input method instance for the given
+     * locale from the given list of descriptors
+     * @param descriptors iterator of the list of IM descriptors
+     * @param locale the locale to be supported by the IM
+     * @return input method instance
+     * @throws Exception
+     */
+    private InputMethod getIMInstance(Iterator<InputMethodDescriptor> descriptors,
+                                      Locale locale) throws Exception {
+        while (descriptors.hasNext()) {
+            InputMethodDescriptor desc = descriptors.next();
+            Locale[] locs = desc.getAvailableLocales();
+            for (Locale element : locs) {
+                if (locale.equals(element)) {
+                    return getIMInstance(desc);
+                }
+            }
+        }
+        return null;
+    }
+
+    private InputMethod getIMInstance(InputMethodDescriptor imd) throws Exception {
+        InputMethod im = imInstances.get(imd);
+        if (im == null) {
+            im = imd.createInputMethod();
+            im.setInputMethodContext(this);
+            imInstances.put(imd, im);
+        }
+        return im;
+    }
+    
+    private void initIM(InputMethod im, Locale locale) {
+        if (im == null) {
+            return;
+        }
+        im.setLocale(locale);
+        im.setCharacterSubsets(null);
+        //???AWT: activateIM(im);
+        try {
+            im.setCompositionEnabled(inputMethod != null ? 
+                                     inputMethod.isCompositionEnabled() : true);
+        } catch (UnsupportedOperationException uoe) {
+
+        }
+        
+    }
+
+    private void closeIM(InputMethod im) {
+        if (im == null) {
+            return;
+        }
+        if (im.isCompositionEnabled()) {
+            im.endComposition();
+        }
+        
+        im.deactivate(true);
+        im.hideWindows();
+        
+    }
+    
+    @Override
+    public void setCharacterSubsets(Subset[] subsets) {
+        if (inputMethod != null) {
+            inputMethod.setCharacterSubsets(subsets);
+        }
+        super.setCharacterSubsets(subsets);
+    }
+
+    @Override
+    public void setCompositionEnabled(boolean enable) {
+        if (inputMethod != null) {
+            inputMethod.setCompositionEnabled(enable);
+        }
+        super.setCompositionEnabled(enable);
+    }
+
+    //???AWT
+    /*
+    public JFrame createInputMethodJFrame(String title,
+                                          boolean attachToInputContext) {
+        JFrame jf = new IMJFrame(title, attachToInputContext ? this : null);
+        imWindows.add(jf);
+        return jf;
+    }
+
+    public Window createInputMethodWindow(String title,
+                                          boolean attachToInputContext) {
+        Window w = new IMWindow(title, attachToInputContext ? this : null);
+        imWindows.add(w);
+        return w;
+    }
+    */
+    
+    @SuppressWarnings("deprecation")
+    public void dispatchInputMethodEvent(int id,
+                                         AttributedCharacterIterator text,
+                                         int committedCharacterCount,
+                                         TextHitInfo caret,
+                                         TextHitInfo visiblePosition) {
+        if (client == null) {
+            return;
+        }
+        //???AWT
+        /*
+        InputMethodEvent ime = new InputMethodEvent(client, id, text,
+                                                    committedCharacterCount,
+                                                    caret, visiblePosition);
+        
+
+        if ((client.getInputMethodRequests() != null) &&
+            !IMManager.belowTheSpot()) {
+            
+            client.dispatchEvent(ime);
+        } else {
+            
+            // show/hide composition window if necessary
+            if (committedCharacterCount < text.getEndIndex()) {
+                IMManager.showCompositionWindow(getCompositionWindow());
+            } else {
+                getCompositionWindow().hide();
+            }
+            composeWindow.getActiveClient().dispatchEvent(ime);
+        }
+        */
+        
+    }
+
+    public void enableClientWindowNotification(InputMethod inputMethod,
+                                               boolean enable) {
+        if (enable) {
+            notifyIM.add(inputMethod);
+            //???AWT
+            /*
+            if (client != null) {
+                notifyClientWindowChange(IMManager.getWindow(client).getBounds());
+            } else {
+                pendingClientNotify = true;
+            }
+            */
+        } else {
+            notifyIM.remove(inputMethod);
+        }
+        
+    }
+
+    public AttributedCharacterIterator cancelLatestCommittedText(
+                                                                 Attribute[] attributes) {
+        return getIMRequests().cancelLatestCommittedText(attributes);
+    }
+
+    public AttributedCharacterIterator getCommittedText(int beginIndex,
+                                                        int endIndex,
+                                                        Attribute[] attributes) {
+        return getIMRequests().getCommittedText(beginIndex, endIndex,
+                                                attributes);
+    }
+
+    public int getCommittedTextLength() {
+        return getIMRequests().getCommittedTextLength();
+    }
+
+    public int getInsertPositionOffset() {
+        return getIMRequests().getInsertPositionOffset();
+    }
+
+    public TextHitInfo getLocationOffset(int x, int y) {
+        InputMethodRequests imr = getStyleIMRequests();
+        if (imr != null) {
+            return imr.getLocationOffset(x, y);
+        }
+        return null;
+    }
+
+    public AttributedCharacterIterator getSelectedText(Attribute[] attributes) {
+        return getIMRequests().getSelectedText(attributes);
+    }
+
+    public Rectangle getTextLocation(TextHitInfo offset) {        
+        return getStyleIMRequests().getTextLocation(offset);
+    }
+    
+    /**
+     * To be called by AWT when client Window's bounds/visibility/state
+     * change
+     */
+    public void notifyClientWindowChange(Rectangle bounds) {
+        if (notifyIM.contains(inputMethod)) {
+            inputMethod.notifyClientWindowChange(bounds);
+        }
+        pendingClientNotify = false;
+    }
+
+    public final InputMethod getInputMethod() {
+        return inputMethod;
+    }
+
+    public final Component getClient() {
+        return client;
+    }
+
+    public final NativeIM getNativeIM() {
+        return nativeIM;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/internal/nls/Messages.java b/awt/org/apache/harmony/awt/internal/nls/Messages.java
new file mode 100644
index 0000000..96762c9
--- /dev/null
+++ b/awt/org/apache/harmony/awt/internal/nls/Messages.java
@@ -0,0 +1,143 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
+ * All changes made to this file manually will be overwritten 
+ * if this tool runs again. Better make changes in the template file.
+ */
+
+package org.apache.harmony.awt.internal.nls;
+
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+// BEGIN android-deleted
+/*
+ * For Android, this module is a separate library and not part of the
+ * boot classpath, so its resources won't be found on the boot classpath
+ * as is assumed by MsgHelp.getString(). We instead use a local MsgHelp
+ * which bottoms out in a call to the useful part of its lower-level
+ * namesake.
+ */
+//import org.apache.harmony.kernel.vm.VM;
+//import org.apache.harmony.luni.util.MsgHelp;
+// END android-deleted
+
+/**
+ * This class retrieves strings from a resource bundle and returns them,
+ * formatting them with MessageFormat when required.
+ * <p>
+ * It is used by the system classes to provide national language support, by
+ * looking up messages in the <code>
+ *    org.apache.harmony.awt.internal.nls.messages
+ * </code>
+ * resource bundle. Note that if this file is not available, or an invalid key
+ * is looked up, or resource bundle support is not available, the key itself
+ * will be returned as the associated message. This means that the <em>KEY</em>
+ * should a reasonable human-readable (english) string.
+ * 
+ */
+public class Messages {
+
+    // BEGIN android-deleted
+    //private static final String sResource =
+    //    "org.apache.harmony.awt.internal.nls.messages";
+    // END android-deleted
+
+    /**
+     * Retrieves a message which has no arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg) {
+        return MsgHelp.getString(msg);
+    }
+
+    /**
+     * Retrieves a message which takes 1 argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            Object the object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg) {
+        return getString(msg, new Object[] { arg });
+    }
+
+    /**
+     * Retrieves a message which takes 1 integer argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            int the integer to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, int arg) {
+        return getString(msg, new Object[] { Integer.toString(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 1 character argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            char the character to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, char arg) {
+        return getString(msg, new Object[] { String.valueOf(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 2 arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg1
+     *            Object an object to insert in the formatted output.
+     * @param arg2
+     *            Object another object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg1, Object arg2) {
+        return getString(msg, new Object[] { arg1, arg2 });
+    }
+
+    /**
+     * Retrieves a message which takes several arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param args
+     *            Object[] the objects to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object[] args) {
+        return MsgHelp.getString(msg, args);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java b/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java
new file mode 100644
index 0000000..b57fe11
--- /dev/null
+++ b/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/*
+ * This implementation is based on the class of the same name in
+ * org.apache.harmony.luni.util.
+ */
+
+package org.apache.harmony.awt.internal.nls;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Logger;
+import java.util.Locale;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.MissingResourceException;
+
+/**
+ * This class contains helper methods for loading resource bundles and
+ * formatting external message strings.
+ */
+public final class MsgHelp {
+    /** name of the resource for this class */
+    private static final String RESOURCE_NAME =
+        "/org/apache/harmony/awt/internal/nls/messages.properties";
+
+    /** the resource bundle for this class */
+    private static final ResourceBundle THE_BUNDLE;
+
+    static {
+        ResourceBundle rb = null;
+
+        try {
+            InputStream in = MsgHelp.class.getResourceAsStream(
+                    RESOURCE_NAME);
+            rb = new PropertyResourceBundle(in);
+        } catch (IOException ex) {
+            Logger.global.warning("Couldn't read resource bundle: " +
+                    ex);
+        } catch (RuntimeException ex) {
+            // Shouldn't happen, but deal at least somewhat gracefully.
+            Logger.global.warning("Couldn't find resource bundle: " +
+                    ex);
+        }
+
+        THE_BUNDLE = rb;
+    }
+    
+    public static String getString(String msg) {
+        if (THE_BUNDLE == null) {
+            return msg;
+        }
+        try {
+            return THE_BUNDLE.getString(msg);
+        } catch (MissingResourceException e) {
+            return "Missing message: " + msg;
+        }
+    }
+    
+    static public String getString(String msg, Object[] args) {
+        String format = msg;
+        if (THE_BUNDLE != null) {
+            try {
+                format = THE_BUNDLE.getString(msg);
+            } catch (MissingResourceException e) {
+            }
+        }
+
+        return org.apache.harmony.luni.util.MsgHelp.format(format, args);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/state/MenuItemState.java b/awt/org/apache/harmony/awt/state/MenuItemState.java
new file mode 100644
index 0000000..b13e50b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/state/MenuItemState.java
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.state;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+
+/**
+ * State of menu item
+ */
+
+public interface MenuItemState {
+
+    String getText();
+    Rectangle getTextBounds();
+    void setTextBounds(int x, int y, int w, int h);
+
+    String getShortcut();
+    Rectangle getShortcutBounds();
+    void setShortcutBounds(int x, int y, int w, int h);
+
+    Rectangle getItemBounds();
+    void setItemBounds(int x, int y, int w, int h);
+
+    boolean isMenu();
+    boolean isChecked();
+    boolean isEnabled();
+
+    boolean isCheckBox();
+    boolean isSeparator();
+
+    Dimension getMenuSize();
+}
diff --git a/awt/org/apache/harmony/awt/state/MenuState.java b/awt/org/apache/harmony/awt/state/MenuState.java
new file mode 100644
index 0000000..564a49a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/state/MenuState.java
@@ -0,0 +1,46 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.state;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Point;
+
+/**
+ * State of pop-up or drop-down menu
+ */
+
+public interface MenuState {
+    int getWidth();
+    int getHeight();
+    Point getLocation();
+
+    void setSize(int w, int h);
+
+    Font getFont();
+    boolean isFontSet();
+    FontMetrics getFontMetrics(Font f);
+
+    int getItemCount();
+    int getSelectedItemIndex();
+
+    MenuItemState getItem(int index);
+}
diff --git a/awt/org/apache/harmony/awt/state/State.java b/awt/org/apache/harmony/awt/state/State.java
new file mode 100644
index 0000000..4b8706d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/state/State.java
@@ -0,0 +1,55 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.state;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Rectangle;
+
+/**
+ * State of the component
+ */
+public interface State {
+
+    boolean isEnabled();
+    boolean isVisible();
+    boolean isFocused();
+
+    Font getFont();
+    boolean isFontSet();
+    FontMetrics getFontMetrics();
+
+    Color getBackground();
+    boolean isBackgroundSet();
+
+    Color getTextColor();
+    boolean isTextColorSet();
+
+    Rectangle getBounds();
+    Dimension getSize();
+
+    Dimension getDefaultMinimumSize();
+    void setDefaultMinimumSize(Dimension size);
+
+    long getWindowId();
+}
diff --git a/awt/org/apache/harmony/awt/wtk/CreationParams.java b/awt/org/apache/harmony/awt/wtk/CreationParams.java
new file mode 100644
index 0000000..63c581d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/CreationParams.java
@@ -0,0 +1,133 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+/**
+ * This class describes cross-platform NativeWindow creation params
+ * See also WindowFactory.createWindow
+ */
+public class CreationParams {
+    /**
+     * Initial state is maximized verticaly
+     */
+    public final long MAXIMIZED_VERT = 1;
+    /**
+     * Initial state is maximized horizontaly
+     */
+    public final long MAXIMIZED_HORIZ = 2;
+    /**
+     * Initial state is maximized both
+     * horizontaly and verticaly
+     */
+    public final long MAXIMIZED = 3;
+
+    /**
+     * The top-level window that has all possible decorations,
+     * has no owner and is displayed in taskbar
+     */
+    public final static int DECOR_TYPE_FRAME = 1;
+    /**
+     * The dialog window
+     */
+    public final static int DECOR_TYPE_DIALOG = 2;
+    /**
+     * The transient undecorated pop-up window
+     */
+    public final static int DECOR_TYPE_POPUP = 3;
+    /**
+     * The undecoraded pop-up window
+     */
+    public final static int DECOR_TYPE_UNDECOR = 4;
+    /**
+     * Non-MDI child window
+     */
+    public final static int DECOR_TYPE_NONE = 0;
+
+    /**
+     * Initial x.
+     */
+    public int x = 0;
+    /**
+     * Initial y.
+     */
+    public int y = 0;
+    /**
+     * Initial width.
+     */
+    public int w = 1;
+    /**
+     * Initial height.
+     */
+    public int h = 1;
+    /**
+     * The decoration type of the top-level window. The possible values are:
+     * DECOR_TYPE_FRAME, DECOR_TYPE_DIALOG, DECOR_TYPE_POPUP and DECOR_TYPE_UNDECOR
+     */
+    public int decorType = DECOR_TYPE_NONE;
+    /**
+     * Window is child of parent, otherwise it's
+     * toplevel(child of desktop) window owned by parent.
+     */
+    public boolean child = false;
+    /**
+     * Window is resizable
+     */
+    public boolean resizable = true;
+    /**
+     * The window has no decorations
+     */
+    public boolean undecorated = false;
+    /**
+     * Initial visibility state.
+     */
+    public boolean visible = false;
+    /**
+     * Window is ALWAYS topmost in Z order.
+     */
+    public boolean topmost = false;
+    /**
+     * Window is disabled.
+     */
+    public boolean disabled = false;
+    /**
+     * Window initially iconified.
+     */
+    public boolean iconified = false;
+    /**
+     * Bitwise OR of MAXIMIZED_* constants.
+     * Means if window is initially maximized.
+     */
+    public int maximizedState = 0;
+    /**
+     * Tells that window position should be determined by native windowing system 
+     */
+    public boolean locationByPlatform = false;
+    /**
+     * Id of parent or owner window, see child field
+     * For non-child window without owner equals 0.
+     */
+    public long parentId = 0;
+    /**
+     * Name wich is displayed on titlebar, taskbar and visible
+     * for system requests.
+     */
+    public String name = null;
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/wtk/CursorFactory.java b/awt/org/apache/harmony/awt/wtk/CursorFactory.java
new file mode 100644
index 0000000..35e7d33
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/CursorFactory.java
@@ -0,0 +1,85 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Dimension;
+import java.awt.Image;
+
+/**
+ * Provides factory for NativeCursor
+ */
+public abstract class CursorFactory {
+    protected NativeCursor[] systemCursors = {
+            null, null, null, null,
+            null, null, null, null,
+            null, null, null, null,
+            null, null,
+    };
+    /**
+     * Creates and returns NativeCursor for predefined
+     * Java Cursor
+     *
+     * @param type - type of predefined Java Cursor
+     * @return created cursor
+     */
+    public abstract NativeCursor createCursor(int type);
+
+    /**
+     * Gets a cached instance of system(predefined) native cursor
+     * or creates a new one. This is a platform-independent method.
+     *
+     * @param type - type of predefined Java Cursor
+     * @return created cursor
+     */
+    public NativeCursor getCursor(int type) {
+        if (type >= 0 && type < systemCursors.length) {
+            NativeCursor cursor = systemCursors[type];
+            if (cursor == null) {
+                cursor = createCursor(type);
+                systemCursors[type] = cursor;
+            }
+            return cursor;
+        }
+        return null;
+    }
+    /**
+     * Creates and returns custom NativeCursor from image
+     *
+     * @param img - image(source) to create cursor from
+     * @param xHotSpot - x coordinate of the hotspot relative to the source's origin
+     * @param yHotSpot - y coordinate of the hotspot relative to the source's origin
+     * @return created cursor
+     */
+    public abstract NativeCursor createCustomCursor(Image img, int xHotSpot, int yHotSpot);
+
+    /**
+     * Query native system for the best cursor size closest to specified dimensions
+     * @param prefWidth - preferred width
+     * @param prefHeight - preferred height
+     * @return closest supported dimensions to ones specified
+     */
+    public abstract Dimension getBestCursorSize(int prefWidth, int prefHeight);
+
+    /**
+     * @return maximum number of colors supported by custom cursors
+     */
+    public abstract int getMaximumCursorColors();
+}
diff --git a/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java b/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java
new file mode 100644
index 0000000..0d7c84f
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java
@@ -0,0 +1,82 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov, Alexey A. Petrenko, Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.peer.FontPeer;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.font.FontManager;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+
+
+/**
+ * GraphicsFactory interface defines methods for Graphics2D 
+ * and font stuff instances factories.
+ */
+public interface GraphicsFactory {
+    static final FontMetrics cacheFM[] =  new FontMetrics[10];
+    
+    /**
+     * This method creates Graphics2D instance for specified native window.
+     *  
+     * @param win Native window to draw
+     * @param translateX Translation along X axis
+     * @param translateY Translation along Y axis
+     * @param clip Clipping area for a new Graphics2D instance
+     * @return New Graphics2D instance for specified native window
+     * @deprecated
+     */
+    @Deprecated
+    Graphics2D getGraphics2D(NativeWindow win, int translateX, int translateY, MultiRectArea clip);
+
+    /**
+     * This method creates Graphics2D instance for specified native window.
+     *  
+     * @param win Native window to draw
+     * @param translateX Translation along X axis
+     * @param translateY Translation along Y axis
+     * @param width Width of drawing area
+     * @param height Height of drawing area
+     * @return New Graphics2D instance for specified native window
+     */
+    Graphics2D getGraphics2D(NativeWindow win, int translateX, int translateY, int width, int height);
+    // ???AWT: not standard harmony
+    Graphics2D getGraphics2D(Canvas c, Paint p);
+    
+    /**
+     * Creates instance of GraphicsEnvironment for specified WindowFactory
+     *  
+     * @param wf WindowFactory
+     * @return New instance of GraphicsEnvironment
+     */
+    GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf);
+    
+    // Font methods
+    FontMetrics getFontMetrics(Font font);
+    FontManager getFontManager();
+    FontPeer getFontPeer(Font font);
+    Font embedFont(String fontFilePath);
+}
diff --git a/awt/org/apache/harmony/awt/wtk/KeyInfo.java b/awt/org/apache/harmony/awt/wtk/KeyInfo.java
new file mode 100644
index 0000000..1f8a29a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/KeyInfo.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.event.KeyEvent;
+
+/**
+ * Keystroke information
+ */
+
+public final class KeyInfo {
+
+    public int vKey;
+    public int keyLocation;
+    public final StringBuffer keyChars;
+
+    public static final int DEFAULT_VKEY = KeyEvent.VK_UNDEFINED;
+    public static final int DEFAULT_LOCATION = KeyEvent.KEY_LOCATION_STANDARD;
+
+    public KeyInfo() {
+        vKey = DEFAULT_VKEY;
+        keyLocation = DEFAULT_LOCATION;
+        keyChars = new StringBuffer();
+    }
+
+    public void setKeyChars(char ch) {
+        keyChars.setLength(0);
+        keyChars.append(ch);
+    }
+
+    public void setKeyChars(StringBuffer sb) {
+        keyChars.setLength(0);
+        keyChars.append(sb);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeCursor.java b/awt/org/apache/harmony/awt/wtk/NativeCursor.java
new file mode 100644
index 0000000..2c6eb1e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeCursor.java
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+/**
+ * The interface provides access to platform dependent functionality
+ * for the class java.awt.Cursor.
+ */
+public interface NativeCursor {
+    /**
+     * Sets the current cursor shape
+     * to this cursor when a pointer is inside
+     * @param winID - window(currently used only on X11)
+     */
+    void setCursor(long winID);
+    /**
+     * Destroys the native resource associated with
+     * this cursor
+     */
+    void destroyCursor();
+
+    /**
+     * @return Native handle associated with this cursor
+     */
+    long getId();
+
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeEvent.java b/awt/org/apache/harmony/awt/wtk/NativeEvent.java
new file mode 100644
index 0000000..1471c1a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeEvent.java
@@ -0,0 +1,268 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+
+
+/**
+ * The interface describing cross-platform translation of system
+ * messages.
+ *
+ * <p/>Some messages can appear only on specific platform,
+ * but they still can have cross-platform interpretation if the
+ * application should be aware of them and can react using
+ * cross-platform API.
+ *
+ */
+public abstract class NativeEvent {
+
+    /**
+     * Message has no common cross-platform
+     * interpretation and should be skipped.
+     */
+    public static final int ID_PLATFORM = 0;
+
+    /**
+     * Window bounds have changed.
+     */
+    public static final int ID_BOUNDS_CHANGED = -1;
+
+    /**
+     * Window decoration size has changed.
+     */
+    public static final int ID_INSETS_CHANGED = -2;
+
+    /**
+     * Window was just created (WM_CREATE on Windows)
+     */
+    public static final int ID_CREATED = -3;
+
+    /**
+     * Mouse grab was canceled by the native system
+     */
+    public static final int ID_MOUSE_GRAB_CANCELED = -4;
+
+    /**
+     * System color scheme or visual theme was changed
+     */
+    public static final int ID_THEME_CHANGED = -5;
+
+    protected long windowId;
+    protected int eventId;
+    protected long otherWindowId;
+
+    protected Point screenPos;
+    protected Point localPos;
+    protected Rectangle windowRect;
+
+    protected int modifiers;
+    protected int mouseButton;
+    protected int wheelRotation;
+
+    protected KeyInfo keyInfo = new KeyInfo();
+
+    protected int windowState = -1;
+    protected long time;
+
+    /**
+     * Returns the system window id of the event recipient.
+     * @return HWND on Windows, xwindnow on X
+     */
+    public long getWindowId() {
+        return windowId;
+    }
+
+    /**
+     * Returns cross-platform event id
+     * should be one of ID_* constants or
+     * id constants from java.awt.AWTEvent subclasess
+     * @return cross-platform event id
+     */
+    public int getEventId() {
+        return eventId;
+    }
+
+    /**
+     * Returns the position of cursor when event occured relative to
+     * top-left corner of recipient window
+     * @return position of cursor in local coordinates
+     */
+    public Point getLocalPos() {
+        return localPos;
+    }
+
+    /**
+     * Returns the position of cursor when event occured
+     * in screen coordinates.
+     * @return position of cursor in screen coordinates
+     */
+    public Point getScreenPos() {
+        return screenPos;
+    }
+
+    /**
+     * The recipient window bounds when the event occured
+     * @return window bounds
+     */
+    public Rectangle getWindowRect() {
+        return windowRect;
+    }
+
+    /**
+     * Returns the state of keyboard and mouse buttons when the event
+     * occured if event from mouse or keyboard, for other events can
+     * return junk values. The value is bitwise OR of
+     * java.awt.event.InputEvent *_DOWN constants.
+     *
+     * Method is aware of system mouse button swap for left-hand
+     * mouse and return swapped values.
+     * @return bitwise OR of java.awt.event.InputEvent *_DOWN constants
+     */
+    public int getInputModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * Returns the iconified/maximized state of recipient window if
+     * event is state related, for other events can junk values.
+     * The value has the same meaning as Frame.getExtendedState
+     * It's bitwise OR of ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT
+     * @return bitwise OR of ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT
+     */
+    public int getWindowState() {
+        return windowState;
+    }
+
+    /**
+     * The same meaning as java.awt.event.getKeyCode
+     * @return java.awt.event VK_* constant
+     */
+    public int getVKey() {
+        return (keyInfo != null) ? keyInfo.vKey : KeyInfo.DEFAULT_VKEY;
+    }
+
+    /**
+     * The same meaning as java.awt.event.getKeyLocation
+     * @return java.awt.event KEY_LOCATION_* constant
+     */
+    public int getKeyLocation() {
+        return (keyInfo != null) ? keyInfo.keyLocation : KeyInfo.DEFAULT_LOCATION;
+    }
+
+    /**
+     * Return the string of characters associated with the event
+     * Has meaning only for KEY_PRESSED as should be translated to
+     * serie of KEY_TYPED events. For dead keys and input methods
+     * one key press can generate multiple key chars.
+     * @return string of characters
+     */
+    public StringBuffer getKeyChars() {
+        if (keyInfo == null) {
+            return null;
+        }
+        if (keyInfo.vKey == KeyEvent.VK_ENTER) {
+            keyInfo.keyChars.setLength(0);
+            keyInfo.setKeyChars('\n');
+        }
+        return keyInfo.keyChars;
+    }
+
+    public char getLastChar() {
+        if (keyInfo == null || keyInfo.keyChars.length() == 0) {
+            return KeyEvent.CHAR_UNDEFINED;
+        }
+        return keyInfo.keyChars.charAt(keyInfo.keyChars.length()-1);
+    }
+
+    /**
+     * Returns the number of mouse button which changed it's state,
+     * otherwise 0.
+     * Left button is 1, middle button is 2, right button is 3.
+     *
+     * Method is aware of system mouse button swap for left-hand
+     * mouse and return swapped values.
+     * @return mouse button number
+     */
+    public int getMouseButton() {
+        return mouseButton;
+    }
+
+    /**
+     * Returns time when the message was received
+     * @return time in milliseconds
+     */
+    public long getTime() {
+        return time;
+    }
+
+    /**
+     * For the focus event contains the oposite window.
+     * This means it lost focus if recipient gains it,
+     * or will gain focus if recipient looses it.
+     * @return HWND on Windows, xwindnow on X
+     */
+    public long getOtherWindowId() {
+        return otherWindowId;
+    }
+
+    /**
+     * Returns the "dirty" area of the window as set of non-intersecting
+     * rectangles. This area is to be painted.
+     * @return non-empty array of null if empty
+     */
+    public abstract MultiRectArea getClipRects();
+
+    /**
+     * Returns the "dirty" area of the window as one rectangle.
+     * This area is to be painted.
+     * @return non-null Rectangle
+     */
+    public abstract Rectangle getClipBounds();
+
+    /**
+     * Returns the window insets. Insets is area which belongs to
+     * window somehow but is outside of it's client area,
+     * it usually contains system provided border and titlebar.
+     * @return non-null java.awt.Insets
+     */
+    public abstract Insets getInsets();
+
+    /**
+     * Returns true if event is popup menu trigger.
+     * @return boolean flag
+     */
+    public abstract boolean getTrigger();
+
+    /**
+     * Returns the number of "clicks" the mouse wheel was rotated.
+     * @return negative values if the mouse wheel was rotated up/away from the user,
+     * and positive values if the mouse wheel was rotated down/ towards the user
+     */
+    public int getWheelRotation() {
+        return wheelRotation;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java b/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java
new file mode 100644
index 0000000..0738cd1
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java
@@ -0,0 +1,117 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.util.LinkedList;
+
+
+/**
+ * Describes the cross-platform native event queue interface
+ *
+ * <p/> The implementation constructor should remember thread it was
+ * created. All other methods would be called obly from this thread,
+ * except awake().
+ */
+public abstract class NativeEventQueue {
+    
+    private ShutdownWatchdog shutdownWatchdog;
+    private class EventMonitor {}
+    private final Object eventMonitor = new EventMonitor();
+    private final LinkedList<NativeEvent> eventQueue = new LinkedList<NativeEvent>();
+
+    public static abstract class Task {
+        public volatile Object returnValue;
+
+        public abstract void perform();
+    }
+    
+    /**
+     * Blocks current thread until native event queue is not empty
+     * or awaken from other thread by awake().
+     *
+     * <p/>Should be called only on tread which
+     * will process native events.
+     *
+     * @return if event loop should be stopped
+     */
+    public abstract boolean waitEvent();
+
+    /**
+     * Determines whether or not the native event queue is empty.
+     * An queue is empty if it contains no messages waiting.
+     *
+     * @return true if the queue is empty; false otherwise
+     */
+    public boolean isEmpty() {
+        synchronized(eventQueue) {
+            return eventQueue.isEmpty();
+        }
+    }
+
+    public NativeEvent getNextEvent() {
+        synchronized (eventQueue) {
+            if (eventQueue.isEmpty()) {
+                shutdownWatchdog.setNativeQueueEmpty(true);
+                return null;
+            }
+            return eventQueue.remove(0);
+        }
+    }
+    
+    protected void addEvent(NativeEvent event) {
+        synchronized (eventQueue) {
+            eventQueue.add(event);
+            shutdownWatchdog.setNativeQueueEmpty(false);
+        }
+        synchronized (eventMonitor) {
+            eventMonitor.notify();
+        }
+    }
+
+    public final Object getEventMonitor() {
+        return eventMonitor;
+    }
+
+    public abstract void awake();
+
+    /**
+     * Gets AWT system window ID.
+     *
+     * @return AWT system window ID
+     */
+    public abstract long getJavaWindow();
+
+    /**
+     * Add NativeEvent to the queue
+     */
+    public abstract void dispatchEvent();
+
+    public abstract void performTask(Task task);
+
+    public abstract void performLater(Task task);
+    
+    public final void setShutdownWatchdog(ShutdownWatchdog watchdog) {
+        synchronized (eventQueue) {
+            shutdownWatchdog = watchdog;
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeEventThread.java b/awt/org/apache/harmony/awt/wtk/NativeEventThread.java
new file mode 100644
index 0000000..d50add4
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeEventThread.java
@@ -0,0 +1,78 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+
+/**
+ * NativeEventThread
+ */
+public class NativeEventThread extends Thread {
+    
+    public interface Init {
+        WTK init();
+    }
+    
+    NativeEventQueue nativeQueue;
+    Init init;
+    
+    private WTK wtk;
+    
+    public NativeEventThread() {
+        super("AWT-NativeEventThread"); //$NON-NLS-1$
+        setDaemon(true);
+    }
+
+    @Override
+    public void run() {
+        synchronized (this) {
+            try {
+                wtk = init.init();
+                nativeQueue = wtk.getNativeEventQueue();
+            } finally {
+                notifyAll();
+            }
+        }
+        
+        runModalLoop();
+    }
+
+    void runModalLoop() {
+        while (nativeQueue.waitEvent()) {
+            nativeQueue.dispatchEvent();
+        }
+    }
+    
+    public void start(Init init) {
+        synchronized (this) {
+            this.init = init;
+            super.start();
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+    
+    public WTK getWTK() {
+        return wtk;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeIM.java b/awt/org/apache/harmony/awt/wtk/NativeIM.java
new file mode 100644
index 0000000..1626f4a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeIM.java
@@ -0,0 +1,130 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.AWTEvent;
+import java.awt.AWTException;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.im.spi.InputMethod;
+import java.awt.im.spi.InputMethodContext;
+import java.awt.im.spi.InputMethodDescriptor;
+import java.lang.Character.Subset;
+import java.util.Locale;
+
+/**
+ * A cross-platform interface for native input
+ * method sub-system functionality.
+ */
+public abstract class NativeIM implements InputMethod, InputMethodDescriptor {
+    protected InputMethodContext imc;
+
+    public void activate() {
+
+    }
+
+    public void deactivate(boolean isTemporary) {
+
+    }
+
+    public void dispatchEvent(AWTEvent event) {
+
+    }
+
+    public void dispose() {
+
+    }
+
+    public void endComposition() {
+
+    }
+
+    public Object getControlObject() {
+        return null;
+    }
+
+    public Locale getLocale() {
+        return null;
+    }
+
+    public void hideWindows() {
+
+    }
+
+    public boolean isCompositionEnabled() {
+        return false;
+    }
+
+    public void notifyClientWindowChange(Rectangle bounds) {
+
+    }
+
+    public void reconvert() {
+
+    }
+
+    public void removeNotify() {
+
+    }
+
+    public void setCharacterSubsets(Subset[] subsets) {
+
+    }
+    
+    public void setCompositionEnabled(boolean enable) {
+
+    }
+
+    public void setInputMethodContext(InputMethodContext context) {
+        imc = context;
+    }
+
+    public boolean setLocale(Locale locale) {
+        return false;
+    }
+
+    public Locale[] getAvailableLocales() throws AWTException {
+    	return new Locale[]{Locale.getDefault(), Locale.ENGLISH};
+        //return new Locale[]{Locale.getDefault(), Locale.US};
+    }
+
+    public InputMethod createInputMethod() throws Exception {        
+        return this;
+    }
+
+    public String getInputMethodDisplayName(Locale inputLocale,
+                                            Locale displayLanguage) {
+        return "System input methods"; //$NON-NLS-1$
+    }
+
+    public Image getInputMethodIcon(Locale inputLocale) {
+        return null;
+    }
+
+    public boolean hasDynamicLocaleList() {
+        return false;
+    }
+    
+    public abstract void disableIME();
+    
+//    public abstract void disableIME(long id);
+
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java b/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java
new file mode 100644
index 0000000..0696975
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java
@@ -0,0 +1,42 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Point;
+
+/**
+ * The interface provides access to platform dependent functionality
+ * for classes java.awt.PointerInfo & java.awt.MouseInfo.
+ */
+public interface NativeMouseInfo {
+
+    /**
+     * Returns the Point that represents
+     * the coordinates of the pointer on the screen.
+     */
+    Point getLocation();
+
+    /**
+     * Returns the number of buttons on the mouse.
+     * If no mouse is installed returns -1.
+     */
+    int getNumberOfButtons();
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeRobot.java b/awt/org/apache/harmony/awt/wtk/NativeRobot.java
new file mode 100644
index 0000000..0b354d0
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeRobot.java
@@ -0,0 +1,75 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+
+/**
+ * A cross-platform interface for java.awt.Robot implementation
+ */
+public interface NativeRobot {
+
+    /**
+     * @see java.awt.Robot#createScreenCapture(Rectangle)
+     * @param screenRect rectangle to capture in screen coordinates
+     * @return the captured image or null if
+     * capture failed.
+     */
+    BufferedImage createScreenCapture(Rectangle screenRect);
+
+    /**
+     * @see java.awt.Robot#getPixelColor(int, int)
+     */
+    Color getPixel(int x, int y);
+
+    /**
+     * Generate a native system keyboard input event.
+     * @param keycode A Java virtual key code
+     * @param press A key is pressed if true, released otherwise
+     * @see java.awt.Robot#keyPress(int)
+     * @throws IllegalArgumentException if keycode is invalid in the native system
+     */
+    void keyEvent(int keycode, boolean press);
+
+    /**
+     * Generate a native system mouse button(s) press or release event.
+     * @param buttons A mask of Java mouse button flags
+     * @param press buttons are pressed if true, released otherwise
+     * @see java.awt.Robot#mousePress(int)
+     */
+    void mouseButton(int buttons, boolean press);
+
+    /**
+     * Generate a native system mouse motion event.
+     *
+     * @see java.awt.Robot#mouseMove(int, int)
+     */
+    void mouseMove(int x, int y);
+
+    /**
+     * Generate a native system mouse wheel event.
+     *
+     * @see java.awt.Robot#mouseWheel(int)
+     */
+    void mouseWheel(int wheelAmt);
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeWindow.java b/awt/org/apache/harmony/awt/wtk/NativeWindow.java
new file mode 100644
index 0000000..73fd6c0
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeWindow.java
@@ -0,0 +1,220 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+
+
+/**
+ * Provides cross-platform way to manipulate native window.
+ *
+ * Results of methods are reported through native messages.
+ */
+public interface NativeWindow {
+    /**
+     * Returns system id of the associated window
+     * @return HWND on Windows, xwindow on X
+     */
+    long getId();
+
+    /**
+     * Shows/hides window
+     * @param v - new visibility
+     */
+    void setVisible(boolean v);
+
+    /**
+     * Means only size should be changed
+     */
+    static final int BOUNDS_NOMOVE = 1;
+
+    /**
+     * Means only position should be changed
+     */
+    static final int BOUNDS_NOSIZE = 2;
+
+    /**
+     * Tries to set desired window bounds. It's not gurantied the
+     * property will have the desired value. The value change
+     * should be reported by system event (as for other properties).
+     *
+     * <p/>  If child, position is relative to parent window.
+     * @param x - desired x
+     * @param y - desired y
+     * @param w - desired width
+     * @param h - desired height
+     * @param boundsMask - bitwise OR of BOUNDS_* constants.
+     * Governs the new bounds interpretation.
+     */
+    void setBounds(int x, int y, int w, int h, int boundsMask);
+
+    /**
+     * Returns last notified window bounds. This means the last bounds
+     * reported by system event.
+     *
+     * <p/>  If child, position is relative to parent window.
+     * @return last notified window bounds
+     */
+    Rectangle getBounds();
+
+    /**
+     * Returns last notified insets. This means the last insets
+     * reported by system event. Insets are margins around client area
+     * ocupied by system provided decor, ususally border and titlebar.
+     * @return last notified insets
+     */
+    Insets getInsets();
+
+    /**
+     * Enables/disables processing of input (key, mouse) event
+     * by window. If disabled input events are ignored.
+     * @param value - if enabled
+     */
+    void setEnabled(boolean value);
+
+    /**
+     * Sets the "focusable" window state.
+     * @param value - if true makes window focusable
+     */
+    void setFocusable(boolean value);
+
+    /**
+     *
+     * @return current focusable window state
+     */
+    boolean isFocusable();
+
+    /**
+     * Tries to set application input focus to the window or clear
+     * current focus from focused window.
+     *
+     * <p/> For toplevel windows it's not gurantied focus will land in
+     * desired window even if function returns true. Focus traversal should be tracked
+     * by processing system events.
+     *
+     * @param focus  - if true sets focus, else clears focus
+     * @return if success
+     */
+    boolean setFocus(boolean focus);
+
+    /**
+     * Destroys the asscoiated window.
+     * Attempts to use it thereafter can result in
+     * unpredictable bechavior.
+     */
+    void dispose();
+
+    /**
+     * Changes window Z-order to place this window under, If w is null
+     * places places this window on the top. Z-order is per parent.
+     * Toplevels a children of desktop in terms of Z-order.
+     * @param w - window to place under.
+     */
+    void placeAfter(NativeWindow w);
+
+    /**
+     * Places window on top of Z-order
+     */
+    void toFront();
+
+    /**
+     * Places window on bottom of Z-order
+     */
+    void toBack();
+
+    /**
+     * Makes the window resizable/not resizable by user
+     * @param value - if resizable
+     */
+    void setResizable(boolean value);
+
+    /**
+     * Sets the window caption
+     * @param title - caption text
+     */
+    void setTitle(String title);
+
+    /**
+     * Activate the mouse event capturing
+     */
+    void grabMouse();
+
+    /**
+     * Deactivate mouse event capturing
+     */
+    void ungrabMouse();
+
+    /**
+     * Set extended state for top-level window.
+     *
+     * @param state - new state, bitmask of ICONIFIED, MAXIMIZED_BOTH, etc.
+     */
+    void setState(int state);
+
+    /**
+     * Set the image to be displayed in the minimized icon for
+     * top-level [decorated] window.
+     * @param image the icon image to be displayed
+     */
+    void setIconImage(Image image);
+
+    /**
+     * Makes window top-most if value is true,
+     * non-topmost(normal) otherwise.
+     */
+    void setAlwaysOnTop(boolean value);
+
+    /**
+     * Set desired [top-level] window bounds when being in maximized state.
+     * Fields set to Integer.MAX_VALUE are ignored[system-supplied values are
+     * used instead]
+     */
+    void setMaximizedBounds(Rectangle bounds);
+
+    /**
+     * Get absolute position on the screen
+     */
+    Point getScreenPos();
+
+    /**
+     * Set a window "packed" flag:
+     * the flag indicates that if insets change
+     * client area shouldn't be resized, but frame
+     * must be resized instead
+     */
+    void setPacked(boolean packed);
+    
+    /**
+     * Make window an "input method window" by setting
+     * special window style, e. g. small title bar, no
+     * close, minimize/maximize buttons. For internal
+     * use by input method framework.
+     *
+     */
+    void setIMStyle();
+
+    MultiRectArea getObscuredRegion(Rectangle part);
+}
diff --git a/awt/org/apache/harmony/awt/wtk/ShutdownThread.java b/awt/org/apache/harmony/awt/wtk/ShutdownThread.java
new file mode 100644
index 0000000..701eb46
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/ShutdownThread.java
@@ -0,0 +1,83 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public final class ShutdownThread extends Thread {
+    
+    public static final class Watchdog {
+    }
+
+    public ShutdownThread() {
+        setName("AWT-Shutdown"); //$NON-NLS-1$
+        setDaemon(false);
+    }
+    
+    private boolean shouldStop = false;
+
+    @Override
+    public void run() {
+        synchronized (this) {
+            notifyAll(); // synchronize the startup
+
+            while (true) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                }
+
+                if (shouldStop) {
+                    notifyAll(); // synchronize the shutdown
+                    return;
+                }
+            }
+        }
+    }
+
+    @Override
+    public void start() {
+        synchronized (this) {
+            super.start();
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                // awt.26=Shutdown thread was interrupted while starting
+                throw new RuntimeException(
+                        Messages.getString("awt.26")); //$NON-NLS-1$
+            }
+        }
+    }
+
+    public void shutdown() {
+        synchronized (this) {
+            shouldStop = true;
+            notifyAll();
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                // awt.27=Shutdown thread was interrupted while stopping
+                throw new RuntimeException(
+                        Messages.getString("awt.27")); //$NON-NLS-1$
+            }
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java b/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java
new file mode 100644
index 0000000..6efa519
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+/**
+ * Shutdown Watchdog
+ */
+public final class ShutdownWatchdog {
+    
+    private boolean nativeQueueEmpty = true;
+    private boolean awtQueueEmpty = true;
+    private boolean windowListEmpty = true;
+
+    private boolean forcedShutdown = false;
+    
+    private ShutdownThread thread;
+
+    public synchronized void setNativeQueueEmpty(boolean empty) {
+        nativeQueueEmpty = empty;
+        checkShutdown();
+    }
+
+    public synchronized void setAwtQueueEmpty(boolean empty) {
+        awtQueueEmpty = empty;
+        checkShutdown();
+    }
+
+    public synchronized void setWindowListEmpty(boolean empty) {
+        windowListEmpty = empty;
+        checkShutdown();
+    }
+    
+    public synchronized void forceShutdown() {
+        forcedShutdown = true;
+        shutdown();
+    }
+    
+    public synchronized void start() {
+        keepAlive();
+    }
+
+    private void checkShutdown() {
+        if (canShutdown()) {
+            shutdown();
+        } else {
+            keepAlive();
+        }
+    }
+
+    private boolean canShutdown() {
+        return (nativeQueueEmpty && awtQueueEmpty && windowListEmpty) ||
+                forcedShutdown;
+    }
+
+    private void keepAlive() {
+        if (thread == null) {
+            thread = new ShutdownThread();
+            thread.start();
+        }
+    }
+
+    private void shutdown() {
+        if (thread != null) {
+            thread.shutdown();
+            thread = null;
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/Synchronizer.java b/awt/org/apache/harmony/awt/wtk/Synchronizer.java
new file mode 100644
index 0000000..3eeaa0b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/Synchronizer.java
@@ -0,0 +1,200 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.util.Hashtable;
+import java.util.LinkedList;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * Class synchronizer is to protect AWT state integrity in multithreading environment.
+ * It is supposed to have a child class per native platform.
+ * The only instance is created on the first use of one of the core AWT classes.
+ * Registers WTK on the dispatch thread startup.
+ * It is just a special kind of mutex.
+ *
+ */
+
+public class Synchronizer {
+    //TODO: think about java.util.concurrent use for faster blocking/awaking operations
+    //TODO: think about all synchronized methods. Is there need to synchronize everything?
+
+    /**
+     * This field holds the counter of lock operation.
+     * To free synchronizer unlock method must be called $acquestCounter times.
+     * Equals to 0 when synchronizer is free.
+     */
+    protected int acquestCounter;
+
+    /**
+     * This field holds the owner of synchronizer.
+     * Owner of synchronizer is a last thread that successfully locked synchronizer and
+     * still havn't freed it. Equals to null when synchronizer is free.
+     */
+    protected Thread owner;
+
+    /**
+     * This field holds the wait queue.
+     * Wait queue is a queue where thread wait for synchronizer access.
+     * Empty when synchronizer is free.
+     */
+    protected final LinkedList<Thread> waitQueue = new LinkedList<Thread>();
+
+    /**
+     * The event dispatch thread
+     */
+    protected Thread dispatchThread;
+
+    private final Hashtable<Thread, Integer> storedStates = new Hashtable<Thread, Integer>();
+
+    /**
+     * Acquire the lock for this synchronizer. Nested lock is supported.
+     * If the mutex is already locked by another thread, the current thread will be put
+     * into wait queue until the lock becomes available.
+     * All user threads are served in FIFO order. Dispatch thread has higher priority.
+     * Supposed to be used in Toolkit.lockAWT() only.
+     */
+    public void lock() {
+        synchronized (this) {
+            Thread curThread = Thread.currentThread();
+
+            if (acquestCounter == 0) {
+                acquestCounter = 1;
+                owner = curThread;
+            } else {
+                if (owner == curThread) {
+                    acquestCounter++;
+                } else {
+                    if (curThread == dispatchThread) {
+                        waitQueue.addFirst(curThread);
+                    } else {
+                        waitQueue.addLast(curThread);
+                    }
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                        if (owner != curThread) {
+                            waitQueue.remove(curThread);
+                            // awt.1F=Waiting for resource access thread interrupted not from unlock method.
+                            throw new RuntimeException(Messages
+                                    .getString("awt.1F")); //$NON-NLS-1$
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Release the lock for this synchronizer.
+     * If wait queue is not empty the first waiting thread acquires the lock.
+     * Supposed to be used in Toolkit.unlockAWT() only.
+     */
+    public void unlock() {
+        synchronized (this) {
+            if (acquestCounter == 0) {
+                // awt.20=Can't unlock not locked resource.
+                throw new RuntimeException(Messages.getString("awt.20")); //$NON-NLS-1$
+            }
+            if (owner != Thread.currentThread()) {
+                // awt.21=Not owner can't unlock resource.
+                throw new RuntimeException(Messages.getString("awt.21")); //$NON-NLS-1$
+            }
+
+            acquestCounter--;
+            if (acquestCounter == 0) {
+                if (waitQueue.size() > 0) {
+                    acquestCounter = 1;
+                    owner = waitQueue.removeFirst();
+                    owner.interrupt();
+                } else {
+                    owner = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * Stores state of this synchronizer and frees it.
+     * Supposed to be used in Toolkit.unsafeInvokeAndWaitUnderAWTLock() only in pair with
+     * lockAndRestoreState().
+     * Do not call it directly.
+     */
+    public void storeStateAndFree() {
+        synchronized (this) {
+            Thread curThread = Thread.currentThread();
+
+            if (owner != curThread) {
+                // awt.22=Not owner can't free resource.
+                throw new RuntimeException(Messages.getString("awt.22")); //$NON-NLS-1$
+            }
+            if (storedStates.containsKey(curThread)) {
+                // awt.23=One thread can't store state several times in a row.
+                throw new RuntimeException(Messages.getString("awt.23")); //$NON-NLS-1$
+            }
+
+            storedStates.put(curThread, new Integer(acquestCounter));
+            acquestCounter = 1;
+            unlock();
+        }
+    }
+
+    /**
+     * Locks this synchronizer and restores it's state.
+     * Supposed to be used in Toolkit.unsafeInvokeAndWaitUnderAWTLock() only in pair with
+     * storeStateAndFree().
+     * Do not call it directly.
+     */
+    public void lockAndRestoreState() {
+        synchronized (this) {
+            Thread curThread = Thread.currentThread();
+
+            if (owner == curThread) {
+                // awt.24=Owner can't overwrite resource state. Lock operations may be lost.
+                throw new RuntimeException(
+                        Messages.getString("awt.24")); //$NON-NLS-1$
+            }
+            if (!storedStates.containsKey(curThread)) {
+                // awt.25=No state stored for current thread.
+                throw new RuntimeException(Messages.getString("awt.25")); //$NON-NLS-1$
+            }
+
+            lock();
+            acquestCounter = storedStates.get(curThread).intValue();
+            storedStates.remove(curThread);
+        }
+    }
+
+    /**
+     * Sets references to WTK and event dispatch thread.
+     * Called on toolkit startup.
+     *
+     * @param wtk - reference to WTK instance
+     * @param dispatchThread - reference to event dispatch thread
+     */
+    public void setEnvironment(WTK wtk, Thread dispatchThread) {
+        synchronized (this) {
+            this.dispatchThread = dispatchThread;
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/wtk/SystemProperties.java b/awt/org/apache/harmony/awt/wtk/SystemProperties.java
new file mode 100644
index 0000000..6b59f0e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/SystemProperties.java
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Font;
+import java.awt.font.TextAttribute;
+import java.awt.im.InputMethodHighlight;
+import java.util.Map;
+
+/**
+ * NativeProperties
+ */
+
+public interface SystemProperties {
+
+    /**
+     * Get current value of a system color
+     * @param index - one of java.awt.SystemColor constants
+     * @return ARGB value of requested system color
+     */
+    int getSystemColorARGB(int index);
+
+    /**
+     * Get default font for GUI elements such as menus and buttons
+     * @return the font object
+     */
+    Font getDefaultFont();
+    
+    /**
+     * Fill the given Map with system properties
+     */
+    void init(Map<String, ?> desktopProperties);
+
+    /**
+     * Fills the given map with system-dependent visual text
+     * attributes for the abstract description 
+     * of the given input method highlight
+     * @see java.awt.Toolkit.mapInputMethodHighlight()
+     */
+    void mapInputMethodHighlight(InputMethodHighlight highlight, Map<TextAttribute, ?> map);
+}
diff --git a/awt/org/apache/harmony/awt/wtk/WTK.java b/awt/org/apache/harmony/awt/wtk/WTK.java
new file mode 100644
index 0000000..4162fbd
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/WTK.java
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.GraphicsDevice;
+
+
+public abstract class WTK {
+
+    public abstract GraphicsFactory getGraphicsFactory();
+    public abstract NativeEventQueue getNativeEventQueue();
+    public abstract WindowFactory getWindowFactory();
+
+    /**
+     * Returns platform specific implementation of the interface
+     * org.apache.harmony.awt.wtk.CursorFactory.
+     * @return implementation of CursorFactory
+     */
+    public abstract CursorFactory getCursorFactory();
+
+    /**
+     * Returns platform specific implementation of the interface
+     * org.apache.harmony.awt.wtk.NativeMouseInfo.
+     * @return implementation of NativeMouseInfo
+     */
+    public abstract NativeMouseInfo getNativeMouseInfo();
+
+    public abstract SystemProperties getSystemProperties();
+
+    /**
+     * Returns platform specific implementation of the interface
+     * org.apache.harmony.awt.wtk.NativeRobot.
+     * @return implementation of NativeRobot
+     */
+    public abstract NativeRobot getNativeRobot(GraphicsDevice screen);
+    
+    /**
+     * Returns platform specific implementation of the abstract
+     * class org.apache.harmony.awt.wtk.NativeIM.
+     * @return implementation of NativeIM
+     */
+    public abstract NativeIM getNativeIM();
+}
diff --git a/awt/org/apache/harmony/awt/wtk/WindowFactory.java b/awt/org/apache/harmony/awt/wtk/WindowFactory.java
new file mode 100644
index 0000000..23604da
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/WindowFactory.java
@@ -0,0 +1,85 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Dimension;
+import java.awt.Point;
+
+/**
+ * Provides factory for NativeWindow
+ */
+public interface WindowFactory {
+    /**
+     * Creates and returns NativeWindow with desired
+     * creation params
+     *
+     * @param p - initial window properties
+     * @return created window
+     */
+    NativeWindow createWindow(CreationParams p);
+    /**
+     * Create NativeWindow instance connected to existing native resource
+     * @param nativeWindowId - id of existing window
+     * @return created NativeWindow instance
+     */
+    NativeWindow attachWindow(long nativeWindowId);
+    /**
+     * Returns NativeWindow instance if created by this instance of
+     * WindowFactory, otherwise null
+     *
+     * @param id - HWND on Windows xwindow on X
+     * @return NativeWindow or null if unknown
+     */
+    NativeWindow getWindowById(long id);
+    /**
+     * Returns NativeWindow instance of the top-level window
+     * that contains a specified point and was
+     * created by this instance of WindowFactory
+     * @param p - Point to check
+     * @return NativeWindow or null if the point is
+     * not within a window created by this WindowFactory
+     */
+    NativeWindow getWindowFromPoint(Point p);
+
+    /**
+     * Returns whether native system supports the state for windows.
+     * This method tells whether the UI concept of, say, maximization or iconification is supported.
+     * It will always return false for "compound" states like Frame.ICONIFIED|Frame.MAXIMIZED_VERT.
+     * In other words, the rule of thumb is that only queries with a single frame state
+     * constant as an argument are meaningful.
+     *
+     * @param state - one of named frame state constants.
+     * @return true is this frame state is supported by this Toolkit implementation, false otherwise.
+     */
+    boolean isWindowStateSupported(int state);
+
+    /**
+     * @see org.apache.harmony.awt.ComponentInternals
+     */
+    void setCaretPosition(int x, int y);
+
+    /**
+     * Request size of arbitrary native window
+     * @param id - window ID
+     * @return window size
+     */
+    Dimension getWindowSizeById(long id);
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/beans/internal/nls/Messages.java b/awt/org/apache/harmony/beans/internal/nls/Messages.java
new file mode 100644
index 0000000..727c757
--- /dev/null
+++ b/awt/org/apache/harmony/beans/internal/nls/Messages.java
@@ -0,0 +1,132 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
+ * All changes made to this file manually will be overwritten 
+ * if this tool runs again. Better make changes in the template file.
+ */
+
+package org.apache.harmony.beans.internal.nls;
+
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.apache.harmony.kernel.vm.VM;
+import org.apache.harmony.luni.util.MsgHelp;
+
+/**
+ * This class retrieves strings from a resource bundle and returns them,
+ * formatting them with MessageFormat when required.
+ * <p>
+ * It is used by the system classes to provide national language support, by
+ * looking up messages in the <code>
+ *    org.apache.harmony.beans.internal.nls.messages
+ * </code>
+ * resource bundle. Note that if this file is not available, or an invalid key
+ * is looked up, or resource bundle support is not available, the key itself
+ * will be returned as the associated message. This means that the <em>KEY</em>
+ * should a reasonable human-readable (english) string.
+ * 
+ */
+public class Messages {
+
+    private static final String sResource =
+        "org.apache.harmony.beans.internal.nls.messages"; //$NON-NLS-1$
+
+    /**
+     * Retrieves a message which has no arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg) {
+        return MsgHelp.getString(sResource, msg);
+    }
+
+    /**
+     * Retrieves a message which takes 1 argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            Object the object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg) {
+        return getString(msg, new Object[] { arg });
+    }
+
+    /**
+     * Retrieves a message which takes 1 integer argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            int the integer to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, int arg) {
+        return getString(msg, new Object[] { Integer.toString(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 1 character argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            char the character to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, char arg) {
+        return getString(msg, new Object[] { String.valueOf(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 2 arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg1
+     *            Object an object to insert in the formatted output.
+     * @param arg2
+     *            Object another object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg1, Object arg2) {
+        return getString(msg, new Object[] { arg1, arg2 });
+    }
+
+    /**
+     * Retrieves a message which takes several arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param args
+     *            Object[] the objects to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object[] args) {
+        return MsgHelp.getString(sResource, msg, args);
+    }
+}
diff --git a/awt/org/apache/harmony/beans/internal/nls/messages.properties b/awt/org/apache/harmony/beans/internal/nls/messages.properties
new file mode 100644
index 0000000..72b1c8c
--- /dev/null
+++ b/awt/org/apache/harmony/beans/internal/nls/messages.properties
@@ -0,0 +1,103 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#  
+#      http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+# 
+
+# messages for EN locale
+beans.00=no getter for {0} property
+beans.01=no property for name {0} is found
+beans.02=in DefaultPersistenceDelegate.mutatesTo() {0} : {1}
+beans.03=Target Bean class is null
+beans.04=bad property name
+beans.05=Modifier for setter method should be public.
+beans.06=Number of parameters in setter method is not equal to 1.
+beans.07=Parameter type in setter method does not corresponds to predefined.
+beans.08=Number of parameters in getter method is not equal to 0.
+beans.09=Parameter type in getter method does not corresponds to predefined.
+beans.0A=Modifier for getter method should be public.
+beans.0B=Exception in command execution
+beans.0C=source is null
+beans.0D=Error in expression: {0}
+beans.0E=Changes are null
+beans.0F=The new BeanContext can not be set
+beans.10=no node is found for statement with target = {0}
+beans.11=no getter for property {0} found
+beans.12=cannot access property {0} getter
+beans.13=no setter for property {0} found
+beans.14=Exception while finding property descriptor
+beans.15=The listener is null
+beans.16=The provider is null
+beans.17=The child is null
+beans.18=The requestor is null
+beans.19=The service class is null
+beans.1A=The service selector is null
+beans.1B=The service is null
+beans.1C=The event is null
+beans.1D=bean is null
+beans.1E=Illegal class name: {0}
+beans.1F=Method not found: get{0}
+beans.20=Method not found: set{0}
+beans.21=Modifier for indexed getter method should be public.
+beans.22=Number of parameters in getter method is not equal to 1.
+beans.23=Parameter in indexed getter method is not of integer type.
+beans.24=Parameter type in indexed getter method does not correspond to predefined.
+beans.25=Modifier for indexed setter method should be public.
+beans.26=Number of parameters in indexed setter method is not equal to 2.
+beans.27=First parameter type in indexed setter method should be int.
+beans.28=Second parameter type in indexed setter method does not corresponds to predefined.
+beans.29=Membership listener is null
+beans.2A=Target child can not be null
+beans.2B=Resource name can not be null
+beans.2C=The child can not be null
+beans.2D=Invalid resource
+beans.2E=PropertyVetoException was thrown while removing a child: {0}; Original error message:{1}
+beans.2F=Target child is null
+beans.30=PropertyVetoException was thrown while adding a child: {0}; Original error message:{1}
+beans.31=No valid method {0} for {1} found.
+beans.32=Cannot acquire event type from {0} listener.
+beans.33={0} does not return <void>
+beans.34={0} should have a single input parameter
+beans.35=Single parameter does not match to {0} class
+beans.36=No input params are allowed for getListenerMethod
+beans.37=Return type of getListenerMethod is not an array of listeners
+beans.38=Add and remove methods are not available
+beans.39=Cannot generate event set descriptor for name {0}.
+beans.3A=Event type with name {0} is not found.
+beans.3B=skipping expression {0}...
+beans.3C=Unknown method name for array
+beans.3D=First parameter in array getter(setter) is not of Integer type
+beans.3E=Illegal number of arguments in array getter
+beans.3F=Illegal number of arguments in array setter
+beans.40=No constructor for class {0} found
+beans.41=No method with name {0} is found
+beans.42=target is not generated: classname {0} is not found
+beans.43=Cannot convert {0} to char
+beans.44=for property {0} no getter(setter) is found
+beans.45=method name is not generated: error in getMethodName()
+beans.46=Not a valid child
+beans.47=Unable to instantiate property editor
+beans.48=Property editor is not assignable from the PropertyEditor interface
+beans.49=Child cannot implement both BeanContextChild and BeanContextProxy
+beans.4A=newInstance is null
+beans.4B=type is null
+beans.4C=encoder is null
+beans.4D=Invalid method call
+beans.4E=stopClass is not ancestor of beanClass
+beans.4F=search path is null
+beans.50=not an indexed property
+beans.51=Listener method {0} should have parameter of type {1}
+beans.52=listenerMethodName(s) is null
+beans.53=eventSetName is null
+beans.54=listenerType is null
+beans.55=Method is null
diff --git a/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java b/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java
new file mode 100644
index 0000000..498e1bb
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java
@@ -0,0 +1,124 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
+ * All changes made to this file manually will be overwritten 
+ * if this tool runs again. Better make changes in the template file.
+ */
+
+package org.apache.harmony.x.imageio.internal.nls;
+
+import org.apache.harmony.luni.util.MsgHelp;
+
+/**
+ * This class retrieves strings from a resource bundle and returns them,
+ * formatting them with MessageFormat when required.
+ * <p>
+ * It is used by the system classes to provide national language support, by
+ * looking up messages in the <code>
+ *    org.apache.harmony.x.imageio.internal.nls.messages
+ * </code>
+ * resource bundle. Note that if this file is not available, or an invalid key
+ * is looked up, or resource bundle support is not available, the key itself
+ * will be returned as the associated message. This means that the <em>KEY</em>
+ * should a reasonable human-readable (english) string.
+ * 
+ */
+public class Messages {
+
+    private static final String sResource =
+        "org.apache.harmony.x.imageio.internal.nls.messages"; //$NON-NLS-1$
+
+    /**
+     * Retrieves a message which has no arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg) {
+        return MsgHelp.getString(sResource, msg);
+    }
+
+    /**
+     * Retrieves a message which takes 1 argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            Object the object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg) {
+        return getString(msg, new Object[] { arg });
+    }
+
+    /**
+     * Retrieves a message which takes 1 integer argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            int the integer to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, int arg) {
+        return getString(msg, new Object[] { Integer.toString(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 1 character argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            char the character to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, char arg) {
+        return getString(msg, new Object[] { String.valueOf(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 2 arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg1
+     *            Object an object to insert in the formatted output.
+     * @param arg2
+     *            Object another object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg1, Object arg2) {
+        return getString(msg, new Object[] { arg1, arg2 });
+    }
+
+    /**
+     * Retrieves a message which takes several arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param args
+     *            Object[] the objects to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object[] args) {
+        return MsgHelp.getString(sResource, msg, args);
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties b/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties
new file mode 100644
index 0000000..8a49dd8
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#  
+#      http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+# 
+
+# messages for EN locale
+imageio.1=Wrong bitDepth-numBands composition
\ No newline at end of file
diff --git a/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java b/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java
new file mode 100644
index 0000000..caeefdd
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java
@@ -0,0 +1,94 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package org.apache.harmony.x.imageio.metadata;
+
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.imageio.metadata.IIOMetadataFormat;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+
+public class IIOMetadataUtils {
+    private IIOMetadataUtils() {} 
+
+    public static IIOMetadataFormat instantiateMetadataFormat(
+            String formatName, boolean standardFormatSupported,
+            String nativeMetadataFormatName, String nativeMetadataFormatClassName,
+            String [] extraMetadataFormatNames, String [] extraMetadataFormatClassNames
+    ) {
+        if (formatName == null) {
+            throw new IllegalArgumentException("formatName == null!");
+        }
+        if (formatName.equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
+            if (standardFormatSupported) {
+                return IIOMetadataFormatImpl.getStandardFormatInstance();
+            }
+        }
+
+        String className = null;
+
+        if (formatName.equals(nativeMetadataFormatName)) {
+            className = nativeMetadataFormatClassName;
+        } else if (extraMetadataFormatNames != null) {
+            for (int i = 0; i < extraMetadataFormatNames.length; i++) {
+                if (formatName.equals(extraMetadataFormatNames[i])) {
+                    className = extraMetadataFormatClassNames[i];
+                    break;
+                }
+            }
+        }
+
+        if (className == null) {
+            throw new IllegalArgumentException("Unsupported format name");
+        }
+
+        // Get the context class loader and try to use it first
+        ClassLoader contextClassloader = AccessController.doPrivileged(
+                new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        return Thread.currentThread().getContextClassLoader();
+                    }
+        });
+
+        Class cls;
+
+        try {
+            cls = Class.forName(className, true, contextClassloader);
+        } catch (ClassNotFoundException e) {
+            try {
+                // Use current class loader
+                cls = Class.forName(className);
+            } catch (ClassNotFoundException e1) {
+                throw new IllegalStateException ("Can't obtain format");
+            }
+        }
+
+        try {
+            //???AWT:
+            //Method getInstance = cls.getMethod("getInstance");
+            //return (IIOMetadataFormat) getInstance.invoke(null);
+            return null;
+        } catch (Exception e) {
+            IllegalStateException e1 = new IllegalStateException("Can't obtain format");
+            e1.initCause(e); // Add some details to the message
+            throw e1;
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java
new file mode 100644
index 0000000..051f906
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java
@@ -0,0 +1,115 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem Rafikov
+ * @version $Revision: 1.2 $
+ */
+package org.apache.harmony.x.imageio.plugins.jpeg;
+
+import javax.imageio.stream.ImageInputStream;
+
+import org.apache.harmony.awt.gl.image.DecodingImageSource;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * This allows usage of the java2d jpegdecoder with ImageInputStream in
+ * the JPEGImageReader. Temporary, only to make JPEGImageReader#read(..)
+ * working.
+ *
+ */
+public class IISDecodingImageSource extends DecodingImageSource {
+
+    private final InputStream is;
+
+    public IISDecodingImageSource(ImageInputStream iis) {
+        is = new IISToInputStreamWrapper(iis);
+    }
+
+    @Override
+    protected boolean checkConnection() {
+        return true;
+    }
+
+    @Override
+    protected InputStream getInputStream() {
+        return is;
+    }
+
+    static class IISToInputStreamWrapper extends InputStream {
+
+        private ImageInputStream input;
+
+        public IISToInputStreamWrapper(ImageInputStream input) {
+            this.input=input;
+        }
+
+        @Override
+        public int read() throws IOException {
+            return input.read();
+        }
+
+        @Override
+        public int read(byte[] b) throws IOException {
+            return input.read(b);
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            return input.read(b, off, len);
+        }
+
+        @Override
+        public long skip(long n) throws IOException {
+            return input.skipBytes(n);
+        }
+
+        @Override
+        public boolean markSupported() {
+        	return true;  // This is orig
+        	
+            // ???AWT: FIXME
+        	// This is an error in Harmony. Not all input streams
+        	// have mark support and it is not ok to just return true. 
+        	// There should be an input.markSupported(). However, if 
+        	// this call returns false, nothing works anymore.
+        	
+        	// The backside is that BitmapFactory uses a call to markSupport()
+        	// to find out if it needs to warp the stream in a
+        	// BufferedInputStream to get mark support, and this fails!
+        	
+        	// Currently, the hack is in BitmapFactory, where we always
+        	// wrap the stream in a BufferedInputStream.
+        }
+
+        @Override
+        public void mark(int readlimit) {
+            input.mark();
+        }
+
+        @Override
+        public void reset() throws IOException {
+            input.reset();
+        }
+
+        @Override
+        public void close() throws IOException {
+            input.close();
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java
new file mode 100644
index 0000000..067a825
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package org.apache.harmony.x.imageio.plugins.jpeg;
+
+public class JPEGConsts {
+
+    private JPEGConsts() {}
+
+    public static final int SOI = 0xD8;
+
+    //-- IJG (Independed JPEG Group) color spaces
+    public static final int JCS_UNKNOW = 0;
+    public static final int JCS_GRAYSCALE = 1;
+    public static final int JCS_RGB = 2;
+    public static final int JCS_YCbCr = 3;
+    public static final int JCS_CMYK = 4;
+    public static final int JCS_YCC = 5;
+    public static final int JCS_RGBA = 6;
+    public static final int JCS_YCbCrA = 7;
+    public static final int JCS_YCCA = 10;
+    public static final int JCS_YCCK = 11;
+
+    public static int[][] BAND_OFFSETS = {{}, {0}, {0, 1}, {0, 1, 2}, {0, 1, 2, 3}};
+
+    public static final float DEFAULT_JPEG_COMPRESSION_QUALITY = 0.75f;
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java
new file mode 100644
index 0000000..110ed23
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java
@@ -0,0 +1,126 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.4 $
+ */
+package org.apache.harmony.x.imageio.plugins.jpeg;
+
+
+import javax.imageio.ImageReader;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.plugins.jpeg.JPEGImageReadParam;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageReaderSpi;
+
+import org.apache.harmony.awt.gl.image.DecodingImageSource;
+import org.apache.harmony.awt.gl.image.OffscreenImage;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+
+/**
+ * This implementation uses org.apache.harmony.awt.gl.image.JpegDecoder to read
+ * an image. The only implemented method is read(..);
+ *
+ * TODO: Implements generic decoder to be used by javad2 and imageio
+ *
+ * @see org.apache.harmony.awt.gl.image.JpegDecoder
+ * @see org.apache.harmony.x.imageio.plugins.jpeg.IISDecodingImageSource
+ */
+public class JPEGImageReader extends ImageReader {
+
+    ImageInputStream iis;
+
+    public JPEGImageReader(ImageReaderSpi imageReaderSpi) {
+        super(imageReaderSpi);
+    }
+
+    @Override
+    public int getHeight(int i) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public int getWidth(int i) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public int getNumImages(boolean b) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public Iterator<ImageTypeSpecifier> getImageTypes(int i) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public IIOMetadata getStreamMetadata() throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public IIOMetadata getImageMetadata(int i) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public BufferedImage read(int i, ImageReadParam imageReadParam) throws IOException {
+        if (iis == null) {
+            throw new IllegalArgumentException("input stream == null");
+        }
+
+        DecodingImageSource source = new IISDecodingImageSource(iis);
+        OffscreenImage image = new OffscreenImage(source);
+        source.addConsumer(image);
+        source.load();
+        // The interrupted flag should be cleared because ImageDecoder interrupts
+        // current thread while decoding. The same technique is used in
+        // ImageLoader#run(). Another solution can be to create
+        // a separate decoding thread. However, decoder keeps its own pool
+        // of threads so creating a new thread will be just a waste of resources.
+        Thread.interrupted();
+        return image.getBufferedImage();
+    }
+
+    @Override
+    public BufferedImage read(int i) throws IOException {
+        return read(i, null);
+    }
+
+    @Override
+    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
+        super.setInput(input, seekForwardOnly, ignoreMetadata);
+        iis = (ImageInputStream) input;
+    }
+
+    @Override
+    public ImageReadParam getDefaultReadParam() {
+        return new JPEGImageReadParam();
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java
new file mode 100644
index 0000000..c719ce7
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package org.apache.harmony.x.imageio.plugins.jpeg;
+
+import java.io.IOException;
+import java.util.Locale;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ServiceRegistry;
+import javax.imageio.stream.ImageInputStream;
+
+public class JPEGImageReaderSpi extends ImageReaderSpi {
+
+    public JPEGImageReaderSpi() {
+        super(JPEGSpiConsts.vendorName, JPEGSpiConsts.version,
+                JPEGSpiConsts.names, JPEGSpiConsts.suffixes,
+                JPEGSpiConsts.MIMETypes, JPEGSpiConsts.readerClassName,
+                STANDARD_INPUT_TYPE, JPEGSpiConsts.writerSpiNames,
+                JPEGSpiConsts.supportsStandardStreamMetadataFormat,
+                JPEGSpiConsts.nativeStreamMetadataFormatName,
+                JPEGSpiConsts.nativeStreamMetadataFormatClassName,
+                JPEGSpiConsts.extraStreamMetadataFormatNames,
+                JPEGSpiConsts.extraStreamMetadataFormatClassNames,
+                JPEGSpiConsts.supportsStandardImageMetadataFormat,
+                JPEGSpiConsts.nativeImageMetadataFormatName,
+                JPEGSpiConsts.nativeImageMetadataFormatClassName,
+                JPEGSpiConsts.extraImageMetadataFormatNames,
+                JPEGSpiConsts.extraImageMetadataFormatClassNames);
+    }
+
+
+    @Override
+    public boolean canDecodeInput(Object source) throws IOException {
+        ImageInputStream markable = (ImageInputStream) source;
+        try {
+            markable.mark();
+
+            byte[] signature = new byte[3];
+            markable.seek(0);
+            markable.read(signature, 0, 3);
+            markable.reset();
+
+            if ((signature[0] & 0xFF) == 0xFF &&
+                    (signature[1] & 0xFF) == JPEGConsts.SOI &&
+                    (signature[2] & 0xFF) == 0xFF) { // JPEG
+                return true;
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    @Override
+    public ImageReader createReaderInstance(Object extension) throws IOException {
+        return new JPEGImageReader(this);
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "DRL JPEG decoder";
+    }
+
+    @Override
+    public void onRegistration(ServiceRegistry registry, Class<?> category) {
+        // super.onRegistration(registry, category);
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java
new file mode 100644
index 0000000..ae3e876
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java
@@ -0,0 +1,402 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package org.apache.harmony.x.imageio.plugins.jpeg;
+
+import com.android.internal.awt.ImageOutputStreamWrapper;
+
+import javax.imageio.ImageWriter;
+import javax.imageio.IIOImage;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.metadata.IIOMetadata;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap.CompressFormat;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.awt.image.*;
+import java.awt.*;
+import java.awt.color.ColorSpace;
+
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+public class JPEGImageWriter extends ImageWriter {
+
+    // /* ???AWT: Debugging
+    private static final boolean DEBUG = false;
+    private static Bitmap bm;
+    public static Bitmap getBitmap() {
+        return bm;
+    }
+    private static BufferedImage bufImg;
+    public static BufferedImage getBufImage() {
+        return bufImg;
+    }
+    static private RenderedImage renImg;
+    static public RenderedImage getRenImage() {
+        return renImg;
+    }
+    // */
+    
+    private long cinfo;
+    private RenderedImage image;
+    private Raster sourceRaster;
+    private WritableRaster scanRaster;
+    private int srcXOff = 0;
+    private int srcYOff = 0;
+    private int srcWidth;
+    private int srcHeight;
+
+    //-- y step for image subsampling
+    private int deltaY = 1;
+    //-- x step for image subsampling
+    private int deltaX = 1;
+
+    private ImageOutputStream ios;
+
+    public JPEGImageWriter(ImageWriterSpi imageWriterSpi) {
+        super(imageWriterSpi);
+        //???AWT: cinfo = initCompressionObj();
+        cinfo = System.currentTimeMillis();
+    }
+
+    static {
+        //???AWT
+        /*
+        System.loadLibrary("jpegencoder");
+        initWriterIds(ImageOutputStream.class);
+        */
+    }
+
+    @Override
+    public void write(IIOMetadata iioMetadata, IIOImage iioImage, ImageWriteParam param)
+            throws IOException {
+
+        if (ios == null) {
+            throw new IllegalArgumentException("ios == null");
+        }
+        if (iioImage == null) {
+            throw new IllegalArgumentException("Image equals null");
+        }
+
+        RenderedImage img = null;
+        if (!iioImage.hasRaster()) {
+            img = iioImage.getRenderedImage();
+            if (img instanceof BufferedImage) {
+                sourceRaster = ((BufferedImage) img).getRaster();
+            } else {
+                sourceRaster = img.getData();
+            }
+        } else {
+            sourceRaster = iioImage.getRaster();
+        }
+        
+        // AWT???: Debugging
+        if (DEBUG) {
+            if( img==null ) {
+                System.out.println("****J: Image is NULL");
+            } else {
+                renImg = img;
+                bufImg = (BufferedImage)img;
+            }
+        }
+
+        int numBands = sourceRaster.getNumBands();
+        int sourceIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getSourceCSType(img);
+
+        srcWidth = sourceRaster.getWidth();
+        srcHeight = sourceRaster.getHeight();
+
+        int destWidth = srcWidth;
+        int destHeight = srcHeight;
+
+        boolean progressive = false;
+         
+        if (param != null) {
+            Rectangle reg = param.getSourceRegion();
+            if (reg != null) {
+                srcXOff = reg.x;
+                srcYOff = reg.y;
+
+                srcWidth = reg.width + srcXOff > srcWidth
+                        ? srcWidth - srcXOff
+                        : reg.width;
+                srcHeight = reg.height + srcYOff > srcHeight
+                        ? srcHeight - srcYOff
+                        : reg.height;
+            }
+
+            //-- TODO uncomment when JPEGImageWriteParam be implemented
+            //-- Only default progressive mode yet
+            // progressive = param.getProgressiveMode() ==  ImageWriteParam.MODE_DEFAULT;
+
+            //-- def is 1
+            deltaX = param.getSourceXSubsampling();
+            deltaY = param.getSourceYSubsampling();
+
+            //-- def is 0
+            int offsetX = param.getSubsamplingXOffset();
+            int offsetY = param.getSubsamplingYOffset();
+
+            srcXOff += offsetX;
+            srcYOff += offsetY;
+            srcWidth -= offsetX;
+            srcHeight -= offsetY;
+
+            destWidth = (srcWidth + deltaX - 1) / deltaX;
+            destHeight = (srcHeight + deltaY - 1) / deltaY;
+        }
+
+        //-- default DQTs (see JPEGQTable java doc and JPEG spec K1 & K2 tables)
+        //-- at http://www.w3.org/Graphics/JPEG/itu-t81.pdf
+        //-- Only figuring out how to set DQT in IJG library for future metadata
+        //-- support. IJG def tables are the same.
+        //JPEGQTable[] dqt = new JPEGQTable[2];
+//        int[][] dqt = null;
+//        int[][] dqt = new int[2][];
+//        dqt[0] = JPEGQTable.K1Div2Luminance.getTable();
+//        dqt[1] = JPEGQTable.K2Div2Chrominance.getTable();
+        
+        //???AWT: I think we don't need this amymore
+        /*
+        //-- using default color space
+        //-- TODO: Take destination cs from param or use default if there is no cs
+        int destIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getDestinationCSType(img);
+
+        DataBufferByte dbuffer = new DataBufferByte(numBands * srcWidth);
+
+        scanRaster = Raster.createInterleavedRaster(dbuffer, srcWidth, 1,
+                numBands * srcWidth, numBands, JPEGConsts.BAND_OFFSETS[numBands], null);
+
+        encode(dbuffer.getData(), srcWidth, destWidth, destHeight, deltaX,
+                sourceIJGCs, destIJGCs, numBands, progressive,
+                null, cinfo);
+        */
+        
+        SampleModel model = sourceRaster.getSampleModel();
+        
+        if (model instanceof SinglePixelPackedSampleModel) {
+            DataBufferInt ibuf = (DataBufferInt)sourceRaster.getDataBuffer();
+            int[] pixels = ibuf.getData();
+            
+            // Create a bitmap with the pixel
+            bm = Bitmap.createBitmap(pixels, srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
+            
+            // Use Bitmap.compress() to write the image
+            ImageOutputStreamWrapper iosw = new ImageOutputStreamWrapper(ios);
+            bm.compress(CompressFormat.JPEG, 100, iosw);
+        } else {
+            // ???AWT: Add support for other color models
+            throw new RuntimeException("Color model not supported yet");
+        }
+
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+        if (cinfo != 0) {
+            //???AWT: dispose(cinfo);
+            cinfo = 0;
+            ios = null;
+        }
+    }
+
+
+    public IIOMetadata getDefaultStreamMetadata(ImageWriteParam imageWriteParam) {
+        throw new UnsupportedOperationException("not supported yet");
+    }
+
+    public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam) {
+        throw new UnsupportedOperationException("not supported yet");
+    }
+
+    @Override
+    public IIOMetadata convertStreamMetadata(IIOMetadata iioMetadata, ImageWriteParam imageWriteParam) {
+        throw new UnsupportedOperationException("not supported yet");
+    }
+
+    @Override
+    public IIOMetadata convertImageMetadata(IIOMetadata iioMetadata, ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam) {
+        throw new UnsupportedOperationException("not supported yet");
+    }
+
+    @Override
+    public void setOutput(Object output) {
+        super.setOutput(output);
+        ios = (ImageOutputStream) output;
+        //???AWT: setIOS(ios, cinfo);
+        sourceRaster = null;
+        scanRaster = null;
+        srcXOff = 0;
+        srcYOff = 0;
+        srcWidth = 0;
+        srcHeight = 0;
+        deltaY = 1;
+    }
+
+    /**
+     * Frees resources
+     * @param structPointer
+     */
+    //???AWT: private native void dispose(long structPointer);
+
+    /**
+     * Inits methods Ids for native to java callbacks
+     * @param iosClass
+     */
+    //???AWT: private native static void initWriterIds(Class<ImageOutputStream> iosClass);
+
+    /**
+     * Inits compression objects
+     * @return pointer to the native structure
+     */
+    //???AWT: private native long initCompressionObj();
+
+    /**
+     * Sets image output stream in IJG layer
+     * @param stream
+     */
+    //???AWT: private native void setIOS(ImageOutputStream stream, long structPointer);
+
+    /**
+     * Runs encoding process.
+     *
+     * @param data image data buffer to encode
+     * @param srcWidth - source width
+     * @param width - destination width
+     * @param height destination height
+     * @param deltaX - x subsampling step
+     * @param inColorSpace - original color space
+     * @param outColorSpace - destination color space
+     * @param numBands - number of bands
+     * @param cinfo - native handler
+     * @return
+     */
+    //???AWT:
+    /*
+    private native boolean encode(byte[] data, int srcWidth,
+                                  int width, int height, int deltaX,
+                                  int inColorSpace, int outColorSpace,
+                                  int numBands, boolean progressive,
+                                  int[][] dqt,
+                                  long cinfo);
+    */
+
+    /**
+     * Callback for getting a next scanline
+     * @param scanline scan line number
+     */
+    @SuppressWarnings("unused")
+    private void getScanLine(int scanline) {
+        //-- TODO: processImageProgress in ImageWriter
+        Raster child = sourceRaster.createChild(srcXOff,
+                srcYOff + scanline * deltaY, srcWidth, 1, 0, 0, null);
+
+        scanRaster.setRect(child);
+    }
+
+    /**
+     * Maps color space types to IJG color spaces
+     * @param image
+     * @return
+     */
+    private int getSourceCSType(RenderedImage image) {
+        int type = JPEGConsts.JCS_UNKNOW;
+        ColorModel cm = image.getColorModel();
+
+        if (null == cm) {
+            return type;
+        }
+
+        if (cm instanceof IndexColorModel) {
+            throw new UnsupportedOperationException("IndexColorModel is not supported yet");
+        }
+
+        boolean hasAlpha = cm.hasAlpha();
+        ColorSpace cs = cm.getColorSpace();
+        switch(cs.getType()) {
+            case ColorSpace.TYPE_GRAY:
+                type = JPEGConsts.JCS_GRAYSCALE;
+                break;
+           case ColorSpace.TYPE_RGB:
+                type = hasAlpha ? JPEGConsts.JCS_RGBA : JPEGConsts.JCS_RGB;
+                break;
+           case ColorSpace.TYPE_YCbCr:
+                type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
+                break;
+           case ColorSpace.TYPE_3CLR:
+                 type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC;
+                 break;
+           case ColorSpace.TYPE_CMYK:
+                  type = JPEGConsts.JCS_CMYK;
+                  break;
+        }
+        return type;
+    }
+
+    /**
+     * Returns destination color space.
+     * (YCbCr[A] for RGB)
+     *
+     * @param image
+     * @return
+     */
+    private int getDestinationCSType(RenderedImage image) {
+        int type = JPEGConsts.JCS_UNKNOW;
+        ColorModel cm = image.getColorModel();
+        if (null != cm) {
+            boolean hasAlpha = cm.hasAlpha();
+            ColorSpace cs = cm.getColorSpace();
+
+            switch(cs.getType()) {
+                case ColorSpace.TYPE_GRAY:
+                    type = JPEGConsts.JCS_GRAYSCALE;
+                    break;
+               case ColorSpace.TYPE_RGB:
+                    type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
+                    break;
+               case ColorSpace.TYPE_YCbCr:
+                    type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
+                    break;
+               case ColorSpace.TYPE_3CLR:
+                     type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC;
+                     break;
+               case ColorSpace.TYPE_CMYK:
+                      type = JPEGConsts.JCS_CMYK;
+                      break;
+            }
+        }
+        return type;
+    }
+
+    public ImageWriteParam getDefaultWriteParam() {
+        return new JPEGImageWriteParam(getLocale());
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java
new file mode 100644
index 0000000..b7990e0
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package org.apache.harmony.x.imageio.plugins.jpeg;
+
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.ImageWriter;
+import javax.imageio.ImageTypeSpecifier;
+import java.io.IOException;
+import java.util.Locale;
+
+public class JPEGImageWriterSpi extends ImageWriterSpi {
+
+    public JPEGImageWriterSpi() {
+        super(JPEGSpiConsts.vendorName, JPEGSpiConsts.version,
+                JPEGSpiConsts.names, JPEGSpiConsts.suffixes, JPEGSpiConsts.MIMETypes,
+                JPEGSpiConsts.writerClassName, STANDARD_OUTPUT_TYPE,
+                JPEGSpiConsts.readerSpiNames, JPEGSpiConsts.supportsStandardStreamMetadataFormat /*TODO: support st. metadata format*/,
+                JPEGSpiConsts.nativeStreamMetadataFormatName, JPEGSpiConsts.nativeStreamMetadataFormatClassName,
+                JPEGSpiConsts.extraStreamMetadataFormatNames, JPEGSpiConsts.extraStreamMetadataFormatClassNames,
+                JPEGSpiConsts.supportsStandardImageMetadataFormat, JPEGSpiConsts.nativeImageMetadataFormatName, JPEGSpiConsts.nativeImageMetadataFormatClassName,
+                JPEGSpiConsts.extraImageMetadataFormatNames, JPEGSpiConsts.extraImageMetadataFormatClassNames);
+    }
+
+    @Override
+    public boolean canEncodeImage(ImageTypeSpecifier imageTypeSpecifier) {
+        return true;
+    }
+
+    @Override
+    public ImageWriter createWriterInstance(Object o) throws IOException {
+        return new JPEGImageWriter(this);
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "DRL JPEG Encoder";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java
new file mode 100644
index 0000000..c3b4a50
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java
@@ -0,0 +1,57 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package org.apache.harmony.x.imageio.plugins.jpeg;
+
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+public class JPEGSpiConsts {
+    private JPEGSpiConsts() {}
+
+    public static final String vendorName = "Intel Corporation";
+    public static final String version = "0.1 beta";
+
+    static final String readerClassName = "org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReader";
+    static final String writerClassName = "org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriter";
+
+    static final String[] names = {"jpeg", "jpg", "JPEG", "JPG"};
+    static final String[] suffixes = {"jpeg", "jpg"};
+    static final String[] MIMETypes = {"image/jpeg"};
+
+    static final String[] writerSpiNames = {"org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriterSpi"};
+    static final String[] readerSpiNames = {"org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReaderSpi"};
+
+    //-- TODO fill this stuff with correct data
+    static final boolean supportsStandardStreamMetadataFormat = false;
+    static final String nativeStreamMetadataFormatName = null;
+    static final String nativeStreamMetadataFormatClassName = null;
+    static final String[] extraStreamMetadataFormatNames = null;
+    static final String[] extraStreamMetadataFormatClassNames = null;
+    static final boolean supportsStandardImageMetadataFormat = false;
+    static final String nativeImageMetadataFormatName =
+            "org.apache.harmony.x.imageio.plugins.jpeg.MyFormatMetadata_1.0";
+    static final String nativeImageMetadataFormatClassName =
+            "org.apache.harmony.x.imageio.plugins.jpeg.MyFormatMetadata";
+    static final String[] extraImageMetadataFormatNames = null;
+    static final String[] extraImageMetadataFormatClassNames = null;
+
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java
new file mode 100644
index 0000000..480041c
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java
@@ -0,0 +1,106 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package org.apache.harmony.x.imageio.plugins.png;
+
+import org.apache.harmony.awt.gl.image.DecodingImageSource;
+import org.apache.harmony.awt.gl.image.OffscreenImage;
+import org.apache.harmony.x.imageio.plugins.jpeg.IISDecodingImageSource;
+
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageReadParam;
+import javax.imageio.plugins.jpeg.JPEGImageReadParam;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.metadata.IIOMetadata;
+import java.io.IOException;
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+
+public class PNGImageReader  extends ImageReader {
+    ImageInputStream iis;
+
+    public PNGImageReader(ImageReaderSpi imageReaderSpi) {
+        super(imageReaderSpi);
+    }
+
+    public int getNumImages(boolean allowSearch) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    public int getWidth(int imageIndex) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    public int getHeight(int imageIndex) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public IIOMetadata getStreamMetadata() throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public BufferedImage read(int i, ImageReadParam imageReadParam) throws IOException {
+        if (iis == null) {
+            throw new IllegalArgumentException("input stream == null");
+        }
+
+        DecodingImageSource source = new IISDecodingImageSource(iis);
+        OffscreenImage image = new OffscreenImage(source);
+        source.addConsumer(image);
+        source.load();
+        // The interrupted flag should be cleared because ImageDecoder interrupts
+        // current thread while decoding (due its architecture).
+        Thread.interrupted();
+        return image.getBufferedImage();
+    }
+
+    @Override
+    public BufferedImage read(int i) throws IOException {
+        return read(i, null);
+    }
+
+    @Override
+    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
+        super.setInput(input, seekForwardOnly, ignoreMetadata);
+        iis = (ImageInputStream) input;
+    }
+
+    @Override
+    public ImageReadParam getDefaultReadParam() {
+        return new ImageReadParam();
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java
new file mode 100644
index 0000000..50f8b10
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java
@@ -0,0 +1,88 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package org.apache.harmony.x.imageio.plugins.png;
+
+import org.apache.harmony.x.imageio.plugins.jpeg.JPEGSpiConsts;
+
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ServiceRegistry;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+import java.io.IOException;
+import java.util.Locale;
+
+public class PNGImageReaderSpi extends ImageReaderSpi {
+    static final String PNG_NAMES[] = new String[] {"png", "PNG"};
+    static final String PNG_SUFFIXES[] = new String[] {"png"};
+    static final String PNG_MIME_TYPES[] = new String[] {"image/png"};
+    static final String PNG_READER_CLASS_NAME = "org.apache.harmony.x.imageio.plugins.png.PNGImageReader";
+    static final String PNG_READER_SPI_NAMES[] = {"org.apache.harmony.x.imageio.plugins.png.PNGImageReaderSpi"};
+
+    public PNGImageReaderSpi() {
+        super(
+                JPEGSpiConsts.vendorName, JPEGSpiConsts.version,
+                PNG_NAMES, PNG_SUFFIXES,
+                PNG_MIME_TYPES, PNG_READER_CLASS_NAME,
+                STANDARD_INPUT_TYPE, null,
+                false, null,
+                null, null,
+                null, false, 
+                null, null,
+                null, null
+        );
+    }
+
+    @Override
+    public boolean canDecodeInput(Object source) throws IOException {
+        ImageInputStream markable = (ImageInputStream) source;
+        markable.mark();
+
+        byte[] signature = new byte[8];
+        markable.seek(0);
+
+        int nBytes = markable.read(signature, 0, 8);
+        if(nBytes != 8) markable.read(signature, nBytes, 8-nBytes);
+        markable.reset();
+
+        // PNG signature: 137 80 78 71 13 10 26 10
+        return  (signature[0] & 0xFF) == 137 &&
+                (signature[1] & 0xFF) == 80 &&
+                (signature[2] & 0xFF) == 78 &&
+                (signature[3] & 0xFF) == 71 &&
+                (signature[4] & 0xFF) == 13 &&
+                (signature[5] & 0xFF) == 10 &&
+                (signature[6] & 0xFF) == 26 &&
+                (signature[7] & 0xFF) == 10;
+    }
+
+    @Override
+    public ImageReader createReaderInstance(Object extension) throws IOException {
+        return new PNGImageReader(this);
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "DRL PNG decoder";
+    }
+
+    @Override
+    public void onRegistration(ServiceRegistry registry, Class<?> category) {
+        super.onRegistration(registry, category);
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java
new file mode 100644
index 0000000..e2a8d7d
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java
@@ -0,0 +1,247 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Viskov Nikolay
+ * @version $Revision$
+ */
+package org.apache.harmony.x.imageio.plugins.png;
+
+import com.android.internal.awt.ImageOutputStreamWrapper;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.stream.ImageOutputStream;
+
+import org.apache.harmony.x.imageio.internal.nls.Messages;
+
+import org.apache.harmony.luni.util.NotImplementedException;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+
+public class PNGImageWriter extends ImageWriter {
+    
+    // /* ???AWT: Debugging
+    private static final boolean DEBUG = false;
+    private static Bitmap bm;
+    public static Bitmap getBitmap() {
+        return bm;
+    }
+    // */
+    
+    private static int[][] BAND_OFFSETS = {
+            {}, {
+                0 }, {
+                    0, 1 }, {
+                    0, 1, 2 }, {
+                    0, 1, 2, 3 } };
+
+    // Each pixel is a grayscale sample.
+    private static final int PNG_COLOR_TYPE_GRAY = 0;
+    // Each pixel is an R,G,B triple.
+    private static final int PNG_COLOR_TYPE_RGB = 2;
+    // Each pixel is a palette index, a PLTE chunk must appear.
+    private static final int PNG_COLOR_TYPE_PLTE = 3;
+    // Each pixel is a grayscale sample, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
+    // Each pixel is an R,G,B triple, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_RGBA = 6;
+    
+    //???AWT: private static native void initIDs(Class<ImageOutputStream> iosClass);
+
+    static {
+        //???AWT
+        /*
+        System.loadLibrary("pngencoder"); //$NON-NLS-1$
+        initIDs(ImageOutputStream.class);
+        */
+    }
+    
+    /*
+    private native int encode(byte[] input, int bytesInBuffer, int bytePixelSize, Object ios, int imageWidth,
+            int imageHeight, int bitDepth, int colorType, int[] palette, int i, boolean b);
+    */
+    
+    protected PNGImageWriter(ImageWriterSpi iwSpi) {
+        super(iwSpi);
+    }
+
+    @Override
+    public IIOMetadata convertStreamMetadata(IIOMetadata arg0, ImageWriteParam arg1) {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public IIOMetadata convertImageMetadata(IIOMetadata arg0, ImageTypeSpecifier arg1, ImageWriteParam arg2) {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier arg0, ImageWriteParam arg1) {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public IIOMetadata getDefaultStreamMetadata(ImageWriteParam arg0) {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public void write(IIOMetadata streamMetadata, IIOImage iioImage, ImageWriteParam param) throws IOException {
+        if (output == null) {
+            throw new IllegalStateException("Output not been set");
+        }
+        if (iioImage == null) {
+            throw new IllegalArgumentException("Image equals null");
+        }
+        // AWT???: I think this is not needed anymore
+        // if (iioImage.hasRaster() && !canWriteRasters()) {
+        //    throw new UnsupportedOperationException("Can't write raster");
+        //}// ImageOutputStreamImpl
+        
+        Raster sourceRaster;
+        RenderedImage img = null;
+        if (!iioImage.hasRaster()) {
+            img = iioImage.getRenderedImage();
+            if (img instanceof BufferedImage) {
+                sourceRaster = ((BufferedImage) img).getRaster();
+            } else {
+                sourceRaster = img.getData();
+            }
+        } else {
+            sourceRaster = iioImage.getRaster();
+        }
+
+        SampleModel model = sourceRaster.getSampleModel();
+        int srcWidth = sourceRaster.getWidth();
+        int srcHeight = sourceRaster.getHeight();
+        int numBands = model.getNumBands();
+        
+        ColorModel colorModel = img.getColorModel();
+        int pixelSize = colorModel.getPixelSize();
+        int bytePixelSize = pixelSize / 8;
+        int bitDepth = pixelSize / numBands;
+        
+        // byte per band
+        int bpb = bitDepth > 8 ? 2 : 1;
+        
+        boolean isInterlace = true;
+        if (param instanceof PNGImageWriterParam) {
+            isInterlace = ((PNGImageWriterParam) param).getInterlace();
+        }
+        
+        int colorType = PNG_COLOR_TYPE_GRAY;
+        int[] palette = null;
+        
+        if (colorModel instanceof IndexColorModel) {
+            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
+            }
+            if (numBands != 1) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
+            }
+
+            IndexColorModel icm = (IndexColorModel) colorModel;
+            palette = new int[icm.getMapSize()];
+            icm.getRGBs(palette);
+            colorType = PNG_COLOR_TYPE_PLTE;
+        }
+        else if (numBands == 1) {
+            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
+            }
+            colorType = PNG_COLOR_TYPE_GRAY;
+        }
+        else if (numBands == 2) {
+            if (bitDepth != 8 && bitDepth != 16) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
+            }
+            colorType = PNG_COLOR_TYPE_GRAY_ALPHA;
+        }
+        else if (numBands == 3) {
+            if (bitDepth != 8 && bitDepth != 16) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1")); //$NON-NLS-1$
+            }
+            colorType = PNG_COLOR_TYPE_RGB;
+        }
+        else if (numBands == 4) {
+            if (bitDepth != 8 && bitDepth != 16) {
+                //Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1")); //$NON-NLS-1$
+            }
+            colorType = PNG_COLOR_TYPE_RGBA;
+        }
+        
+        /* ???AWT: I think this is not needed anymore
+        int dbufferLenght = bytePixelSize * imageHeight * imageWidth;
+        DataBufferByte dbuffer = new DataBufferByte(dbufferLenght);
+
+        WritableRaster scanRaster = Raster.createInterleavedRaster(dbuffer, imageWidth, imageHeight, bpb * numBands
+                * imageWidth, bpb * numBands, BAND_OFFSETS[numBands], null);
+
+        scanRaster.setRect(((BufferedImage) image).getRaster()// image.getData()
+                .createChild(0, 0, imageWidth, imageHeight, 0, 0, null));
+        */
+
+        if (DEBUG) {
+            System.out.println("**** raster:" + sourceRaster);        
+            System.out.println("**** model:" + model);
+            System.out.println("**** type:" + colorType);
+        }
+        
+        if (model instanceof SinglePixelPackedSampleModel) {
+            DataBufferInt ibuf = (DataBufferInt)sourceRaster.getDataBuffer();
+            int[] pixels = ibuf.getData();
+            
+            // Create a bitmap with the pixel
+            bm = Bitmap.createBitmap(pixels, srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
+            
+            // Use Bitmap.compress() to write the image
+            ImageOutputStream ios = (ImageOutputStream) getOutput();
+            ImageOutputStreamWrapper iosw = new ImageOutputStreamWrapper(ios);
+            bm.compress(CompressFormat.PNG, 100, iosw);
+        } else {
+            // ???AWT: Add support for other color models
+            throw new RuntimeException("Color model not supported yet");
+        }
+    }
+
+    public ImageWriteParam getDefaultWriteParam() {
+        return new PNGImageWriterParam();
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java
new file mode 100644
index 0000000..bf3a000
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Viskov Nikolay
+ * @version $Revision$
+ */
+package org.apache.harmony.x.imageio.plugins.png;
+
+import javax.imageio.ImageWriteParam;
+
+public class PNGImageWriterParam extends ImageWriteParam {
+
+    private boolean isInterlace = true;
+
+    public PNGImageWriterParam() {
+        super();
+    }
+
+    public boolean getInterlace() {
+        return isInterlace;
+    }
+
+    public void setInterlace(boolean b) {
+        isInterlace = b;
+    }
+
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java
new file mode 100644
index 0000000..6eed14d
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java
@@ -0,0 +1,113 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Viskov Nikolay
+ * @version $Revision$
+ */
+package org.apache.harmony.x.imageio.plugins.png;
+
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferByte;
+import java.awt.image.IndexColorModel;
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+import javax.imageio.spi.ImageWriterSpi;
+
+public class PNGImageWriterSpi extends ImageWriterSpi {
+
+    public PNGImageWriterSpi() {
+        super("Intel Corporation",// vendorName
+                "1.0",// version
+                new String[] {
+                        "png", "PNG" },// names
+                new String[] {
+                        "png", "PNG" },// suffixes
+                new String[] {
+                    "image/png" },// MIMETypes
+                "org.apache.harmony.x.imageio.plugins.png.PNGImageWriter",// writerClassName
+                STANDARD_OUTPUT_TYPE,// outputTypes
+                new String[] {
+                    "org.apache.harmony.x.imageio.plugins.png.PNGImageWriterSpi" },// readerSpiNames
+                false,// supportsStandardStreamMetadataFormat
+                null,// nativeStreamMetadataFormatName
+                null,// nativeStreamMetadataFormatClassName
+                null,// extraStreamMetadataFormatNames
+                null,// extraStreamMetadataFormatClassNames
+                false,// supportsStandardImageMetadataFormat
+                null,// nativeImageMetadataFormatName
+                null,// nativeImageMetadataFormatClassName
+                null,// extraImageMetadataFormatNames
+                null// extraImageMetadataFormatClassNames
+        );
+    }
+
+    @Override
+    public boolean canEncodeImage(ImageTypeSpecifier type) {
+        boolean canEncode = true;
+
+        int numBands = type.getSampleModel().getNumBands();
+
+        ColorModel colorModel = type.getColorModel();
+
+        int bitDepth = colorModel.getPixelSize() / numBands;
+
+        if (colorModel instanceof IndexColorModel) {
+            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) {
+                canEncode = false;
+            }
+            if (numBands != 1) {
+                canEncode = false;
+            }
+        }
+        else if (numBands == 1) {
+            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) {
+                canEncode = false;
+            }
+        }
+        else if (numBands == 2) {
+            if (bitDepth != 8 && bitDepth != 16) {
+                canEncode = false;
+            }
+        }
+        else if (numBands == 3) {
+            if (bitDepth != 8 && bitDepth != 16) {
+                canEncode = false;
+            }
+        }
+        else if (numBands == 4) {
+            if (bitDepth != 8 && bitDepth != 16) {
+                canEncode = false;
+            }
+        }
+
+        return canEncode;
+    }
+
+    @Override
+    public ImageWriter createWriterInstance(Object arg0) throws IOException {
+        return new PNGImageWriter(this);
+    }
+
+    @Override
+    public String getDescription(Locale arg0) {
+        return "DRL PNG encoder";
+    }
+
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java
new file mode 100644
index 0000000..d4fdd76
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageInputStreamSpi;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.FileImageOutputStream;
+import javax.imageio.stream.FileImageInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.Locale;
+
+public class FileIISSpi extends ImageInputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public FileIISSpi() {
+        super(vendor, ver, File.class);
+    }
+
+    @Override
+    public ImageInputStream createInputStreamInstance(Object input, boolean useCache,
+            File cacheDir) throws IOException {
+        if (File.class.isInstance(input)) {
+            return new FileImageInputStream((File) input);
+        }
+        throw new IllegalArgumentException("input is not an instance of java.io.File");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "File IIS Spi";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java
new file mode 100644
index 0000000..acda6a1
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java
@@ -0,0 +1,52 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageOutputStreamSpi;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.FileImageOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.Locale;
+
+public class FileIOSSpi extends ImageOutputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public FileIOSSpi() {
+        super(vendor, ver, File.class);
+    }
+
+    @Override
+    public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache,
+            File cacheDir) throws IOException {
+        if (output instanceof File) {
+            return new FileImageOutputStream((File) output);
+        }
+        throw new IllegalArgumentException("output is not instance of File");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "File IOS Spi";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java
new file mode 100644
index 0000000..ed2fef0
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageInputStreamSpi;
+import javax.imageio.stream.*;
+import java.io.OutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+
+public class InputStreamIISSpi extends ImageInputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public InputStreamIISSpi() {
+        super(vendor, ver, InputStream.class);
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "Output Stream IOS Spi";
+    }
+
+    @Override
+    public boolean canUseCacheFile() {
+        return true;
+    }
+
+    @Override
+    public ImageInputStream createInputStreamInstance(Object input, boolean useCache, File cacheDir) throws IOException {
+        if (input instanceof InputStream) {
+            if (useCache) {
+                return new FileCacheImageInputStream((InputStream) input, cacheDir);
+            } else {
+                return new MemoryCacheImageInputStream((InputStream) input);
+            }
+        }
+        throw new IllegalArgumentException("Output is not an instance of InputStream");
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java
new file mode 100644
index 0000000..dd1e88d
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java
@@ -0,0 +1,60 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageOutputStreamSpi;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.FileCacheImageOutputStream;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Locale;
+
+public class OutputStreamIOSSpi extends ImageOutputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public OutputStreamIOSSpi() {
+        super(vendor, ver, OutputStream.class);
+    }
+
+    @Override
+    public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache, File cacheDir) throws IOException {
+        if (output instanceof OutputStream) {
+            if (useCache) {
+                return new FileCacheImageOutputStream((OutputStream) output, cacheDir);
+            } else {
+                return new MemoryCacheImageOutputStream((OutputStream) output);
+            }
+        }
+        throw new IllegalArgumentException("Output is not an instance of OutputStream");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "Output Stream IOS Spi";
+    }
+
+    @Override
+    public boolean canUseCacheFile() {
+        return true;
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java
new file mode 100644
index 0000000..f97eb87
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageInputStreamSpi;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.FileImageInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Locale;
+
+public class RAFIISSpi extends ImageInputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public RAFIISSpi() {
+        super(vendor, ver, RandomAccessFile.class);
+    }
+
+    @Override
+    public ImageInputStream createInputStreamInstance(Object input, boolean useCache,
+            File cacheDir) throws IOException {
+        if (RandomAccessFile.class.isInstance(input)) {
+            return new FileImageInputStream((RandomAccessFile) input);
+        }
+        throw new IllegalArgumentException(
+                "input is not an instance of java.io.RandomAccessFile");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "RandomAccessFile IIS Spi";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java
new file mode 100644
index 0000000..a9d3649
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageOutputStreamSpi;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.FileImageOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Locale;
+
+public class RAFIOSSpi extends ImageOutputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public RAFIOSSpi() {
+        super(vendor, ver, RandomAccessFile.class);
+    }
+
+    @Override
+    public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache,
+            File cacheDir) throws IOException {
+        if (output instanceof RandomAccessFile) {
+            return new FileImageOutputStream((RandomAccessFile) output);
+        }
+        throw new IllegalArgumentException("output is not instance of java.io.RandomAccessFile");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "RandomAccessFile IOS Spi";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java b/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java
new file mode 100644
index 0000000..64f7b2a
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java
@@ -0,0 +1,226 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package org.apache.harmony.x.imageio.stream;
+
+import java.util.ArrayList;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public final class RandomAccessMemoryCache {
+    private static final int BLOCK_SHIFT = 9;
+    private static final int BLOCK_SIZE = 1 << BLOCK_SHIFT;
+    private static final int BLOCK_MASK = BLOCK_SIZE - 1;
+    
+    private long length;
+
+    private int firstUndisposed = 0;
+
+    private ArrayList<byte[]> blocks = new ArrayList<byte[]>();
+
+    public RandomAccessMemoryCache() {
+    }
+
+    public long length() {
+        return length;
+    }
+
+    public void close() {
+        blocks.clear();
+        length = 0;
+    }
+
+    private void grow(long pos) {
+        int blocksNeeded = (int)(pos >> BLOCK_SHIFT) - blocks.size() + 1;
+        for (int i=0; i < blocksNeeded; i++) {
+            blocks.add(new byte[BLOCK_SIZE]);
+        }
+
+        length = pos + 1;
+    }
+
+    public void putData(int oneByte, long pos) {
+        if (pos >= length) {
+            grow(pos);
+        }
+
+        byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
+        block[(int)(pos & BLOCK_MASK)] = (byte) oneByte;
+    }
+
+    public void putData(byte[] buffer, int offset, int count, long pos) {
+        if (count > buffer.length - offset || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0){
+            return;
+        }
+
+        long lastPos = pos + count - 1;
+        if (lastPos >= length) {
+            grow(lastPos);
+        }
+
+        while (count > 0) {
+            byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
+            int blockOffset = (int)(pos & BLOCK_MASK);
+            int toCopy = Math.min(BLOCK_SIZE - blockOffset, count);
+            System.arraycopy(buffer, offset, block, blockOffset, toCopy);
+            pos += toCopy;
+            count -= toCopy;
+            offset += toCopy;
+        }
+    }
+
+    public int getData(long pos) {
+        if (pos >= length) {
+            return -1;
+        }
+
+        byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
+        return block[(int)(pos & BLOCK_MASK)] & 0xFF;
+    }
+
+    public int getData(byte[] buffer, int offset, int count, long pos) {
+        if (count > buffer.length - offset || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0) {
+            return 0;
+        }
+        if (pos >= length) {
+            return -1;
+        }
+
+        if (count + pos > length) {
+            count = (int) (length - pos);
+        }
+
+        byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
+        int nbytes = Math.min(count, BLOCK_SIZE - (int)(pos & BLOCK_MASK));
+        System.arraycopy(block, (int)(pos & BLOCK_MASK), buffer, offset, nbytes);
+
+        return nbytes;
+    }
+    /*
+    public void seek(long pos) throws IOException {
+        if (pos < 0) {
+            throw new IOException("seek position is negative");
+        }
+        this.pos = pos; 
+    }
+
+    public void readFully(byte[] buffer) throws IOException {
+        readFully(buffer, 0, buffer.length);
+    }
+
+    public void readFully(byte[] buffer, int offset, int count) throws IOException {
+        if (0 <= offset && offset <= buffer.length && 0 <= count && count <= buffer.length - offset) {
+            while (count > 0) {
+                int result = read(buffer, offset, count);
+                if (result >= 0) {
+                    offset += result;
+                    count -= result;
+                } else {
+                    throw new EOFException();
+                }
+            }
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    public long getFilePointer() {
+        return pos;
+    }
+*/
+
+    public void freeBefore(long pos) {
+        int blockIdx = (int)(pos >> BLOCK_SHIFT);
+        if (blockIdx <= firstUndisposed) { // Nothing to do
+            return;
+        }
+
+        for (int i = firstUndisposed; i < blockIdx; i++) {
+            blocks.set(i, null);
+        }
+
+        firstUndisposed = blockIdx;
+    }
+
+    public int appendData(InputStream is, int count) throws IOException {
+        if (count <= 0) {
+            return 0;
+        }
+
+        long startPos = length;
+        long lastPos = length + count - 1;
+        grow(lastPos); // Changes length
+
+        int blockIdx = (int)(startPos >> BLOCK_SHIFT);
+        int offset = (int) (startPos & BLOCK_MASK);
+
+        int bytesAppended = 0;
+
+        while (count > 0) {
+            byte[] block = blocks.get(blockIdx);
+            int toCopy = Math.min(BLOCK_SIZE - offset, count);
+            count -= toCopy;
+
+            while (toCopy > 0) {
+                int bytesRead = is.read(block, offset, toCopy);
+
+                if (bytesRead < 0) {
+                    length -= (count - bytesAppended);
+                    return bytesAppended;
+                }
+
+                toCopy -= bytesRead;
+                offset += bytesRead;
+            }
+
+            blockIdx++;
+            offset = 0;
+        }
+
+        return count;
+    }
+
+    public void getData(OutputStream os, int count, long pos) throws IOException {
+        if (pos + count > length) {
+            throw new IndexOutOfBoundsException("Argument out of cache");
+        }
+
+        int blockIdx = (int)(pos >> BLOCK_SHIFT);
+        int offset = (int) (pos & BLOCK_MASK);
+        if (blockIdx < firstUndisposed) {
+            throw new IndexOutOfBoundsException("The requested data are already disposed");
+        }
+
+        while (count > 0) {
+            byte[] block = blocks.get(blockIdx);
+            int toWrite = Math.min(BLOCK_SIZE - offset, count);
+            os.write(block, offset, toWrite);
+
+            blockIdx++;
+            offset = 0;
+            count -= toWrite;
+        }
+    }
+}
diff --git a/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties b/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties
new file mode 100644
index 0000000..9f647e9
--- /dev/null
+++ b/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties
@@ -0,0 +1,495 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#  
+#      http://www.apache.org/licenses/LICENSE-2.0
+#  
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+# 
+
+# messages for EN locale
+awt.00=FontRenderContext is null
+awt.01='{0}' parameter is null
+awt.02='{0}' parameter has zero length
+awt.03='{0}' iterator parameter is null
+awt.04='{0}' iterator parameter has zero length
+awt.05=Operation cannot be null
+awt.06=Unexpected type of the internal data buffer
+awt.07=Transfer data is not available
+awt.08=xfld parse string error: {0}
+awt.09=min range bound value is greater than max range bound
+awt.0A=Cannot use SinglePixedPackedSampleModel for bpp = {0}
+awt.0B=Wrong color model created for drawable
+awt.0C=Unknown visual class
+awt.0D=Invalid transparency
+awt.0E=Dimensions of the image should be positive
+awt.0F=Cannot open display '{0}'
+awt.10=Only 32-bit format is supported for window state operations.
+awt.11=Invalid key code
+awt.12=XTest is not supported by your X server\!
+awt.13=Cannot allocate color named '{0}'
+awt.14=Transfer data is not available
+awt.15=Can not get monitor info
+awt.16=Can not create DC for device
+awt.17=Unknown Composite type : {0}
+awt.18=Transparency is not supported
+awt.19=Illegal size of volatile image
+awt.1A=Failed to register window class {0} GetLastError returned {1}
+awt.1B=Invalid key code
+awt.1C=Failure to create JavaWindow GetLastError returned {0}
+awt.1D=Cannot get data from OLE clipboard
+awt.1E=Attempt to replace WindowProc handler
+awt.1F=Waiting for resource access thread interrupted not from unlock method
+awt.20=Can't unlock not locked resource
+awt.21=Not owner can't unlock resource
+awt.22=Not owner can't free resource
+awt.23=One thread can't store state several times in a row
+awt.24=Owner can't overwrite resource state. Lock operations may be lost
+awt.25=No state stored for current thread
+awt.26=Shutdown thread was interrupted while starting
+awt.27=Shutdown thread was interrupted while stopping
+awt.28=bad index: {0}
+awt.29=Invalid range
+awt.2A=Position not represented by view
+awt.2B=No word at {0}
+awt.2C=Invalid position: {0}
+awt.2D=Invalid direction
+awt.2E={0} not in range {1},{2}
+awt.2F=No more words
+awt.30=wrong number of elements to copy: {0}, size: {1}
+awt.31=no room to copy: {0}, size: {1}
+awt.32=String: '{0}' does not fit
+awt.33=index is out of range
+awt.34=Initial offset in the destination array is wrong: {0}
+awt.35=Wrong number of elements to copy: {0}
+awt.36=Wrong segment
+awt.37=Unknown  composite type {0}
+awt.38=Property name is not defined
+awt.39=This method is not implemented for image obtained from ImageProducer
+awt.3A=Color Model is null
+awt.3B=Incorrect ImageConsumer completion status
+awt.3C=Unknown PNG color type
+awt.3D=Unknown colorspace
+awt.3E=Clone not supported
+awt.3F=Invalid baseline index
+awt.40=Wrong number of metrics\!
+awt.41=Font returned unsupported type of line metrics. This case is known, but not supported yet.
+awt.42=TextHitInfo out of range
+awt.43=glyphIndex is out of vector's limits
+awt.44=beginGlyphIndex is out of vector's range
+awt.45=numEntries is out of vector's range
+awt.46=length of setPositions array differs from the length of positions array
+awt.47=First argument should be byte or short array
+awt.48=The srcIn raster is incompatible with src ColorModel
+awt.49=The dstIn raster is incompatible with dst ColorModel
+awt.4A=The dstOut raster is incompatible with dst ColorModel
+awt.4B=Iterator out of bounds
+awt.4C=Invalid MultiRectArea in method {0}
+awt.4D=The raster is incompatible with this ColorModel
+awt.4E=Unknown native platform.
+awt.4F=Data is not available
+awt.50=Iterator is read-only
+awt.51=Component expected to be a parent
+awt.52=Time interval can't be <= 0
+awt.53=Handler can't be null
+awt.54=Key event for unfocused component
+awt.55=Double mouse enter event for component
+awt.56=Double mouse exit event for component
+awt.57=Double focus gained event for component
+awt.58=Double focus lost event for component
+awt.59=Application has run out of context thread group
+awt.5A=Default class for PrinterJob is not found
+awt.5B=No access to default class for PrinterJob
+awt.5C=Instantiation exception for PrinterJob
+awt.5D={0} is not supported
+awt.5E=pageIndex is more than book size
+awt.5F=wrong orientation
+awt.60=Width and Height mustn't be equal zero both
+awt.61=Unsupported data type: {0}
+awt.62=Wrong mask : {0}
+awt.63=Coordinates are not in bounds
+awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+awt.65=null argument
+awt.66=Invalid format
+awt.67=subclass is not derived from AWTKeyStroke
+awt.68=subclass could not be instantiated
+awt.69=columns less than zero.
+awt.6A=rows less than zero.
+awt.6B=Queue stack is empty
+awt.6C=Event queue stack is broken
+awt.6D=Point is null
+awt.6E=Color is null
+awt.6F=Index less than zero
+awt.70=MenuItem is null
+awt.71=Parent is null
+awt.72=Key event for unfocused component
+awt.73=no such item
+awt.74=Input parameters a and b should not be null
+awt.75=rows and cols cannot both be zero
+awt.76=rows and cols cannot be negative
+awt.77=default focus traversal policy cannot be null
+awt.78=invalid focus traversal key identifier
+awt.79=cannot set null focus traversal key
+awt.7A=focus traversal keys cannot map to KEY_TYPED events
+awt.7B=focus traversal keys must be unique for a Component
+awt.7C=this KeyboardFocusManager is not installed in the current thread's context
+awt.7D=Property name is null
+awt.7E=invalid hotSpot
+awt.7F=AddLayoutComponent: attempt to add null component
+awt.80=AddLayoutComponent: constraint object must be GridBagConstraints
+awt.81=AddLayoutComponent: {0}
+awt.82=RemoveLayoutComponent: attempt to remove null component
+awt.83=SetConstraints: attempt to get constraints of null component
+awt.84=SetConstraints: attempt to set null constraints
+awt.85=SetConstraints: {0}
+awt.86=MinimumLayoutSize: {0}
+awt.87=PreferredLayoutSize: {0}
+awt.88=LayoutContainer: {0}
+awt.89=LookupConstraints: attempt to get constraints of null component
+awt.8A=AdjustForGravity: attempt to use null constraints
+awt.8B=AdjustForGravity: attempt to use null rectangle
+awt.8C=AdjustForGravity: {0}
+awt.8D=REMINDER component expected after RELATIVE one
+awt.8E=component is out of grid's range
+awt.8F=Weights' overrides array is too long
+awt.90=Lengths' overrides array is too long
+awt.91=Unsupported constraints object: {0}
+awt.92=Constraints object must be String
+awt.93=cannot get component: invalid constraint: {0}
+awt.94=transform can not be null
+awt.95=Wrong start index: {0}
+awt.96=Wrong finish index: {0}
+awt.97=Wrong range length: {0}
+awt.98=Wrong count value, can not be negative: {0}
+awt.99=Wrong [start + count] is out of range: {0}
+awt.9A=Unsupported font format
+awt.9B=Can't create font - bad font data
+awt.9C=wrong value of GridBagConstraints: {0}
+awt.9D=relative grid size parameter goes after absolute grid coordinate
+awt.9E=wrong values sum of GridBagConstraints' gridwidth and gridx
+awt.9F=wrong values sum of GridBagConstraints' gridheight and gridy
+awt.100=component has RELATIVE width and height
+awt.101=position less than zero.
+awt.102=columns less than zero.
+awt.103=item is null
+awt.104=item doesn't exist in the choice menu
+awt.105=index less than zero
+awt.106=specified position is greater than the number of items
+awt.107=Color parameter outside of expected range: component {0}
+awt.108=Alpha value outside of expected range
+awt.109=Color parameter outside of expected range
+awt.10A=Priority must be a value between 0 and 1, inclusive
+awt.10B=aContainer and aComponent cannot be null
+awt.10C=aContainer is not a focus cycle root of aComponent
+awt.10D=aContainer should be focus cycle root or focus traversal policy provider
+awt.10E=focusCycleRoot cannot be null
+awt.10F=improper alignment: {0}
+awt.110=Iterator out of bounds
+awt.111=Parameter npoints is greater than array length
+awt.112=Negative number of points
+awt.113=illegal scrollbar orientation
+awt.114=Image is null
+awt.115=Anchor is null
+awt.116=Invalid value for media
+awt.117=Invalid value for orientationRequested
+awt.118=Invalid value for printerResolution
+awt.119=Invalid value for origin
+awt.11A=Invalid value for printQuality
+awt.11B=Invalid value for printerResolution[]
+awt.11C=Invalid value for color
+awt.11D=Unknown rule
+awt.11E=Wrong alpha value
+awt.11F=parent is not a component
+awt.120=origin is not a descendant of parent
+awt.121=parent must be showing on the screen
+awt.122=Does not support display mode changes
+awt.123=Unsupported display mode: {0}
+awt.124=Cannot change the modality while the dialog is visible
+awt.125=null owner window
+awt.126=Window is showing
+awt.127=Cannot change the decorations while the window is visible
+awt.128=Graphics environment is headless
+awt.129=Not a screen device
+awt.12A=illegal component position
+awt.12B=adding container to itself
+awt.12C=adding container's parent to itself
+awt.12D=adding a window to a container
+awt.12E=Unknown component event id
+awt.12F=Attempt to start nested mouse grab
+awt.130=Attempt to grab mouse in not displayable window
+awt.131=AddLayoutComponent: constraint object must be String
+awt.132=wrong parent for CardLayout
+awt.133=Negative width
+awt.134=Illegal cap
+awt.135=Illegal join
+awt.136=miterLimit less than 1.0f
+awt.137=Negative dashPhase
+awt.138=Zero dash length
+awt.139=Negative dash[{0}]
+awt.13A=All dash lengths zero
+awt.13B=offset off is out of range
+awt.13C=number of elemets len is out of range
+awt.13D=Rectangle width and height must be > 0
+awt.13E=Cannot call method from the event dispatcher thread
+awt.13F=Delay must be to 0 to 60,000ms
+awt.140=Invalid combination of button flags
+awt.141=failed to parse hotspot property for cursor: 
+awt.142=Exception: class {0} {1} occurred while loading: {2}
+awt.143=illegal cursor type
+awt.144=Can be set by scrollpane only
+awt.145=illegal file dialog mode
+awt.146=illegal scrollbar display policy
+awt.147=position greater than 0
+awt.148=child is null
+awt.149=ScrollPane controls layout
+awt.14A=Can not create VolatileImage with specified capabilities
+awt.14B=Only Canvas or Window is allowed
+awt.14C=Number of buffers must be greater than one
+awt.14D=Buffer capabilities should support flipping
+awt.14E=Component should be displayable
+awt.14F=invalid focus traversal key identifier
+awt.150=no parent
+awt.151=component must be showing on the screen to determine its location
+awt.152=Invalid number of copies
+awt.153=Invalid value for maxPage
+awt.154=Invalid value for minPage
+awt.155=Invalid value for fromPage
+awt.156=Invalid value for toPage
+awt.157=Invalid value for pageRanges
+awt.158=Invalid value for destination
+awt.159=Invalid value for dialog
+awt.15A=Invalid value for defaultSelection
+awt.15B=Invalid value for multipleDocumentHandling
+awt.15C=Invalid value for attribute sides
+awt.15D=Invalid colorspace
+awt.15E=Unknown component. Must be REDCOMPONENT, GREENCOMPONENT or BLUECOMPONENT.
+awt.15F=Profile class does not comply with ICC specification
+awt.160=Color space doesn't comply with ICC specification
+awt.161=Unable to open file {0}
+awt.162=Invalid ICC Profile Data
+awt.163=Can't open color profile
+awt.164=Not a predefined color space
+awt.165=Color space doesn't comply with ICC specification
+awt.166=TRC is not a simple gamma value
+awt.167=TRC is a gamma value, not a table
+awt.168=Invalid profile class
+awt.169=Component index out of range
+awt.16A=Invalid component index: {0}
+awt.16B=Not a predefined colorspace
+awt.16C=Can't load class: {0}
+awt.16D=Can't parse MIME type: {0}
+awt.16E=Transferable has null data
+awt.16F=Can't create reader for this representation class
+awt.170=Can't create default D&D cursor: {0}
+awt.171=Attempt to start a drag while an existing drag operation is still executing
+awt.172=Drag source is null
+awt.173=One listener is already exist
+awt.174=dgl is not current listener
+awt.175=Listener mismatch
+awt.176=DropTarget cannot be added as listener to itself
+awt.177=Invalid user action
+awt.178=Invalid source action
+awt.179=Context peer is null
+awt.17A=Trigger event is null
+awt.17B=Can't init ACTION_NONE drag
+awt.17C=Image offset is null
+awt.17D=Transferable is null
+awt.17E=Component associated with the trigger event is null
+awt.17F=DragSource for the trigger event is null
+awt.180=Source actions for the DragGestureRecognizer associated with the trigger event are equal to DnDConstants.ACTION_NONE
+awt.181=Attempt to register context as its listener
+awt.182=dsl is not current listener
+awt.183=Invalid status
+awt.184=Invalid action
+awt.185=Component is null
+awt.186=DragSource is null
+awt.187=Origin is null
+awt.188=Event list is null
+awt.189=Event list is empty
+awt.18A=Context is null
+awt.18B=Invalid button value
+awt.18C=Cannot invoke null runnable
+awt.18D=Source is null
+awt.18E=Wrong event id
+awt.18F=Text must be null for CARET_POSITION_CHANGED
+awt.190=Wrong committedCharacterCount
+awt.191=Invalid keyCode for KEY_TYPED event, must be VK_UNDEFINED
+awt.192=Invalid keyChar for KEY_TYPED event, can't be CHAR_UNDEFINED
+awt.193=Listener can't be zero
+awt.194=Unknown attribute name
+awt.195=Offset is out of bounds
+awt.196=Justification impossible, layout already justified
+awt.197=Endpoints are out of range
+awt.198=Illegal alignment argument
+awt.199=Illegal range argument value: {0}
+awt.19A=start or count arguments are out of text range
+awt.19B=count argument must be positive
+awt.19C=weight must be a positive number
+awt.19D=growLeftLimit must be a positive number
+awt.19E=growRightLimit must be a positive number
+awt.19F=incorrect value for shrinkPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+awt.200=incorrect value for growPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+awt.201=shrinkLeftLimit must be a positive number
+awt.202=shrinkRightLimit must be a positive number
+awt.203=Offset limit should be greater than current position
+awt.204=Determinant is zero
+awt.205=Invalid type of Arc: {0}
+awt.206=Flatness is less then zero
+awt.207=Limit is less then zero
+awt.208=Path is null
+awt.209=Invalid winding rule value
+awt.20A=First segment should be SEG_MOVETO type
+awt.20B=unknown input method highlight state
+awt.20C=Number of Bits equals to zero
+awt.20D=The number of bits per pixel is not a power of 2 or pixels span data element boundaries
+awt.20E=Data Bit offset is not a multiple of pixel bit stride
+awt.20F=Number of bands must be only 1
+awt.210=The component value for this ColorModel is signed
+awt.211=Pixel values for this ColorModel are not conveniently representable as a single int
+awt.212=There is more than one component in this ColorModel
+awt.213=This ComponentColorModel does not support the unnormalized form
+awt.214=This Color Model doesn't support this transferType
+awt.215=transferType is not one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE
+awt.216=The components array is not large enough to hold all the color and alpha components
+awt.217=The transfer type of this ComponentColorModel is not one of the following transfer types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+awt.218=The components array is not large enough to hold all the color and alpha components
+awt.219=This transferType is not supported by this color model
+awt.21A=This ComponentColorModel does not support this transferType
+awt.21B=The length of normComponents minus normOffset is less than numComponents
+awt.21C=The number of scale factors should not be zero
+awt.21D=Number of src bands ({0}) does not match number of dst bands ({1})
+awt.21E=Number of scaling constants is not equal to the number of bands
+awt.21F=Unable to transform source
+awt.220=Source should not have IndexColorModel
+awt.221=The imageType is TYPE_BYTE_BINARY and the color map has more than 16 entries
+awt.222=The imageType is not TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED
+awt.223=The imageType is not compatible with ColorModel
+awt.224=Unknown image type
+awt.225=Property name is null
+awt.226=Both tileX and tileY are not equal to 0
+awt.227=This image type can't have alpha
+awt.228=minX or minY of this raster not equal to zero
+awt.229=Number of components in the LUT does not match the number of bands
+awt.22A=Wrong type of pixels array
+awt.22B=Length of data should not be less than width*height
+awt.22C=Unknown data type {0}
+awt.22D=This transferType ( {0} ) is not supported by this color model
+awt.22E=w or h is less than or equal to zero
+awt.22F=The product of w and h is greater than Integer.MAX_VALUE
+awt.230=dataType is not one of the supported data types
+awt.231=Number of bands must be more then 0
+awt.232=Offset should be not less than zero
+awt.233=Number of components should be positive
+awt.234=Width or Height equals zero
+awt.235=Wrong Data Buffer type : {0}
+awt.236=The bits is less than 1 or greater than 32
+awt.237=Source and destinations rasters do not have the same number of bands
+awt.238=The number of arrays in the LookupTable does not meet the restrictions
+awt.239=The space is not a TYPE_RGB space
+awt.23A=The min/max normalized component values are not 0.0/1.0
+awt.23B=The mask of the {0} component is not contiguous
+awt.23C=The mask of the alpha component is not contiguous
+awt.23D=The mask of the red component is not contiguous
+awt.23E=The mask of the green component is not contiguous
+awt.23F=The mask of the blue component is not contiguous
+awt.240=The transferType not is one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT or DataBuffer.TYPE_INT
+awt.241=Any offset between bands is greater than the Scanline stride
+awt.242=Pixel stride is less than any offset between bands
+awt.243=Product of Pixel stride and w is greater than Scanline stride
+awt.244=Width or Height of child Raster is less than or equal to zero
+awt.245=parentX disposes outside Raster
+awt.246=parentY disposes outside Raster
+awt.247=parentX + w results in integer overflow
+awt.248=parentY + h results in integer overflow
+awt.249=childMinX + w results in integer overflow
+awt.24A=childMinY + h results in integer overflow
+awt.24B=Pixel stride must be >= 0
+awt.24C=Scanline stride must be >= 0
+awt.24D=Bank Indices length must be equal Bank Offsets length
+awt.24E=Index of {0} bank must be >= 0
+awt.24F=Unable to invert transform {0}
+awt.250=Unknown interpolation type: {0}
+awt.251=Transformed width ({0}) and height ({1}) should be greater than 0
+awt.252=Source can't be same as the destination
+awt.253=Different number of bands in source and destination
+awt.254=Number of bands in the source raster ({0}) is incompatible with the matrix [{1}x{2}]
+awt.255=Number of bands in the destination raster ({0}) is incompatible with the matrix [{1}x{2}]
+awt.256=Source raster is null
+awt.257=Source raster is equal to destination
+awt.258=Number of source bands ({0}) is not equal to number of destination bands ({1})
+awt.259=Source image is null
+awt.25A=Source equals to destination
+awt.25B=Null ColorSpace passed as a parameter
+awt.25C=Null profiles passed as a parameter
+awt.25D=Source or destination color space is not defined
+awt.25E=Incorrect number of source raster bands. Should be equal to the number of color components of source colorspace.
+awt.25F=Incorrect number of destination raster bands. Should be equal to the number of color components of destination colorspace.
+awt.260=Incompatible rasters - width or height differs
+awt.261=Destination color space is undefined
+awt.262=Destionation color space should be defined
+awt.263=Incompatible images - width or height differs
+awt.264=Size of the color map is less than 1
+awt.265=The raster argument is not compatible with this IndexColorModel
+awt.266=The number of bits in a pixel is greater than 16
+awt.267=The transferType is invalid
+awt.268=The pixel is not a primitive array of type transferType
+awt.269=The transferType is not one of DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
+awt.26A=Incorrect ImageConsumer completion status
+awt.26B=The number of bits in the pixel values is less than 1
+awt.26C=bits is null
+awt.26D=The elements in bits is less than 0
+awt.26E=The sum of the number of bits in bits is less than 1
+awt.26F=The cspace is null
+awt.270=The transparency is not a valid value
+awt.271=The number of bits in bits is less than 1
+awt.272=The length of components minus offset is less than numComponents
+awt.273=The length of normComponents minus normOffset is less than numComponents
+awt.274=componentIdx is greater than the number of components or less than zero
+awt.275=This pixel representation is not suuported by tis Color Model
+awt.276=location.x + w or location.y + h results in integer overflow
+awt.277=bankIndices or bandOffsets is null
+awt.278=dataBuffer is null
+awt.279=bands is less than 1
+awt.27A=dataBuffer has more than one bank
+awt.27B=bandOffsets is null
+awt.27C=bandMasks is null
+awt.27D=bitsPerBand or bands is not greater than zero
+awt.27E=The product of bitsPerBand and bands is greater than the number of bits held by dataType
+awt.27F=SampleModel or DataBuffer is null
+awt.280=SampleModel is null
+awt.281=sampleModel, dataBuffer, aRegion or sampleModelTranslate is null
+awt.282=aRegion has width or height less than or equal to zero
+awt.283=Overflow X coordinate of Raster
+awt.284=Overflow Y coordinate of Raster
+awt.285=Width or Height of child Raster is less than or equal to zero
+awt.286=parentX disposes outside Raster
+awt.287=parentY disposes outside Raster
+awt.288=parentX + width results in integer overflow
+awt.289=parentY + height results in integer overflow
+awt.28A=childMinX + width results in integer overflow
+awt.28B=childMinY + height results in integer overflow
+awt.28C=Rect is null
+awt.28D=Length of dataArray[{0}] is less than size + offset[{1}]
+awt.28E=Length of dataArray is less than size + offset
+awt.28F=Source and destination rasters do not have the same width!
+awt.290=Source and destination rasters do not have the same height!
+awt.291=Source and destination images do not have the same width!
+awt.292=Source and destination images do not have the same height!
+awt.294=pixel is null
+awt.295=data is null
+awt.296=can't allocate memory on video card to create new display list
+awt.297=Invalid keyLocation
+awt.298=dataBuffer is too small
+
+awt.err.00=file dialog {0} error!
+awt.err.01=error: {0}
+awt.err.02=GDIPlus DrawDriverString error status = {0}
+awt.err.03=gdipDrawCompositeGlyphVector: GDIPlus DrawDriverString error status = {0}
+awt.err.04=gdipDrawCompositeGlyphVector: GDIPlus DrawDriverString error status = {0}
diff --git a/camera/libcameraservice/Android.mk b/camera/libcameraservice/Android.mk
new file mode 100644
index 0000000..4e7d6d2
--- /dev/null
+++ b/camera/libcameraservice/Android.mk
@@ -0,0 +1,58 @@
+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 ($(BOARD_CAMERA_LIBRARIES),)
+USE_CAMERA_STUB:=true
+else
+USE_CAMERA_STUB:=false
+endif #libcamerastub
+
+ifeq ($(USE_CAMERA_STUB),true)
+#
+# libcamerastub
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=               \
+    CameraHardwareStub.cpp      \
+    FakeCamera.cpp
+
+LOCAL_MODULE:= libcamerastub
+
+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 \
+    libcutils
+
+LOCAL_MODULE:= libcameraservice
+
+LOCAL_CFLAGS+=-DLOG_TAG=\"CameraService\"
+
+ifeq ($(USE_CAMERA_STUB), true)
+LOCAL_STATIC_LIBRARIES += libcamerastub
+LOCAL_CFLAGS += -include CameraHardwareStub.h
+else
+LOCAL_SHARED_LIBRARIES += $(BOARD_CAMERA_LIBRARIES)
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/camera/libcameraservice/CameraHardwareStub.cpp b/camera/libcameraservice/CameraHardwareStub.cpp
new file mode 100644
index 0000000..ea21af8
--- /dev/null
+++ b/camera/libcameraservice/CameraHardwareStub.cpp
@@ -0,0 +1,357 @@
+/*
+**
+** 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(),
+                    mHeap(0),
+                    mFakeCamera(0),
+                    mPreviewFrameSize(0),
+                    mRawPictureCallback(0),
+                    mJpegPictureCallback(0),
+                    mPictureCallbackCookie(0),
+                    mPreviewCallback(0),
+                    mPreviewCallbackCookie(0),
+                    mAutoFocusCallback(0),
+                    mAutoFocusCallbackCookie(0),
+                    mCurrentPreviewFrame(0)
+{
+    initDefaultParameters();
+}
+
+void CameraHardwareStub::initDefaultParameters()
+{
+    CameraParameters p;
+
+    p.setPreviewSize(176, 144);
+    p.setPreviewFrameRate(15);
+    p.setPreviewFormat("yuv422sp");
+
+    p.setPictureSize(kCannedJpegWidth, kCannedJpegHeight);
+    p.setPictureFormat("jpeg");
+
+    if (setParameters(p) != NO_ERROR) {
+        LOGE("Failed to set default parameters?!");
+    } 
+}
+
+void CameraHardwareStub::initHeapLocked()
+{
+    int width, height;
+    mParameters.getPreviewSize(&width, &height);
+
+    LOGD("initHeapLocked: preview size=%dx%d", width, height);
+
+    // Note that we enforce yuv422 in setParameters().
+    int how_big = width * 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
+    mHeap = 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(mHeap, i * mPreviewFrameSize, mPreviewFrameSize);
+    }
+
+    // Recreate the fake camera to reflect the current size.
+    delete mFakeCamera;
+    mFakeCamera = new FakeCamera(width, height);
+}
+
+CameraHardwareStub::~CameraHardwareStub()
+{
+    delete mFakeCamera;
+    mFakeCamera = 0; // paranoia
+    singleton.clear();
+}
+
+sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const
+{
+    return mHeap;
+}
+
+// ---------------------------------------------------------------------------
+
+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 = mHeap;
+    
+        // 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.
+        mPreviewCallback(buffer, mPreviewCallbackCookie);
+    
+        // Advance the buffer pointer.
+        mCurrentPreviewFrame = (mCurrentPreviewFrame + 1) % kBufferCount;
+
+        // Wait for it...
+        usleep(delay);
+    }
+
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::startPreview(preview_callback cb, void* user)
+{
+    Mutex::Autolock lock(mLock);
+    if (mPreviewThread != 0) {
+        // already running
+        return INVALID_OPERATION;
+    }
+    mPreviewCallback = cb;
+    mPreviewCallbackCookie = user;
+    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();
+}
+
+// ---------------------------------------------------------------------------
+
+int CameraHardwareStub::beginAutoFocusThread(void *cookie)
+{
+    CameraHardwareStub *c = (CameraHardwareStub *)cookie;
+    return c->autoFocusThread();
+}
+
+int CameraHardwareStub::autoFocusThread()
+{
+    if (mAutoFocusCallback != NULL) {
+        mAutoFocusCallback(true, mAutoFocusCallbackCookie);
+        mAutoFocusCallback = NULL;
+        return NO_ERROR;
+    }
+    return UNKNOWN_ERROR;
+}
+
+status_t CameraHardwareStub::autoFocus(autofocus_callback af_cb,
+                                       void *user)
+{
+    Mutex::Autolock lock(mLock);
+
+    if (mAutoFocusCallback != NULL) {
+        return mAutoFocusCallback == af_cb ? NO_ERROR : INVALID_OPERATION;
+    }
+
+    mAutoFocusCallback = af_cb;
+    mAutoFocusCallbackCookie = user;
+    if (createThread(beginAutoFocusThread, this) == false)
+        return UNKNOWN_ERROR;
+    return NO_ERROR;
+}
+
+/*static*/ int CameraHardwareStub::beginPictureThread(void *cookie)
+{
+    CameraHardwareStub *c = (CameraHardwareStub *)cookie;
+    return c->pictureThread();
+}
+
+int CameraHardwareStub::pictureThread()
+{
+    if (mShutterCallback)
+        mShutterCallback(mPictureCallbackCookie);
+
+    if (mRawPictureCallback) {
+        //FIXME: use a canned YUV image!
+        // In the meantime just make another fake camera picture.
+        int w, h;
+        mParameters.getPictureSize(&w, &h);
+        sp<MemoryHeapBase> heap = new MemoryHeapBase(w * 2 * h);
+        sp<MemoryBase> mem = new MemoryBase(heap, 0, w * 2 * h);
+        FakeCamera cam(w, h);
+        cam.getNextFrameAsYuv422((uint8_t *)heap->base());
+        if (mRawPictureCallback)
+            mRawPictureCallback(mem, mPictureCallbackCookie);
+    }
+
+    if (mJpegPictureCallback) {
+        sp<MemoryHeapBase> heap = new MemoryHeapBase(kCannedJpegSize);
+        sp<MemoryBase> mem = new MemoryBase(heap, 0, kCannedJpegSize);
+        memcpy(heap->base(), kCannedJpeg, kCannedJpegSize);
+        if (mJpegPictureCallback)
+            mJpegPictureCallback(mem, mPictureCallbackCookie);
+    }
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::takePicture(shutter_callback shutter_cb,
+                                         raw_callback raw_cb,
+                                         jpeg_callback jpeg_cb,
+                                         void* user)
+{
+    stopPreview();
+    mShutterCallback = shutter_cb;
+    mRawPictureCallback = raw_cb;
+    mJpegPictureCallback = jpeg_cb;
+    mPictureCallbackCookie = user;
+    if (createThread(beginPictureThread, this) == false)
+        return -1;
+    return NO_ERROR;
+}
+
+status_t CameraHardwareStub::cancelPicture(bool cancel_shutter,
+                                           bool cancel_raw,
+                                           bool cancel_jpeg)
+{
+    if (cancel_shutter) mShutterCallback = NULL;
+    if (cancel_raw) mRawPictureCallback = NULL;
+    if (cancel_jpeg) mJpegPictureCallback = NULL;
+    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, args);
+        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;
+}
+
+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
new file mode 100644
index 0000000..5b445d3
--- /dev/null
+++ b/camera/libcameraservice/CameraHardwareStub.h
@@ -0,0 +1,115 @@
+/*
+**
+** 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 <ui/CameraHardwareInterface.h>
+#include <utils/MemoryBase.h>
+#include <utils/MemoryHeapBase.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class CameraHardwareStub : public CameraHardwareInterface {
+public:
+    virtual sp<IMemoryHeap> getPreviewHeap() const;
+
+    virtual status_t    startPreview(preview_callback cb, void* user);
+    virtual void        stopPreview();
+    virtual status_t    autoFocus(autofocus_callback, void *user);
+    virtual status_t    takePicture(shutter_callback,
+                                    raw_callback,
+                                    jpeg_callback,
+                                    void* user);
+    virtual status_t    cancelPicture(bool cancel_shutter,
+                                      bool cancel_raw,
+                                      bool cancel_jpeg);
+    virtual status_t    dump(int fd, const Vector<String16>& args) const;
+    virtual status_t    setParameters(const CameraParameters& params);
+    virtual CameraParameters  getParameters() const;
+    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)
+            : Thread(false), 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>  mHeap;
+    sp<MemoryBase>      mBuffers[kBufferCount];
+
+    FakeCamera          *mFakeCamera;
+    bool                mPreviewRunning;
+    int                 mPreviewFrameSize;
+
+    shutter_callback    mShutterCallback;
+    raw_callback        mRawPictureCallback;
+    jpeg_callback       mJpegPictureCallback;
+    void                *mPictureCallbackCookie;
+
+    // protected by mLock
+    sp<PreviewThread>   mPreviewThread;
+    preview_callback    mPreviewCallback;
+    void                *mPreviewCallbackCookie;
+
+    autofocus_callback  mAutoFocusCallback;
+    void                *mAutoFocusCallbackCookie;
+
+    // only used from PreviewThread
+    int                 mCurrentPreviewFrame;
+};
+
+}; // namespace android
+
+#endif
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
new file mode 100644
index 0000000..5784c4b
--- /dev/null
+++ b/camera/libcameraservice/CameraService.cpp
@@ -0,0 +1,757 @@
+/*
+**
+** 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 "CameraService"
+#include <utils/Log.h>
+
+#include <utils/IServiceManager.h>
+#include <utils/IPCThreadState.h>
+#include <utils/String16.h>
+#include <utils/Errors.h>
+#include <utils/MemoryBase.h>
+#include <utils/MemoryHeapBase.h>
+#include <ui/ICameraService.h>
+
+#include "CameraService.h"
+
+namespace android {
+
+extern "C" {
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pthread.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
+
+#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
+static int debug_frame_cnt;
+#endif
+
+// ----------------------------------------------------------------------------
+
+void CameraService::instantiate() {
+    defaultServiceManager()->addService(
+            String16("media.camera"), new CameraService());
+}
+
+// ----------------------------------------------------------------------------
+
+CameraService::CameraService() :
+    BnCameraService()
+{
+    LOGI("CameraService started: pid=%d", getpid());
+}
+
+CameraService::~CameraService()
+{
+    if (mClient != 0) {
+        LOGE("mClient was still connected in destructor!");
+    }
+}
+
+sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient)
+{
+    LOGD("Connect E from ICameraClient %p", cameraClient->asBinder().get());
+
+    Mutex::Autolock lock(mLock);
+    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...
+                LOGD("Connect X same client is reconnecting...");
+                return currentClient;
+            } else {
+                // it's another client... boot the previous one...
+                LOGD("new client connecting, booting the old one...");
+                mClient.clear();
+            }
+        } else {
+            // can't promote, the previous client has died...
+            LOGD("new client connecting, old reference was dangling...");
+            mClient.clear();
+        }
+    }
+
+    // create a new Client object
+    sp<Client> client = new Client(this, cameraClient);
+    mClient = client;
+#if DEBUG_CLIENT_REFERENCES
+    // Enable tracking for this object, and track increments and decrements of
+    // the refcount.
+    client->trackMe(true, true);
+#endif
+    LOGD("Connect X");
+    return client;
+}
+
+void CameraService::removeClient(const sp<ICameraClient>& cameraClient)
+{
+    // declar this outside the lock to make absolutely sure the
+    // destructor won't be called with the lock held.
+    sp<Client> client;
+
+    Mutex::Autolock lock(mLock);
+
+    if (mClient == 0) {
+        // This happens when we have already disconnected.
+        LOGV("mClient is null.");
+        return;
+    }
+
+    // Promote mClient. It should never fail because we're called from
+    // a binder call, so someone has to have a strong reference.
+    client = mClient.promote();
+    if (client == 0) {
+        LOGW("can't get a strong reference on mClient!");
+        mClient.clear();
+        return;
+    }
+
+    if (cameraClient->asBinder() != client->getCameraClient()->asBinder()) {
+        // ugh! that's not our client!!
+        LOGW("removeClient() called, but mClient doesn't match!");
+    } else {
+        // okay, good, forget about mClient
+        mClient.clear();
+    }
+}
+
+CameraService::Client::Client(const sp<CameraService>& cameraService,
+        const sp<ICameraClient>& cameraClient) :
+    mCameraService(cameraService), mCameraClient(cameraClient), mHardware(0)
+{
+    LOGD("Client E constructor");
+    mHardware = openCameraHardware();
+    mHasFrameCallback = false;
+    LOGD("Client X constructor");
+}
+
+#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()
+{ 
+    // spin down hardware
+    LOGD("Client E destructor");
+    if (mSurface != 0) {
+#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
+    }
+
+    disconnect();
+    LOGD("Client X destructor");
+}
+
+void CameraService::Client::disconnect()
+{
+    LOGD("Client E disconnect");
+    Mutex::Autolock lock(mLock);
+    mCameraService->removeClient(mCameraClient);
+    if (mHardware != 0) {
+        // Before destroying mHardware, we must make sure it's in the
+        // idle state.
+        mHardware->stopPreview();
+        // Cancel all picture callbacks.
+        mHardware->cancelPicture(true, true, true);
+        // Release the hardware resources.
+        mHardware->release();
+    }
+    mHardware.clear();
+    LOGD("Client X disconnect");
+}
+
+// pass the buffered ISurface to the camera service
+status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
+{
+    LOGD("setPreviewDisplay(%p)", surface.get());
+    Mutex::Autolock lock(mLock);
+    Mutex::Autolock surfaceLock(mSurfaceLock);
+    // asBinder() is safe on NULL (returns NULL)
+    if (surface->asBinder() != mSurface->asBinder()) {
+        if (mSurface != 0) {
+            LOGD("clearing old preview surface %p", mSurface.get());
+            mSurface->unregisterBuffers();
+        }
+        mSurface = surface;
+    }
+    return NO_ERROR;
+}
+
+// tell the service whether to callback with each preview frame
+void CameraService::Client::setHasFrameCallback(bool installed)
+{
+    Mutex::Autolock lock(mLock);
+    mHasFrameCallback = installed;
+    // If installed is false, mPreviewBuffer will be released in stopPreview().
+}
+
+// start preview mode, must call setPreviewDisplay first
+status_t CameraService::Client::startPreview()
+{
+    LOGD("startPreview()");
+
+    /* we cannot call into mHardware with mLock held because
+     * mHardware has callbacks onto us which acquire this lock
+     */
+
+    Mutex::Autolock lock(mLock);
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+    
+    if (mSurface == 0) {
+        LOGE("setPreviewDisplay must be called before startPreview!");
+        return INVALID_OPERATION;
+    }
+    
+    // XXX: This needs to be improved. remove all hardcoded stuff
+    
+    int w, h;
+    CameraParameters params(mHardware->getParameters());
+    params.getPreviewSize(&w, &h);
+    
+    mSurface->unregisterBuffers();
+
+#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
+    debug_frame_cnt = 0;
+#endif
+    
+    status_t ret = mHardware->startPreview(previewCallback,
+                                           mCameraService.get());
+    if (ret == NO_ERROR) {
+        mSurface->registerBuffers(w,h,w,h,
+                                  PIXEL_FORMAT_YCbCr_420_SP,
+                                  mHardware->getPreviewHeap());
+    }
+    else LOGE("mHardware->startPreview() failed with status %d\n",
+              ret);
+    
+    return ret;
+}
+
+// stop preview mode
+void CameraService::Client::stopPreview()
+{
+    LOGD("stopPreview()");
+
+    Mutex::Autolock lock(mLock);
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return;
+    }
+
+    mHardware->stopPreview();
+    LOGD("stopPreview(), hardware stopped OK");
+    
+    if (mSurface != 0) {
+        mSurface->unregisterBuffers();
+    }
+    mPreviewBuffer.clear();
+}
+
+// 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->mLock);
+        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;
+
+    LOGD("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;
+    }
+
+    LOGD("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++;
+    }
+    LOGD("done writing %d bytes to file [%s] in %d passes\n",
+         size, fname, cnt);
+    ::close(fd);
+}
+#endif
+
+// preview callback - frame buffer update
+void CameraService::Client::previewCallback(const sp<IMemory>& mem, void* user)
+{
+    sp<Client> client = getClientFromCookie(user);
+    if (client == 0) {
+        return;
+    }
+
+#if DEBUG_HEAP_LEAKS && 0 // debugging
+    if (gWeakHeap == NULL) {
+        ssize_t offset;
+        size_t size;
+        sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+        if (gWeakHeap != heap) {
+            LOGD("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) {
+            ssize_t offset;
+            size_t size;
+            sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+            dump_to_file("/data/preview.yuv",
+                         (uint8_t *)heap->base() + offset, size);
+        }
+    }
+#endif
+
+    // The strong pointer guarantees the client will exist, but no lock is held.
+    client->postFrame(mem);
+
+#if DEBUG_CLIENT_REFERENCES
+    //**** if the client's refcount is 1, then we are about to destroy it here, 
+    // which is bad--print all refcounts.
+    if (client->getStrongCount() == 1) {
+        LOGE("++++++++++++++++ (PREVIEW) THIS WILL CAUSE A LOCKUP!");
+        client->printRefs();
+    }
+#endif
+}
+
+// take a picture - image is returned in callback
+status_t CameraService::Client::autoFocus()
+{
+    LOGV("autoFocus");
+
+    Mutex::Autolock lock(mLock);
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+
+    return mHardware->autoFocus(autoFocusCallback,
+                                mCameraService.get());
+}
+
+// take a picture - image is returned in callback
+status_t CameraService::Client::takePicture()
+{
+    LOGD("takePicture");
+
+    Mutex::Autolock lock(mLock);
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+    
+    if (mSurface != NULL)
+        mSurface->unregisterBuffers();
+
+    return mHardware->takePicture(shutterCallback,
+                                  yuvPictureCallback,
+                                  jpegPictureCallback,
+                                  mCameraService.get());
+}
+
+// picture callback - snapshot taken
+void CameraService::Client::shutterCallback(void *user)
+{
+    sp<Client> client = getClientFromCookie(user);
+    if (client == 0) {
+        return;
+    }
+
+    client->postShutter();
+}
+
+// picture callback - raw image ready
+void CameraService::Client::yuvPictureCallback(const sp<IMemory>& mem,
+                                               void *user)
+{
+    sp<Client> client = getClientFromCookie(user);
+    if (client == 0) {
+        return;
+    }
+    if (mem == NULL) {
+        client->postRaw(NULL);
+        client->postError(UNKNOWN_ERROR);
+        return;
+    }
+
+    ssize_t offset;
+    size_t size;
+    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+#if DEBUG_HEAP_LEAKS && 0 // debugging
+    gWeakHeap = heap; // debugging
+#endif
+
+    //LOGV("yuvPictureCallback(%d, %d, %p)", offset, size, user);
+#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.
+    int w, h;
+    CameraParameters params(client->mHardware->getParameters());
+    params.getPictureSize(&w, &h);
+
+//  Mutex::Autolock clientLock(client->mLock);
+    if (client->mSurface != 0) {
+        client->mSurface->unregisterBuffers();
+        client->mSurface->registerBuffers(w,h,w,h,
+                                          PIXEL_FORMAT_YCbCr_420_SP, heap);
+        client->mSurface->postBuffer(offset);
+    }
+
+    client->postRaw(mem);
+
+#if DEBUG_CLIENT_REFERENCES
+    //**** if the client's refcount is 1, then we are about to destroy it here, 
+    // which is bad--print all refcounts.
+    if (client->getStrongCount() == 1) {
+        LOGE("++++++++++++++++ (RAW) THIS WILL CAUSE A LOCKUP!");
+        client->printRefs();
+    }
+#endif
+}
+
+// picture callback - jpeg ready
+void CameraService::Client::jpegPictureCallback(const sp<IMemory>& mem, void *user)
+{
+    sp<Client> client = getClientFromCookie(user);
+    if (client == 0) {
+        return;
+    }
+    if (mem == NULL) {
+        client->postJpeg(NULL);
+        client->postError(UNKNOWN_ERROR);
+        return;
+    }
+
+    /** We absolutely CANNOT call into user code with a lock held **/
+
+#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
+
+    client->postJpeg(mem);
+
+#if DEBUG_CLIENT_REFERENCES
+    //**** if the client's refcount is 1, then we are about to destroy it here, 
+    // which is bad--print all refcounts.
+    if (client->getStrongCount() == 1) {
+        LOGE("++++++++++++++++ (JPEG) THIS WILL CAUSE A LOCKUP!");
+        client->printRefs();
+    }
+#endif
+}
+
+void CameraService::Client::autoFocusCallback(bool focused, void *user)
+{
+    LOGV("autoFocusCallback");
+
+    sp<Client> client = getClientFromCookie(user);
+    if (client == 0) {
+        return;
+    }
+
+    client->postAutoFocus(focused);
+
+#if DEBUG_CLIENT_REFERENCES
+    if (client->getStrongCount() == 1) {
+        LOGE("++++++++++++++++ (AUTOFOCUS) THIS WILL CAUSE A LOCKUP!");
+        client->printRefs();
+    }
+#endif
+}
+
+// set preview/capture parameters - key/value pairs
+status_t CameraService::Client::setParameters(const String8& params)
+{
+    LOGD("setParameters(%s)", params.string());
+
+    Mutex::Autolock lock(mLock);
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return INVALID_OPERATION;
+    }
+
+    CameraParameters p(params);
+    mHardware->setParameters(p);
+    return NO_ERROR;
+}
+
+// get preview/capture parameters - key/value pairs
+String8 CameraService::Client::getParameters() const
+{
+    LOGD("getParameters");
+
+    Mutex::Autolock lock(mLock);
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return String8();
+    }
+
+    return mHardware->getParameters().flatten();
+}
+
+void CameraService::Client::postAutoFocus(bool focused)
+{
+    LOGV("postAutoFocus");
+    mCameraClient->autoFocusCallback(focused);
+}
+
+void CameraService::Client::postShutter()
+{
+    mCameraClient->shutterCallback();
+}
+
+void CameraService::Client::postRaw(const sp<IMemory>& mem)
+{
+    LOGD("postRaw");
+    mCameraClient->rawCallback(mem);
+}
+
+void CameraService::Client::postJpeg(const sp<IMemory>& mem)
+{
+    LOGD("postJpeg");
+    mCameraClient->jpegCallback(mem);
+}
+
+void CameraService::Client::postFrame(const sp<IMemory>& mem)
+{
+    ssize_t offset;
+    size_t size;
+    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+
+    sp<MemoryBase> frame;
+
+    {
+        Mutex::Autolock surfaceLock(mSurfaceLock);
+        if (mSurface != NULL)
+            mSurface->postBuffer(offset);
+    }
+    
+    // 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.
+    if (mHasFrameCallback) {
+        if (mPreviewBuffer == 0) {
+            mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
+        } else if (size > mPreviewBuffer->virtualSize()) {
+            mPreviewBuffer.clear();
+            mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
+        }
+        memcpy(mPreviewBuffer->base(), (uint8_t *)heap->base() + offset, size);
+        frame = new MemoryBase(mPreviewBuffer, 0, size);
+    }
+    
+    // Do not hold the client lock while calling back.
+    if (frame != 0) {
+        mCameraClient->frameCallback(frame);
+    }
+}
+
+void CameraService::Client::postError(status_t error) {
+    mCameraClient->errorCallback(error);
+}
+
+status_t CameraService::dump(int fd, const Vector<String16>& args)
+{
+    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",
+                IPCThreadState::self()->getCallingPid(),
+                IPCThreadState::self()->getCallingUid());
+        result.append(buffer);
+        write(fd, result.string(), result.size());
+    } else {
+        AutoMutex lock(&mLock);
+        if (mClient != 0) {
+            sp<Client> currentClient = mClient.promote();
+            currentClient->mHardware->dump(fd, args);
+        } else {
+            result.append("No camera client yet.\n");
+            write(fd, result.string(), result.size());
+        }
+    }
+    return NO_ERROR;
+}
+
+
+#if DEBUG_HEAP_LEAKS
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+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);
+    
+    LOGD("+++ 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).
+
+        LOGD("+++ 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();
+                LOGD("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!
+                    LOGD("DELETING WEAK REFERENCE %p (%p)", h.get(), p);
+                    if (p) delete p;
+                }
+                return NO_ERROR;
+            }
+        }
+        break;
+        default:
+            break;
+        }
+    }
+    return err;
+}
+
+#endif // DEBUG_HEAP_LEAKS
+
+}; // namespace android
+
+
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
new file mode 100644
index 0000000..683c51b
--- /dev/null
+++ b/camera/libcameraservice/CameraService.h
@@ -0,0 +1,160 @@
+/*
+**
+** 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_SERVERS_CAMERA_CAMERASERVICE_H
+#define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
+
+#include <ui/ICameraService.h>
+#include <ui/CameraHardwareInterface.h>
+class android::MemoryHeapBase;
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+#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);
+
+#if DEBUG_HEAP_LEAKS
+    virtual status_t onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+#endif
+
+private:
+
+// ----------------------------------------------------------------------------
+
+    class Client : public BnCamera {
+
+    public:
+        virtual void            disconnect();
+
+        // pass the buffered ISurface to the camera service
+        virtual status_t        setPreviewDisplay(const sp<ISurface>& surface);
+        
+        // tell the service whether to callback with each preview frame
+        virtual void            setHasFrameCallback(bool installed);
+
+        // start preview mode, must call setPreviewDisplay first
+        virtual status_t        startPreview();
+
+        // stop preview mode
+        virtual void            stopPreview();
+
+        // auto focus
+        virtual status_t        autoFocus();
+
+        // 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;
+
+        // our client...
+        const sp<ICameraClient>&    getCameraClient() const { return mCameraClient; }
+
+    private:
+        friend class CameraService;
+                                Client( const sp<CameraService>& cameraService,
+                                        const sp<ICameraClient>& cameraClient);
+                                Client();
+        virtual                 ~Client();
+
+        static      void        previewCallback(const sp<IMemory>& mem, void* user);
+        static      void        shutterCallback(void *user);
+        static      void        yuvPictureCallback(const sp<IMemory>& mem, void* user);
+        static      void        jpegPictureCallback(const sp<IMemory>& mem, void* user);
+        static      void        autoFocusCallback(bool focused, void* user);
+        static      sp<Client>  getClientFromCookie(void* user);
+
+                    void        postShutter();
+                    void        postRaw(const sp<IMemory>& mem);
+                    void        postJpeg(const sp<IMemory>& mem);
+                    void        postFrame(const sp<IMemory>& mem);
+                    void        postError(status_t error);
+                    void        postAutoFocus(bool focused);
+
+                    // Ensures atomicity among the public methods
+        mutable     Mutex                       mLock;
+        // mSurfaceLock synchronizes access to mSurface between
+        // setPreviewSurface() and postFrame().  Note that among
+        // the public methods, all accesses to mSurface are 
+        // syncrhonized by mLock.  However, postFrame() 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
+        // top 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;
+                    sp<MemoryHeapBase>          mPreviewBuffer;
+                    bool                        mHasFrameCallback;
+
+                    // these are immutable once the object is created,
+                    // they don't need to be protected by a lock
+                    sp<ICameraClient>           mCameraClient;
+                    sp<CameraHardwareInterface> mHardware;
+    };
+
+// ----------------------------------------------------------------------------
+
+                            CameraService();
+    virtual                 ~CameraService();
+
+    mutable     Mutex                       mLock;
+                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
new file mode 100644
index 0000000..532560a
--- /dev/null
+++ b/camera/libcameraservice/CannedJpeg.h
@@ -0,0 +1,1546 @@
+const int kCannedJpegWidth = 213;
+const int kCannedJpegHeight = 350;
+const int kCannedJpegSize = 18474;
+
+const char kCannedJpeg[] = {
+  0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
+  0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43,
+  0x00, 0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04, 0x04, 0x05,
+  0x05, 0x05, 0x06, 0x07, 0x0c, 0x08, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b,
+  0x0b, 0x09, 0x0c, 0x11, 0x0f, 0x12, 0x12, 0x11, 0x0f, 0x11, 0x11, 0x13,
+  0x16, 0x1c, 0x17, 0x13, 0x14, 0x1a, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18,
+  0x1a, 0x1d, 0x1d, 0x1f, 0x1f, 0x1f, 0x13, 0x17, 0x22, 0x24, 0x22, 0x1e,
+  0x24, 0x1c, 0x1e, 0x1f, 0x1e, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x05, 0x05,
+  0x05, 0x07, 0x06, 0x07, 0x0e, 0x08, 0x08, 0x0e, 0x1e, 0x14, 0x11, 0x14,
+  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+  0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+  0x1e, 0x1e, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x01, 0x5e, 0x00, 0xd5, 0x03,
+  0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00,
+  0x1c, 0x00, 0x00, 0x02, 0x02, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x07, 0x01, 0x03,
+  0x04, 0x02, 0x08, 0xff, 0xc4, 0x00, 0x55, 0x10, 0x00, 0x01, 0x03, 0x04,
+  0x00, 0x03, 0x03, 0x05, 0x0a, 0x09, 0x08, 0x09, 0x02, 0x06, 0x03, 0x00,
+  0x01, 0x02, 0x03, 0x04, 0x00, 0x05, 0x06, 0x11, 0x07, 0x12, 0x21, 0x13,
+  0x31, 0x41, 0x14, 0x22, 0x51, 0x61, 0x71, 0x15, 0x23, 0x32, 0x34, 0x37,
+  0x72, 0x75, 0x81, 0xb1, 0xb3, 0x08, 0x17, 0x33, 0x42, 0x52, 0x62, 0x76,
+  0x93, 0xb2, 0x16, 0x24, 0x43, 0x53, 0x56, 0x91, 0xa1, 0xd2, 0x25, 0x36,
+  0x63, 0x73, 0x82, 0x92, 0xa2, 0xc1, 0xd1, 0x65, 0xf0, 0x26, 0x27, 0x64,
+  0x66, 0x74, 0xe1, 0x83, 0xc2, 0xf1, 0xff, 0xc4, 0x00, 0x1b, 0x01, 0x01,
+  0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xff,
+  0xc4, 0x00, 0x35, 0x11, 0x00, 0x02, 0x01, 0x03, 0x03, 0x01, 0x05, 0x05,
+  0x07, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
+  0x04, 0x11, 0x12, 0x21, 0x31, 0x41, 0x05, 0x22, 0x32, 0x51, 0x61, 0x06,
+  0x13, 0x71, 0x81, 0xb1, 0x14, 0x33, 0x42, 0x91, 0xa1, 0xc1, 0xd1, 0x15,
+  0x23, 0xe1, 0xf0, 0x24, 0x53, 0x92, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01,
+  0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xfb, 0x2e, 0x8a, 0x2b,
+  0xca, 0x95, 0xae, 0xfe, 0xea, 0x03, 0xd5, 0x15, 0x8d, 0xfb, 0x28, 0xdf,
+  0xb2, 0x80, 0xcd, 0x15, 0x8d, 0xfb, 0x28, 0xdf, 0xb2, 0x80, 0xcd, 0x15,
+  0x8d, 0xfb, 0x28, 0xe6, 0xa0, 0x33, 0x45, 0x63, 0x9a, 0xb3, 0x40, 0x14,
+  0x51, 0x45, 0x00, 0x51, 0x45, 0x14, 0x01, 0x45, 0x14, 0x50, 0x05, 0x14,
+  0x56, 0x37, 0x40, 0x66, 0x8a, 0x37, 0xd6, 0xb1, 0xbf, 0x65, 0x01, 0x9a,
+  0x2b, 0x1b, 0xf6, 0x51, 0xbf, 0x65, 0x01, 0x9a, 0x2b, 0x1b, 0xf6, 0x51,
+  0xbf, 0x65, 0x01, 0x9a, 0x2b, 0xc9, 0x56, 0xbb, 0xeb, 0xd0, 0xa0, 0x0a,
+  0x2b, 0xca, 0x95, 0xa3, 0x45, 0x01, 0xea, 0x93, 0x78, 0xe1, 0xb1, 0xc1,
+  0xec, 0xb8, 0x82, 0x41, 0xf7, 0x1e, 0x4f, 0x71, 0xd7, 0xf4, 0x66, 0x9c,
+  0xa9, 0x37, 0x8e, 0x5f, 0x23, 0xb9, 0x77, 0xd0, 0xf2, 0x7e, 0xec, 0xd0,
+  0x15, 0xb3, 0x5c, 0x3c, 0xc1, 0xd4, 0xd2, 0x14, 0x71, 0x7b, 0x69, 0x25,
+  0x20, 0x9f, 0x7a, 0xaf, 0x5f, 0x8b, 0xbc, 0x1b, 0xfb, 0x2d, 0x6c, 0xfd,
+  0xd5, 0x33, 0x31, 0xf9, 0x16, 0xfe, 0x68, 0xfb, 0x2b, 0xdd, 0x7b, 0x9a,
+  0x23, 0xe4, 0x78, 0x9a, 0xe5, 0xe6, 0x2b, 0x7e, 0x2e, 0xf0, 0x6f, 0xec,
+  0xb5, 0xb3, 0xf7, 0x54, 0x1e, 0x1e, 0x60, 0xc3, 0xaf, 0xf2, 0x5a, 0xd9,
+  0xaf, 0xf7, 0x54, 0xc7, 0x36, 0x54, 0x68, 0x50, 0xde, 0x99, 0x32, 0x43,
+  0x51, 0xa3, 0x30, 0x92, 0xb7, 0x5e, 0x75, 0x41, 0x28, 0x42, 0x40, 0xea,
+  0x54, 0x4f, 0x40, 0x2a, 0x2e, 0xcf, 0x13, 0x28, 0xcd, 0xf9, 0x5c, 0xb3,
+  0x07, 0xb1, 0xcc, 0x7d, 0x63, 0x7e, 0xeb, 0x49, 0x67, 0xf9, 0xd4, 0x94,
+  0xfa, 0x63, 0x34, 0xaf, 0x80, 0x93, 0xe0, 0xe3, 0x83, 0xae, 0xf6, 0x10,
+  0x7a, 0x1a, 0xce, 0xa4, 0xa9, 0x53, 0x59, 0x92, 0x46, 0x94, 0xe3, 0x52,
+  0xa3, 0xc4, 0x5b, 0x17, 0x2f, 0x98, 0xdf, 0x0b, 0xec, 0xaa, 0x65, 0xa9,
+  0xf6, 0x1b, 0x60, 0x92, 0xff, 0x00, 0x48, 0xf1, 0x19, 0x8c, 0xa7, 0xa4,
+  0x3e, 0x7d, 0x08, 0x69, 0x00, 0xad, 0x5f, 0x50, 0xd7, 0xa7, 0x55, 0x98,
+  0x1c, 0x28, 0x93, 0x91, 0x84, 0x2a, 0x0e, 0x09, 0x62, 0xc5, 0x20, 0xa8,
+  0xef, 0xca, 0x6e, 0xcc, 0x87, 0xe5, 0x91, 0xae, 0xf4, 0xc7, 0x42, 0xb9,
+  0x50, 0x7e, 0x7a, 0xf6, 0x3f, 0x46, 0xae, 0x9c, 0x33, 0x0a, 0xc7, 0x71,
+  0x46, 0xd6, 0xbb, 0x4c, 0x1f, 0xe7, 0x6f, 0x0f, 0xe7, 0x33, 0xa4, 0x2c,
+  0xbb, 0x2a, 0x41, 0xf4, 0xad, 0xd5, 0x79, 0xc7, 0xbb, 0xbb, 0xa2, 0x47,
+  0x80, 0x14, 0xc5, 0xaa, 0xf3, 0xea, 0x5c, 0x6a, 0xf0, 0xa4, 0x8e, 0xfa,
+  0x74, 0x34, 0xee, 0xdb, 0x65, 0x47, 0x8e, 0x7e, 0x0f, 0x1c, 0x37, 0xb6,
+  0xbe, 0x26, 0x5c, 0x6d, 0xef, 0xdf, 0x26, 0xeb, 0xf2, 0x93, 0x1c, 0xe5,
+  0x6d, 0x3e, 0x90, 0x96, 0x5b, 0xe5, 0x6c, 0x0f, 0x68, 0x27, 0xd7, 0x4c,
+  0xbf, 0x8a, 0x2e, 0x19, 0xff, 0x00, 0x62, 0xac, 0xff, 0x00, 0xb8, 0xa7,
+  0x8a, 0x2b, 0x9c, 0xe8, 0x12, 0x3f, 0x14, 0x7c, 0x33, 0xfe, 0xc5, 0x59,
+  0xff, 0x00, 0x71, 0x47, 0xe2, 0x8f, 0x86, 0x7f, 0xd8, 0xab, 0x3f, 0xee,
+  0x29, 0xde, 0x8a, 0x01, 0x09, 0xce, 0x16, 0x70, 0xad, 0xb7, 0xd0, 0xc3,
+  0x98, 0x8d, 0x89, 0x0e, 0xb9, 0xf0, 0x10, 0xa6, 0xc0, 0x52, 0xbd, 0x83,
+  0x7d, 0x6b, 0x77, 0xe2, 0x8f, 0x86, 0x7f, 0xd8, 0xab, 0x3f, 0xee, 0x2b,
+  0xb6, 0xef, 0xef, 0x9c, 0x40, 0xb5, 0x23, 0xaf, 0x98, 0xca, 0xd5, 0xf6,
+  0xd3, 0x55, 0x72, 0xdb, 0xd7, 0x75, 0x65, 0x51, 0x63, 0xc2, 0xf1, 0xfa,
+  0x27, 0xfb, 0x90, 0x9e, 0x44, 0x8f, 0xc5, 0x1f, 0x0c, 0xff, 0x00, 0xb1,
+  0x56, 0x7f, 0xdc, 0x51, 0xf8, 0xa3, 0xe1, 0x9f, 0xf6, 0x2a, 0xcf, 0xfb,
+  0x8a, 0x77, 0xa2, 0xba, 0x89, 0x12, 0x3f, 0x14, 0x7c, 0x33, 0xfe, 0xc5,
+  0x59, 0xff, 0x00, 0x71, 0x58, 0x57, 0x08, 0xb8, 0x66, 0xa4, 0x94, 0x9c,
+  0x2a, 0xd1, 0xa2, 0x34, 0x74, 0xce, 0xa9, 0xe2, 0x8a, 0x02, 0x91, 0xbe,
+  0x7e, 0x0e, 0x38, 0x70, 0x75, 0xd9, 0x58, 0xa9, 0x16, 0xa7, 0xd4, 0x76,
+  0x23, 0x4c, 0x6b, 0xcb, 0xa1, 0xa8, 0xfa, 0x0a, 0x1c, 0x3c, 0xe9, 0xdf,
+  0xea, 0xad, 0x3e, 0xca, 0x58, 0xb8, 0x61, 0x36, 0xcc, 0x68, 0x7f, 0xf1,
+  0x8f, 0x0c, 0xe0, 0x37, 0x19, 0x3f, 0x0a, 0xeb, 0x68, 0x69, 0x52, 0xa2,
+  0x01, 0xae, 0xf5, 0xa3, 0x5d, 0xab, 0x43, 0xd6, 0x52, 0xa4, 0x8f, 0xd2,
+  0xf1, 0xaf, 0xa5, 0x48, 0x1b, 0xdd, 0x63, 0x42, 0xb4, 0x85, 0x47, 0x0e,
+  0x0c, 0xe7, 0x4d, 0x4f, 0x93, 0xe7, 0xfb, 0x76, 0x11, 0xc3, 0xab, 0x94,
+  0x26, 0xe6, 0xdb, 0xac, 0x36, 0x59, 0x91, 0x9d, 0x1b, 0x6d, 0xe6, 0x12,
+  0x16, 0x85, 0x8f, 0x51, 0x49, 0x23, 0xff, 0x00, 0x7a, 0xae, 0x81, 0xc3,
+  0xbc, 0x1b, 0x5f, 0xea, 0xb5, 0xb3, 0xf7, 0x54, 0xf1, 0x95, 0x70, 0xce,
+  0xdf, 0x2a, 0x73, 0xf7, 0x8c, 0x56, 0x51, 0xc6, 0xef, 0x4e, 0x9e, 0x67,
+  0x1c, 0x61, 0xb0, 0xa8, 0xb2, 0x95, 0xff, 0x00, 0xd4, 0x31, 0xd1, 0x2b,
+  0xdf, 0xe9, 0x0e, 0x55, 0x8f, 0xd2, 0xf0, 0xa5, 0x58, 0xb7, 0x89, 0xd0,
+  0xef, 0x28, 0xc7, 0xb2, 0xab, 0x7a, 0x2d, 0x17, 0x85, 0x82, 0x63, 0x94,
+  0xb8, 0x57, 0x16, 0x78, 0x1d, 0xea, 0x8e, 0xe1, 0x1d, 0x74, 0x3a, 0x94,
+  0x11, 0xcc, 0x91, 0xe9, 0x1e, 0x75, 0x77, 0xd2, 0xad, 0x4e, 0xa6, 0xcd,
+  0x24, 0xce, 0x0a, 0xb4, 0x6a, 0x53, 0xdd, 0x36, 0xd1, 0xc3, 0xf8, 0xbb,
+  0xc1, 0xbf, 0xb2, 0xd6, 0xcf, 0xdd, 0x51, 0xf8, 0xbb, 0xc1, 0xbf, 0xb2,
+  0xd6, 0xcf, 0xdd, 0x53, 0x48, 0xee, 0xa2, 0xba, 0x74, 0x47, 0xc8, 0xe7,
+  0xd7, 0x2f, 0x31, 0x0e, 0xf1, 0x88, 0xe3, 0x36, 0x4b, 0xc6, 0x2d, 0x3a,
+  0xd1, 0x65, 0x87, 0x06, 0x50, 0xc9, 0x2d, 0xe8, 0xed, 0x59, 0x47, 0x2a,
+  0xb9, 0x4b, 0xa0, 0x11, 0xbf, 0x41, 0x15, 0xf4, 0x60, 0xee, 0xaa, 0x3f,
+  0x33, 0xf8, 0xd6, 0x2d, 0xfb, 0x4f, 0x6e, 0xfb, 0xe1, 0x57, 0x80, 0xee,
+  0xaf, 0x36, 0xed, 0x25, 0x53, 0x63, 0xd2, 0xb5, 0x6d, 0xc3, 0x73, 0x04,
+  0x6c, 0xf7, 0xd1, 0x59, 0xa2, 0xb9, 0x4e, 0x90, 0xa4, 0xde, 0x39, 0x7c,
+  0x8e, 0xe5, 0xdf, 0x43, 0xc9, 0xfb, 0xb3, 0x4e, 0x54, 0x9b, 0xc7, 0x2f,
+  0x91, 0xdc, 0xbb, 0xe8, 0x79, 0x3f, 0x76, 0x68, 0x05, 0xe6, 0x3f, 0x22,
+  0xdf, 0xcd, 0x1f, 0x65, 0x68, 0xbb, 0xdc, 0x61, 0x5a, 0x2d, 0x92, 0x2e,
+  0x57, 0x29, 0x08, 0x8f, 0x12, 0x3a, 0x39, 0xdd, 0x71, 0x5b, 0xd0, 0x1e,
+  0xaf, 0x49, 0x27, 0x40, 0x01, 0xd4, 0x92, 0x05, 0x74, 0x31, 0xf9, 0x26,
+  0xc7, 0xa5, 0x20, 0x0e, 0x9e, 0xaa, 0xe0, 0xe1, 0xed, 0xa1, 0x19, 0xbe,
+  0x42, 0x8c, 0xba, 0x7a, 0x79, 0xf1, 0xfb, 0x5c, 0x85, 0x26, 0xc6, 0xc2,
+  0xbe, 0x0c, 0x99, 0x08, 0x3c, 0xab, 0x98, 0xa1, 0xe2, 0x12, 0xa0, 0x52,
+  0xd8, 0x3d, 0x3a, 0x15, 0xf7, 0x94, 0x91, 0xec, 0xd6, 0xaa, 0xa9, 0x47,
+  0x27, 0x8f, 0x46, 0x93, 0xa9, 0x2c, 0x1d, 0x18, 0x8e, 0x17, 0x33, 0x29,
+  0x97, 0x1f, 0x22, 0xcd, 0xa1, 0xae, 0x3c, 0x26, 0x5c, 0x4b, 0xd6, 0xcb,
+  0x0b, 0xa3, 0xa3, 0x64, 0x1d, 0xa5, 0xf9, 0x43, 0xb9, 0x4e, 0xf8, 0x86,
+  0xfa, 0xa5, 0xbf, 0x5a, 0xb6, 0x45, 0xb0, 0x07, 0x4a, 0x00, 0x1a, 0xe9,
+  0xfe, 0x15, 0x9a, 0xf2, 0x25, 0x27, 0x37, 0x96, 0x7a, 0xd1, 0x82, 0x8a,
+  0xc2, 0x0a, 0x2b, 0x92, 0xee, 0xfc, 0xa8, 0xd0, 0x1c, 0x7a, 0x1c, 0x6f,
+  0x29, 0x79, 0x23, 0xcd, 0x6f, 0x7a, 0xdd, 0x71, 0xe3, 0xf7, 0xf8, 0x77,
+  0x64, 0x72, 0x02, 0x59, 0x92, 0x9e, 0x8e, 0x32, 0xbe, 0x8a, 0x07, 0xfe,
+  0xf5, 0xcd, 0x2b, 0x9a, 0x71, 0xaa, 0xa9, 0x49, 0xe1, 0xbe, 0x3d, 0x49,
+  0xcf, 0x42, 0x5e, 0x8a, 0xd7, 0x25, 0xf6, 0x63, 0x30, 0xa7, 0x9f, 0x71,
+  0x2d, 0xb6, 0x91, 0xb2, 0xa5, 0x1d, 0x0a, 0xae, 0xb2, 0x8c, 0xe9, 0xf7,
+  0xd4, 0xb8, 0xd6, 0x8f, 0x7a, 0x6b, 0xb8, 0xbc, 0x7e, 0x12, 0xbd, 0x9e,
+  0x8a, 0xe6, 0xbf, 0xed, 0x3a, 0x16, 0x30, 0xd5, 0x55, 0xef, 0xd1, 0x75,
+  0x64, 0x4a, 0x49, 0x72, 0x3e, 0x5c, 0xae, 0xd6, 0xdb, 0x72, 0x79, 0xa6,
+  0xcc, 0x69, 0x9f, 0x51, 0x3d, 0x7f, 0xb8, 0x75, 0xa5, 0xc9, 0x9c, 0x40,
+  0xb4, 0xb4, 0x48, 0x61, 0x97, 0xdf, 0xf5, 0xeb, 0x42, 0xab, 0x17, 0x9d,
+  0x75, 0xe7, 0x0b, 0x8f, 0x38, 0xa7, 0x16, 0x7b, 0xd4, 0xa3, 0xb3, 0x5e,
+  0x2b, 0xe3, 0xae, 0x7d, 0xab, 0xb9, 0x9b, 0xfe, 0xd4, 0x54, 0x57, 0xe6,
+  0xff, 0x00, 0xdf, 0x91, 0x93, 0xaa, 0xfa, 0x0d, 0xef, 0x66, 0x0c, 0xb9,
+  0x93, 0xb5, 0x77, 0x30, 0x97, 0xc8, 0xdb, 0x25, 0xb0, 0x8e, 0x71, 0xbe,
+  0xbe, 0x34, 0xc7, 0x0f, 0x88, 0x16, 0x87, 0x54, 0x03, 0xed, 0x3e, 0xc6,
+  0xfc, 0x48, 0xd8, 0xff, 0x00, 0x0a, 0xab, 0x40, 0x24, 0x80, 0x01, 0x24,
+  0xf7, 0x01, 0x5d, 0x73, 0x6d, 0x97, 0x08, 0x4d, 0x21, 0xd9, 0x51, 0x1d,
+  0x65, 0x0b, 0xf8, 0x2a, 0x52, 0x7a, 0x1a, 0xe3, 0xb6, 0xed, 0xcb, 0xfa,
+  0x5a, 0xa7, 0x1d, 0xd3, 0x79, 0x7b, 0x10, 0xa7, 0x22, 0xea, 0xb7, 0x5d,
+  0x20, 0x5c, 0x51, 0xcf, 0x0e, 0x53, 0x6e, 0x8f, 0x40, 0x3d, 0x47, 0xd5,
+  0x5d, 0x95, 0x41, 0x46, 0x90, 0xfc, 0x67, 0x43, 0xb1, 0xdd, 0x5b, 0x4b,
+  0x1d, 0xca, 0x49, 0xd1, 0xab, 0x07, 0x10, 0xcd, 0xbb, 0x65, 0xa2, 0x15,
+  0xdd, 0x41, 0x2b, 0x3d, 0x10, 0xf7, 0x70, 0x3e, 0xda, 0xfa, 0x5e, 0xcd,
+  0xf6, 0x9a, 0x95, 0xc4, 0x95, 0x3a, 0xeb, 0x4b, 0x7d, 0x7a, 0x7f, 0x83,
+  0x48, 0xd4, 0x4f, 0x91, 0xf2, 0x8a, 0x01, 0x04, 0x6c, 0x1d, 0x83, 0x45,
+  0x7d, 0x41, 0xa0, 0x51, 0x45, 0x14, 0x06, 0x0a, 0x41, 0x3b, 0xa8, 0x7c,
+  0xbf, 0x1b, 0xb3, 0xe5, 0x56, 0x47, 0xac, 0xf7, 0xa8, 0xbe, 0x51, 0x19,
+  0xc5, 0x05, 0xa4, 0xa4, 0xf2, 0xad, 0xa7, 0x13, 0xd5, 0x2e, 0x21, 0x43,
+  0xaa, 0x16, 0x93, 0xd4, 0x28, 0x75, 0x15, 0x33, 0x46, 0xa8, 0x0a, 0x45,
+  0x2e, 0x5d, 0x71, 0x5b, 0xf3, 0x58, 0xae, 0x51, 0x24, 0x4a, 0x32, 0x36,
+  0x2c, 0xf7, 0x52, 0x9e, 0x41, 0x38, 0x24, 0x6c, 0xb4, 0xe0, 0xee, 0x4b,
+  0xe9, 0x03, 0x67, 0x5d, 0x16, 0x3c, 0xe1, 0xae, 0xa2, 0xa7, 0xa9, 0xdb,
+  0x33, 0xc6, 0xed, 0x99, 0x56, 0x3f, 0x2a, 0xcb, 0x74, 0x6d, 0x65, 0x87,
+  0x80, 0x28, 0x71, 0xb5, 0x72, 0xba, 0xcb, 0x89, 0xea, 0x87, 0x1b, 0x50,
+  0xea, 0x95, 0xa4, 0x80, 0xa0, 0x7d, 0x35, 0x57, 0xe3, 0x13, 0x2e, 0x3d,
+  0xa4, 0xeb, 0x05, 0xfb, 0x93, 0xdd, 0xcb, 0x3b, 0x81, 0x89, 0x6a, 0x42,
+  0x42, 0x53, 0x21, 0x24, 0x73, 0x35, 0x21, 0x00, 0x77, 0x25, 0xc4, 0xec,
+  0xeb, 0xc1, 0x41, 0x43, 0xc3, 0x55, 0xe9, 0x5a, 0xd7, 0xd5, 0xdd, 0x97,
+  0x27, 0x9b, 0x73, 0x43, 0x4f, 0x7a, 0x3c, 0x1a, 0x73, 0x3f, 0x8d, 0x62,
+  0xdf, 0xb4, 0xf6, 0xef, 0xbe, 0x15, 0x78, 0x0e, 0xea, 0xa3, 0xb3, 0x3f,
+  0x8d, 0x62, 0xdf, 0xb4, 0xf6, 0xdf, 0xbe, 0x15, 0x78, 0x8e, 0xea, 0xe7,
+  0xbc, 0xfb, 0xcf, 0x91, 0xd1, 0x69, 0xf7, 0x61, 0x45, 0x14, 0x57, 0x29,
+  0xd4, 0x14, 0x9b, 0xc7, 0x2f, 0x91, 0xdc, 0xbb, 0xe8, 0x79, 0x3f, 0x76,
+  0x69, 0xca, 0x93, 0x38, 0xe4, 0x7f, 0xf9, 0x3d, 0x97, 0x74, 0xdf, 0xfa,
+  0x22, 0x4f, 0xdd, 0x9a, 0x01, 0x03, 0x28, 0x12, 0xae, 0x49, 0xb5, 0x62,
+  0x56, 0xd7, 0x96, 0xcc, 0xdb, 0xfb, 0xbe, 0x4c, 0xa7, 0x50, 0x74, 0xa6,
+  0x22, 0xa5, 0x1c, 0xd2, 0x1d, 0x1e, 0x82, 0x10, 0x39, 0x47, 0xeb, 0x2d,
+  0x35, 0x74, 0x5a, 0xa0, 0x44, 0xb6, 0x5b, 0x23, 0x5b, 0x60, 0x30, 0x88,
+  0xf1, 0x22, 0xb4, 0x96, 0x58, 0x69, 0x03, 0xcd, 0x42, 0x12, 0x34, 0x90,
+  0x3d, 0x80, 0x0a, 0xac, 0x78, 0x51, 0x10, 0xdc, 0xf8, 0x87, 0x90, 0xdf,
+  0x1d, 0x4f, 0x33, 0x56, 0x98, 0xac, 0x59, 0xe2, 0x1d, 0xf4, 0x0b, 0x52,
+  0x43, 0xf2, 0x0e, 0xbd, 0x27, 0x99, 0x81, 0xbf, 0xd4, 0xab, 0x60, 0x56,
+  0xf7, 0x35, 0x35, 0xcd, 0xfa, 0x18, 0x5b, 0x43, 0x44, 0x17, 0xa8, 0x01,
+  0xa1, 0xaa, 0x28, 0xa2, 0xb0, 0x37, 0x0a, 0x81, 0xc8, 0xf1, 0xf8, 0xb3,
+  0x41, 0x9a, 0xc3, 0x9e, 0x47, 0x31, 0xa1, 0xcc, 0x97, 0xd1, 0xd3, 0xbb,
+  0xd3, 0x53, 0xd4, 0x9d, 0xc4, 0xfb, 0xb9, 0x87, 0x6d, 0x4d, 0xbd, 0x95,
+  0x69, 0xd9, 0x3f, 0x0b, 0xd4, 0x8a, 0xf3, 0xfb, 0x52, 0x74, 0x69, 0xda,
+  0xca, 0x75, 0x96, 0x52, 0xfa, 0xf4, 0xc1, 0x59, 0x63, 0x1b, 0x89, 0x59,
+  0x06, 0x45, 0x73, 0xb9, 0xb4, 0x88, 0x72, 0x5f, 0x4a, 0x9b, 0x6b, 0xcd,
+  0x25, 0x1d, 0x03, 0x84, 0x78, 0x9a, 0x84, 0xad, 0x91, 0x63, 0xbd, 0x29,
+  0xf4, 0xb3, 0x1d, 0xa5, 0x38, 0xe2, 0xbb, 0x92, 0x91, 0xd4, 0xd7, 0xb9,
+  0xd0, 0xa5, 0x41, 0x7b, 0xb1, 0x96, 0xc2, 0xd9, 0x5e, 0xb7, 0xa5, 0x0d,
+  0x57, 0xe5, 0xd5, 0xaa, 0x56, 0xb8, 0x6e, 0xad, 0x4c, 0xbe, 0x99, 0xfd,
+  0xb2, 0x73, 0xbc, 0xbd, 0xcd, 0x14, 0x51, 0x45, 0x73, 0x10, 0x74, 0x5b,
+  0x24, 0x08, 0x97, 0x06, 0x24, 0xa9, 0x1c, 0xe1, 0xa5, 0x85, 0x14, 0xfa,
+  0x75, 0x4e, 0x19, 0x9e, 0x59, 0x6f, 0xba, 0xd9, 0x84, 0x38, 0x8d, 0x2c,
+  0xad, 0x6a, 0x05, 0x45, 0x69, 0xd7, 0x2e, 0xa9, 0x1e, 0x8a, 0xee, 0xb7,
+  0xed, 0x0a, 0xd6, 0xf4, 0x67, 0x46, 0x1c, 0x4b, 0x92, 0x54, 0x9a, 0x58,
+  0x0a, 0x28, 0x48, 0x2a, 0x3a, 0x00, 0x92, 0x7c, 0x05, 0x30, 0x59, 0xb1,
+  0x3b, 0x9c, 0xf4, 0x87, 0x5d, 0x48, 0x8b, 0x1f, 0xbc, 0xb8, 0xef, 0x4e,
+  0x9e, 0xca, 0xc2, 0x85, 0xb5, 0x5b, 0x89, 0x69, 0xa5, 0x16, 0xd8, 0x49,
+  0xbe, 0x06, 0xae, 0x1a, 0xe4, 0x0a, 0x96, 0xd1, 0xb5, 0x4b, 0x5e, 0xdd,
+  0x6c, 0x6d, 0xa5, 0x1e, 0xf5, 0x27, 0xd1, 0xed, 0xa7, 0x47, 0xdd, 0x6d,
+  0x86, 0x56, 0xf3, 0xcb, 0x4a, 0x1b, 0x40, 0xda, 0x94, 0x4e, 0x80, 0x15,
+  0x5d, 0xc7, 0x93, 0x8c, 0xe3, 0x0e, 0x85, 0xb0, 0xa5, 0xcf, 0x9a, 0x9e,
+  0x9c, 0xe0, 0xf4, 0x4d, 0x4a, 0x71, 0x16, 0xe0, 0x5f, 0xc4, 0xa3, 0xbf,
+  0x15, 0x5e, 0xf3, 0x25, 0x69, 0xe6, 0x23, 0xd1, 0xa2, 0x75, 0xff, 0x00,
+  0xbf, 0x45, 0x7d, 0xf5, 0x8f, 0x68, 0x3b, 0x6b, 0x29, 0x46, 0xac, 0x94,
+  0xa7, 0x4d, 0x70, 0x9e, 0x76, 0xe9, 0x96, 0x6d, 0x19, 0x61, 0x6e, 0x78,
+  0x9f, 0xc4, 0x38, 0x4d, 0x3e, 0x5b, 0x8b, 0x0d, 0xc7, 0xd0, 0x0f, 0xc3,
+  0x2a, 0xe5, 0x07, 0xd8, 0x2a, 0x6f, 0x1a, 0xc9, 0x60, 0x5f, 0x01, 0x43,
+  0x04, 0xb6, 0xfa, 0x46, 0xd4, 0xd2, 0xfb, 0xf5, 0xe9, 0x1e, 0x9a, 0xa6,
+  0x6b, 0xb2, 0xcb, 0x3d, 0xcb, 0x65, 0xd1, 0x89, 0xad, 0x13, 0xb6, 0xd5,
+  0xb2, 0x07, 0x88, 0xf1, 0x1f, 0xdd, 0x5e, 0x0d, 0xaf, 0xb4, 0xf7, 0x4a,
+  0xba, 0x75, 0x9a, 0x71, 0x7c, 0xac, 0x71, 0xf0, 0x28, 0xaa, 0x3c, 0xee,
+  0x5e, 0xb4, 0x56, 0xa8, 0x8f, 0xb7, 0x2a, 0x2b, 0x52, 0x1a, 0x50, 0x53,
+  0x6e, 0x24, 0x29, 0x24, 0x78, 0x83, 0x5b, 0x6b, 0xf4, 0x24, 0xd4, 0x96,
+  0x51, 0xb8, 0x6b, 0xae, 0xea, 0xae, 0xe3, 0x5c, 0x1f, 0x72, 0x2e, 0x16,
+  0x9c, 0xfa, 0x38, 0xe5, 0x4c, 0x25, 0xa6, 0x05, 0xdf, 0x47, 0x41, 0x70,
+  0x9e, 0x58, 0x01, 0x47, 0xfd, 0xd3, 0xa5, 0x0b, 0x1e, 0x80, 0x57, 0xe9,
+  0xab, 0x46, 0xa3, 0xb2, 0x5b, 0x4c, 0x5b, 0xf5, 0x82, 0xe1, 0x64, 0x9a,
+  0x9e, 0x68, 0xd3, 0xe3, 0x39, 0x19, 0xdf, 0x9a, 0xb4, 0x94, 0x9d, 0x7a,
+  0xfa, 0xd5, 0xe3, 0x2d, 0x2d, 0x34, 0x56, 0x51, 0x52, 0x4d, 0x32, 0xa0,
+  0xcc, 0xc1, 0x12, 0xb1, 0x60, 0x7b, 0xc6, 0x4f, 0x6e, 0xfb, 0xe1, 0x57,
+  0x80, 0xee, 0xaf, 0x9b, 0xad, 0xd3, 0xa4, 0xcf, 0xc5, 0x70, 0x57, 0x27,
+  0x12, 0x67, 0x31, 0x92, 0x5b, 0xe2, 0x4b, 0xdf, 0x7f, 0x6e, 0xcc, 0x8e,
+  0xc9, 0xcd, 0xfa, 0xca, 0x90, 0x4f, 0xd7, 0x5f, 0x48, 0x8e, 0xea, 0xde,
+  0xed, 0xea, 0x9a, 0x7e, 0x86, 0x16, 0xab, 0x4c, 0x1a, 0xf5, 0x0a, 0x28,
+  0xa2, 0xb9, 0x8e, 0x90, 0xa4, 0xde, 0x37, 0x8d, 0xf0, 0x7f, 0x2e, 0x1b,
+  0xd7, 0xfa, 0x22, 0x47, 0xdd, 0x9a, 0x72, 0xa4, 0xee, 0x37, 0x74, 0xe1,
+  0x06, 0x5c, 0x7d, 0x16, 0x89, 0x1f, 0x76, 0x68, 0x08, 0x8f, 0xc1, 0xcd,
+  0x21, 0xee, 0x1b, 0x0b, 0xc7, 0x4e, 0xd2, 0xef, 0x73, 0x9b, 0x35, 0x64,
+  0x7a, 0xe4, 0x2d, 0x09, 0xff, 0x00, 0xa1, 0x08, 0x15, 0x64, 0x55, 0x7b,
+  0xf8, 0x37, 0xa5, 0x23, 0x81, 0xb8, 0x98, 0x1e, 0x30, 0x42, 0x8f, 0xb4,
+  0xad, 0x44, 0xff, 0x00, 0x89, 0x35, 0x61, 0x51, 0xee, 0xf2, 0x42, 0xd8,
+  0x28, 0xa2, 0x8a, 0x12, 0x15, 0x4e, 0xf1, 0x02, 0x62, 0xa5, 0xe4, 0xf2,
+  0x7c, 0xe2, 0x52, 0xc9, 0xec, 0xd2, 0x3d, 0x1a, 0xab, 0x88, 0xf7, 0x55,
+  0x17, 0x7e, 0x25, 0x57, 0xa9, 0xa4, 0xf7, 0xf6, 0xea, 0xfb, 0x6b, 0xe4,
+  0xfd, 0xad, 0xa8, 0xe3, 0x6f, 0x08, 0x2e, 0xaf, 0xe8, 0x8c, 0xaa, 0xf0,
+  0x76, 0xe1, 0x97, 0x76, 0x6c, 0xd7, 0x94, 0xca, 0x90, 0xd9, 0x5b, 0x65,
+  0x25, 0x27, 0x97, 0xbc, 0x6f, 0xc6, 0xbb, 0x33, 0xdb, 0xf4, 0x5b, 0xdc,
+  0x96, 0x3c, 0x91, 0xb5, 0x04, 0x34, 0x0f, 0x9e, 0xa1, 0xa2, 0x77, 0x4b,
+  0x34, 0x57, 0xc7, 0xc7, 0xb4, 0x2b, 0x46, 0xd5, 0xda, 0xaf, 0x0b, 0x79,
+  0x32, 0xd4, 0xf1, 0x80, 0xa2, 0xbd, 0xb2, 0xd3, 0xaf, 0x38, 0x1b, 0x65,
+  0xb5, 0x38, 0xb3, 0xdc, 0x12, 0x36, 0x69, 0x9a, 0xd9, 0x87, 0x48, 0x53,
+  0x42, 0x4d, 0xd9, 0xf4, 0x41, 0x8e, 0x3a, 0x9e, 0x63, 0xe7, 0x1a, 0xce,
+  0xda, 0xce, 0xb5, 0xcb, 0xc5, 0x28, 0xe7, 0xe9, 0xf3, 0x61, 0x26, 0xc5,
+  0x74, 0x21, 0x6e, 0x28, 0x25, 0x09, 0x2a, 0x51, 0xee, 0x00, 0x6e, 0x99,
+  0x2d, 0x18, 0x7c, 0xf9, 0x2d, 0x89, 0x13, 0x54, 0x98, 0x51, 0xfb, 0xca,
+  0x9c, 0x3a, 0x3a, 0xf6, 0x54, 0x83, 0x97, 0xcb, 0x05, 0x89, 0x05, 0xab,
+  0x2c, 0x31, 0x25, 0xf1, 0xd0, 0xbe, 0xe0, 0xe9, 0x4b, 0x77, 0x7b, 0xdd,
+  0xca, 0xe8, 0xe1, 0x54, 0xb9, 0x2b, 0x52, 0x7c, 0x10, 0x0e, 0x92, 0x3e,
+  0xaa, 0xed, 0xf7, 0x36, 0x76, 0xbf, 0x7b, 0x2f, 0x79, 0x2f, 0x28, 0xf1,
+  0xf3, 0x7d, 0x7e, 0x44, 0xe1, 0x21, 0x94, 0xdc, 0x71, 0x9c, 0x78, 0x72,
+  0xdb, 0xd8, 0xf7, 0x42, 0x58, 0xfe, 0x95, 0x7f, 0x04, 0x1a, 0x5f, 0xbc,
+  0xe4, 0x57, 0x4b, 0xa2, 0x88, 0x7e, 0x41, 0x43, 0x5e, 0x0d, 0xa3, 0xa2,
+  0x45, 0x44, 0xd1, 0x58, 0x57, 0xed, 0x2a, 0xd5, 0x63, 0xee, 0xe3, 0xdd,
+  0x8f, 0x92, 0xd9, 0x7c, 0xfc, 0xfe, 0x64, 0x39, 0x36, 0x14, 0xed, 0x87,
+  0x38, 0x8b, 0xd6, 0x39, 0x37, 0x1d, 0x7d, 0x43, 0xb4, 0x4a, 0x7b, 0x48,
+  0xe4, 0xf8, 0x1f, 0xff, 0x00, 0xdf, 0xfb, 0xd2, 0x4d, 0x77, 0x58, 0x2e,
+  0x0e, 0x5b, 0x2e, 0xcc, 0x4c, 0x6c, 0xfc, 0x05, 0x79, 0xc3, 0xd2, 0x3c,
+  0x45, 0x57, 0xb3, 0xae, 0x55, 0xbd, 0x74, 0xe7, 0xe1, 0x7b, 0x3f, 0x83,
+  0xe4, 0x45, 0xe1, 0x9c, 0x6e, 0xb6, 0xb6, 0x9d, 0x5b, 0x4e, 0x24, 0xa5,
+  0x68, 0x51, 0x4a, 0x81, 0xf0, 0x23, 0xbc, 0x57, 0x9a, 0x6a, 0xe2, 0x35,
+  0xbd, 0xb6, 0xae, 0x0d, 0x5d, 0x62, 0xf5, 0x8d, 0x39, 0x21, 0x7b, 0x1e,
+  0x0a, 0xd7, 0xfd, 0xc7, 0xfd, 0xe9, 0x56, 0xb2, 0xbc, 0xb6, 0x76, 0xd5,
+  0xa5, 0x49, 0xf4, 0xfd, 0x57, 0x47, 0xf9, 0x06, 0xb0, 0xf0, 0x59, 0x7c,
+  0x2b, 0xbb, 0x76, 0xf0, 0x1c, 0xb5, 0xba, 0xad, 0xad, 0x8f, 0x39, 0xbd,
+  0xf8, 0xa4, 0xff, 0x00, 0xe0, 0xff, 0x00, 0xda, 0x9d, 0xaa, 0x8e, 0xc7,
+  0x2e, 0x4b, 0xb5, 0x5e, 0x18, 0x98, 0x92, 0x79, 0x52, 0xad, 0x2c, 0x7a,
+  0x52, 0x7b, 0xea, 0xee, 0x65, 0xc4, 0x3c, 0xca, 0x1d, 0x6c, 0x85, 0x21,
+  0x60, 0x10, 0x47, 0x88, 0xaf, 0xbe, 0xf6, 0x6a, 0xfb, 0xed, 0x16, 0xbe,
+  0xea, 0x4f, 0xbd, 0x0d, 0xbe, 0x5d, 0x3f, 0x83, 0x6a, 0x72, 0xca, 0x3d,
+  0xd6, 0x08, 0xeb, 0x59, 0xa3, 0x55, 0xf4, 0x66, 0x87, 0xce, 0x37, 0x58,
+  0xc2, 0xdb, 0x9b, 0xcf, 0xb5, 0x05, 0xf3, 0x06, 0xf8, 0x8b, 0x6f, 0x96,
+  0x9f, 0x52, 0x64, 0x86, 0x5e, 0x3f, 0xf5, 0x29, 0x75, 0xf4, 0x70, 0xee,
+  0xaf, 0x9e, 0x33, 0x51, 0xae, 0x33, 0xdc, 0xff, 0x00, 0x6a, 0x71, 0xd3,
+  0xf5, 0xf2, 0x01, 0xff, 0x00, 0x8a, 0xfa, 0x1c, 0x77, 0x56, 0x93, 0x79,
+  0xc7, 0xc0, 0xce, 0x1c, 0xbf, 0x8f, 0xf0, 0x14, 0x51, 0x45, 0x66, 0x68,
+  0x14, 0x9b, 0xc6, 0xf3, 0xae, 0x10, 0x65, 0xa7, 0xff, 0x00, 0x48, 0x91,
+  0xf7, 0x66, 0x9c, 0xa9, 0x33, 0x8e, 0x5f, 0x23, 0xb9, 0x77, 0xd0, 0xf2,
+  0x7e, 0xec, 0xd0, 0x11, 0x9f, 0x83, 0x79, 0x2d, 0xf0, 0x82, 0xd5, 0x05,
+  0x67, 0xdf, 0x60, 0x3f, 0x2e, 0x1b, 0xa0, 0xf7, 0x82, 0xdc, 0x97, 0x53,
+  0xaf, 0xee, 0x03, 0xfb, 0xea, 0xc6, 0xaa, 0xb7, 0x82, 0xb2, 0xbc, 0x87,
+  0x22, 0xcb, 0x31, 0xb7, 0x34, 0x92, 0x64, 0xb5, 0x78, 0x8f, 0xb3, 0xf0,
+  0x9b, 0x90, 0xd8, 0x4a, 0xf4, 0x3d, 0x01, 0xd6, 0x9c, 0xff, 0x00, 0x98,
+  0x7a, 0x6a, 0xd2, 0x1d, 0xd5, 0x69, 0xad, 0x32, 0x68, 0xac, 0x25, 0xaa,
+  0x29, 0x85, 0x14, 0x51, 0x55, 0x2c, 0x15, 0x4a, 0xe6, 0x71, 0x8c, 0x4c,
+  0x9a, 0x6b, 0x44, 0x10, 0x0b, 0x9c, 0xc3, 0xd8, 0x7a, 0xd5, 0xd5, 0x4a,
+  0xd9, 0x8d, 0x86, 0xd7, 0x26, 0x4a, 0x6e, 0xd7, 0x17, 0xd4, 0xcb, 0x4d,
+  0x23, 0x95, 0xce, 0x51, 0xf0, 0xbd, 0x15, 0xe0, 0xfb, 0x43, 0x61, 0x2b,
+  0xcb, 0x65, 0xa3, 0x98, 0xbc, 0xef, 0xb6, 0xdd, 0x4a, 0x4e, 0x39, 0x45,
+  0x59, 0x16, 0x34, 0x89, 0x4e, 0x86, 0xa3, 0xb2, 0xb7, 0x56, 0x7b, 0x82,
+  0x46, 0xe9, 0xa6, 0x06, 0x1e, 0x19, 0x68, 0x4a, 0xbe, 0xcb, 0x6e, 0x1b,
+  0x3d, 0xfc, 0x9b, 0xf3, 0x8d, 0x7b, 0x97, 0x96, 0x43, 0xb7, 0xb4, 0x63,
+  0x63, 0xd0, 0x50, 0xca, 0x7b, 0xbb, 0x65, 0x8f, 0x38, 0xfa, 0xe9, 0x5a,
+  0x7c, 0xe9, 0x73, 0x9e, 0x2e, 0xcb, 0x90, 0xb7, 0x54, 0x7f, 0x48, 0xd7,
+  0xc5, 0x62, 0xca, 0xd7, 0x9f, 0xee, 0xcb, 0xf2, 0x8f, 0xf2, 0xcc, 0x76,
+  0x43, 0x5b, 0xf9, 0x2d, 0xa6, 0xd0, 0xd9, 0x63, 0x1f, 0x82, 0x92, 0xbe,
+  0xe2, 0xfb, 0x83, 0xad, 0x2c, 0x5c, 0xee, 0x93, 0xee, 0x4e, 0x97, 0x26,
+  0x49, 0x5b, 0x87, 0xd1, 0xbe, 0x83, 0xea, 0xae, 0x3a, 0x2b, 0x9a, 0xe7,
+  0xb4, 0x2b, 0xdc, 0x2d, 0x2d, 0xe2, 0x3e, 0x4b, 0x65, 0xf9, 0x10, 0xe4,
+  0xd8, 0x51, 0x45, 0x15, 0xc2, 0x40, 0x51, 0x45, 0x14, 0x01, 0x45, 0x14,
+  0x50, 0x0f, 0x18, 0xe2, 0x86, 0x41, 0x88, 0xca, 0xb2, 0x38, 0x41, 0x93,
+  0x18, 0x76, 0x91, 0xc9, 0xff, 0x00, 0x0f, 0xfc, 0x7d, 0x74, 0x8e, 0xa0,
+  0x52, 0xa2, 0x95, 0x02, 0x08, 0x3a, 0x20, 0xf8, 0x54, 0x9e, 0x2f, 0x73,
+  0x55, 0xaa, 0xf4, 0xc4, 0xa0, 0x4f, 0x20, 0x57, 0x2b, 0x83, 0xd2, 0x93,
+  0xdf, 0x52, 0x5c, 0x42, 0xb6, 0x26, 0x1d, 0xe0, 0x4c, 0x8e, 0x37, 0x1a,
+  0x6a, 0x7b, 0x54, 0x11, 0xdd, 0xbf, 0x1f, 0xfc, 0xfd, 0x75, 0xec, 0x57,
+  0xff, 0x00, 0x95, 0x67, 0x1a, 0xdf, 0x8a, 0x9f, 0x75, 0xfc, 0x3f, 0x0b,
+  0xfd, 0xbf, 0x22, 0xcf, 0x75, 0x91, 0x6a, 0xad, 0x2e, 0x18, 0x5d, 0xbc,
+  0xb2, 0xd0, 0x60, 0x3a, 0xad, 0xbb, 0x17, 0xa2, 0x77, 0xe2, 0x83, 0xdd,
+  0xfd, 0xdd, 0xd5, 0x56, 0xd4, 0xc6, 0x19, 0x71, 0x5d, 0xb7, 0x21, 0x8c,
+  0xea, 0x49, 0xe4, 0x71, 0x41, 0xb7, 0x07, 0xa4, 0x13, 0xaf, 0xfc, 0x1a,
+  0xaf, 0x62, 0xde, 0xbb, 0x3b, 0xb8, 0xc9, 0xf0, 0xf6, 0x7f, 0x07, 0xfc,
+  0x08, 0x3c, 0x32, 0xe9, 0xac, 0x13, 0xaa, 0xcd, 0x68, 0x9b, 0x25, 0x98,
+  0x91, 0x9e, 0x95, 0x25, 0xc4, 0xb4, 0xc3, 0x2d, 0xa9, 0xc7, 0x16, 0xa3,
+  0xa0, 0x94, 0xa4, 0x6c, 0x93, 0xec, 0x15, 0xfa, 0xa1, 0xd2, 0x7c, 0xf9,
+  0x92, 0x3c, 0xdc, 0xde, 0x27, 0x5c, 0xee, 0x0c, 0xab, 0x99, 0x07, 0x3b,
+  0xb3, 0xc3, 0xdf, 0xeb, 0x32, 0xdb, 0x01, 0x5f, 0xf5, 0x28, 0xd7, 0xd1,
+  0x43, 0xba, 0xbe, 0x69, 0xb3, 0xa1, 0xd7, 0x71, 0xfc, 0x56, 0xef, 0x25,
+  0xb2, 0xdc, 0x9b, 0xde, 0x63, 0x16, 0xec, 0xf2, 0x7d, 0x06, 0x44, 0xa2,
+  0xb4, 0x8f, 0xa9, 0x05, 0x03, 0xea, 0xaf, 0xa5, 0x85, 0x6b, 0x56, 0x3a,
+  0x70, 0xbd, 0x0c, 0x68, 0xcb, 0x56, 0x5f, 0xa8, 0x51, 0x45, 0x15, 0x91,
+  0xb0, 0x52, 0x67, 0x1c, 0xbe, 0x47, 0x72, 0xef, 0xa1, 0xe4, 0xfd, 0xd9,
+  0xa7, 0x3a, 0x4c, 0xe3, 0x91, 0xd7, 0x07, 0x72, 0xfd, 0xf7, 0x7b, 0x91,
+  0x27, 0xee, 0xcd, 0x00, 0x83, 0x74, 0x98, 0x31, 0x9c, 0x8e, 0xc3, 0x9a,
+  0x95, 0x72, 0x44, 0x86, 0x0c, 0x1b, 0xa9, 0x1e, 0x10, 0xde, 0x29, 0xf7,
+  0xc5, 0x78, 0xe9, 0xb7, 0x03, 0x6b, 0xf9, 0xbc, 0xf5, 0x78, 0xa7, 0xb8,
+  0x55, 0x65, 0x1a, 0xd0, 0xf5, 0xde, 0x12, 0xa2, 0x18, 0x7e, 0x53, 0x1d,
+  0xe6, 0xbb, 0x37, 0x50, 0xe0, 0xd2, 0x16, 0x92, 0x34, 0x52, 0x49, 0xf0,
+  0x20, 0x91, 0x5d, 0x5c, 0x36, 0x9f, 0x37, 0x19, 0x9c, 0x9e, 0x1c, 0xe4,
+  0x6f, 0xf3, 0xbf, 0x19, 0x92, 0xbb, 0x1c, 0xc5, 0x9d, 0xf9, 0x7c, 0x34,
+  0xfe, 0x66, 0xfc, 0x5e, 0x6b, 0xa2, 0x54, 0x3b, 0xca, 0x79, 0x55, 0xd7,
+  0x6a, 0xd7, 0x5d, 0xdc, 0x62, 0xa5, 0x94, 0xce, 0x4b, 0x49, 0x4b, 0x4e,
+  0x1a, 0xe0, 0xb0, 0xea, 0x37, 0x23, 0xbb, 0xb3, 0x65, 0xb6, 0x2e, 0x63,
+  0xc3, 0x98, 0x8e, 0x88, 0x46, 0xf5, 0xcc, 0xaf, 0x45, 0x49, 0x0a, 0x4a,
+  0xe2, 0xd3, 0x2e, 0xae, 0xd5, 0x15, 0xd4, 0x6c, 0xa1, 0x0e, 0x9e, 0x7d,
+  0x7a, 0xc7, 0x4a, 0xf1, 0xbb, 0x4e, 0xe2, 0x76, 0xf6, 0x93, 0xab, 0x4f,
+  0x94, 0x8e, 0xa9, 0x3c, 0x21, 0x5a, 0x5e, 0x69, 0x7e, 0x7d, 0xf2, 0xe2,
+  0x25, 0x06, 0x53, 0xbe, 0x88, 0x42, 0x46, 0xa9, 0x8b, 0x1b, 0xc8, 0x7f,
+  0x94, 0x71, 0x9e, 0xb2, 0x5d, 0x12, 0x8e, 0xd9, 0xc6, 0xc8, 0x42, 0xc0,
+  0xd0, 0x57, 0xff, 0x00, 0xba, 0xae, 0xab, 0x7d, 0xbe, 0x53, 0x90, 0xa6,
+  0xb3, 0x2d, 0xa3, 0xa5, 0xb4, 0xb0, 0xa1, 0x5f, 0x9d, 0x5a, 0xf6, 0xc5,
+  0xcd, 0x3a, 0xba, 0xaa, 0xcd, 0xca, 0x2f, 0x94, 0xf7, 0xca, 0xea, 0x73,
+  0xa9, 0xbc, 0xee, 0x17, 0x08, 0xae, 0x42, 0x9a, 0xf4, 0x57, 0x46, 0x96,
+  0xd2, 0x8a, 0x4d, 0x68, 0xa7, 0x1e, 0x20, 0x45, 0x6e, 0x5c, 0x78, 0x99,
+  0x04, 0x50, 0x0b, 0x72, 0x10, 0x03, 0x9a, 0xf0, 0x55, 0x27, 0x57, 0x25,
+  0xf5, 0xb7, 0xd9, 0xab, 0xca, 0x9a, 0xe3, 0x95, 0xea, 0x9f, 0x04, 0x49,
+  0x61, 0x85, 0x14, 0x51, 0x5c, 0x64, 0x05, 0x14, 0x51, 0x40, 0x14, 0x51,
+  0x45, 0x00, 0x51, 0x45, 0x14, 0x01, 0x4f, 0x56, 0x84, 0xff, 0x00, 0x29,
+  0xf0, 0xb7, 0x2d, 0xa4, 0x83, 0x36, 0x11, 0xe6, 0x64, 0x9e, 0xf2, 0x3c,
+  0x07, 0xda, 0x3e, 0xb1, 0x48, 0xb5, 0x33, 0x86, 0xdd, 0x0d, 0xa6, 0xfa,
+  0xcb, 0xe4, 0x9e, 0xc9, 0x67, 0x91, 0xc1, 0xea, 0x35, 0xe9, 0x76, 0x65,
+  0x78, 0x52, 0xad, 0xa2, 0xa7, 0x82, 0x7d, 0xd7, 0xf0, 0x7d, 0x7e, 0x5c,
+  0x96, 0x8b, 0xc3, 0x22, 0xa4, 0xc7, 0x7a, 0x33, 0xca, 0x65, 0xf6, 0x94,
+  0xdb, 0x89, 0x3a, 0x29, 0x50, 0xd5, 0x32, 0xf0, 0xff, 0x00, 0x1f, 0x7e,
+  0xe3, 0x74, 0x6e, 0x6b, 0xc8, 0x28, 0x89, 0x1d, 0x41, 0x44, 0x91, 0xf0,
+  0xd4, 0x3b, 0x92, 0x3f, 0xef, 0x56, 0x83, 0xd0, 0xe1, 0x4a, 0xe5, 0x71,
+  0xd8, 0xcc, 0xbb, 0xe2, 0x14, 0xa4, 0x03, 0x5b, 0x9b, 0x42, 0x1b, 0x40,
+  0x43, 0x68, 0x4a, 0x12, 0x3b, 0x82, 0x46, 0x80, 0xaf, 0xab, 0xb4, 0xf6,
+  0x5a, 0x14, 0xab, 0xaa, 0x93, 0x9e, 0xa8, 0xad, 0xd2, 0xc7, 0xd4, 0xd1,
+  0x53, 0xc3, 0x3d, 0x55, 0x75, 0xc7, 0x7b, 0x82, 0xd7, 0x8e, 0x47, 0xc4,
+  0x22, 0x3a, 0x51, 0x37, 0x25, 0x7b, 0xc8, 0xc9, 0x49, 0xf3, 0x9b, 0x88,
+  0x00, 0x54, 0xa7, 0x3d, 0x81, 0xbd, 0xa3, 0xda, 0xe2, 0x69, 0xea, 0xf1,
+  0x72, 0x83, 0x67, 0xb5, 0xca, 0xba, 0x5c, 0xa5, 0x37, 0x16, 0x14, 0x46,
+  0x94, 0xf3, 0xef, 0x38, 0x74, 0x94, 0x21, 0x23, 0x64, 0x93, 0x54, 0xed,
+  0x95, 0xc9, 0xb9, 0x0d, 0xfe, 0x6e, 0x6f, 0x75, 0x8c, 0xe4, 0x77, 0xa6,
+  0xb6, 0x23, 0xdb, 0x62, 0x3a, 0x34, 0xb8, 0x70, 0x41, 0xda, 0x42, 0xc7,
+  0x83, 0x8e, 0x1f, 0x3d, 0x43, 0xbc, 0x6d, 0x29, 0xfc, 0xda, 0xfb, 0x3a,
+  0x14, 0x9d, 0x49, 0xe0, 0x8a, 0xd5, 0x55, 0x38, 0xe7, 0xa9, 0xa7, 0x2e,
+  0x43, 0x6d, 0x3d, 0x8a, 0xb4, 0xd2, 0x02, 0x1b, 0x4e, 0x4b, 0x6d, 0x4a,
+  0x52, 0x06, 0x82, 0x40, 0x78, 0x68, 0x0f, 0x65, 0x5e, 0x63, 0xba, 0xa8,
+  0xec, 0xcb, 0xe3, 0x38, 0xb7, 0x7f, 0xfa, 0xcf, 0x6e, 0xfb, 0xe1, 0x57,
+  0x88, 0xee, 0xad, 0x2f, 0x3e, 0xf3, 0xe4, 0x67, 0x67, 0xf7, 0x61, 0x45,
+  0x14, 0x57, 0x29, 0xd4, 0x14, 0x99, 0xc7, 0x1f, 0x91, 0xec, 0xb7, 0xe8,
+  0x89, 0x1f, 0xc0, 0x69, 0xce, 0x93, 0x38, 0xe3, 0xf2, 0x3d, 0x97, 0x7d,
+  0x11, 0x23, 0xf8, 0x0d, 0x00, 0xdb, 0x11, 0x09, 0x4c, 0x56, 0x92, 0x90,
+  0x00, 0x09, 0x1d, 0x00, 0xa8, 0x5c, 0xe7, 0x17, 0x81, 0x95, 0xd9, 0xc4,
+  0x09, 0x6b, 0x76, 0x3b, 0xec, 0xb8, 0x99, 0x10, 0x66, 0xb2, 0x74, 0xf4,
+  0x39, 0x09, 0xf8, 0x0e, 0xb6, 0x7f, 0x48, 0x1f, 0x0e, 0xe2, 0x36, 0x08,
+  0x20, 0x9a, 0x9c, 0x8d, 0xf1, 0x76, 0xfe, 0x60, 0xfb, 0x2b, 0x61, 0x1b,
+  0xa0, 0x11, 0xf1, 0x3c, 0xb6, 0x74, 0x7b, 0xab, 0x78, 0x96, 0x6c, 0xdb,
+  0x30, 0xaf, 0xda, 0x3e, 0x47, 0x29, 0x03, 0x96, 0x35, 0xd9, 0x03, 0xf3,
+  0xd9, 0x27, 0xb9, 0xc0, 0x3a, 0xa9, 0xa3, 0xe7, 0x0e, 0xa4, 0x6d, 0x3d,
+  0x69, 0xbe, 0xe1, 0x12, 0x3d, 0xc2, 0x13, 0x91, 0x24, 0xa0, 0x2d, 0xa7,
+  0x06, 0x88, 0xae, 0x3c, 0x9b, 0x1f, 0xb3, 0xe4, 0x96, 0x87, 0x2d, 0x57,
+  0xb8, 0x2d, 0xcc, 0x88, 0xb2, 0x15, 0xc8, 0xad, 0x82, 0x85, 0x0e, 0xe5,
+  0xa1, 0x43, 0xaa, 0x14, 0x3b, 0xc2, 0x92, 0x41, 0x07, 0xba, 0x93, 0xfb,
+  0x4c, 0xd7, 0x05, 0x46, 0x9f, 0x4c, 0xbc, 0xd3, 0x1e, 0x47, 0x73, 0xad,
+  0x80, 0x6e, 0xb1, 0x13, 0xd7, 0xe1, 0x27, 0xa2, 0x64, 0xa4, 0x00, 0x3a,
+  0x8e, 0x57, 0x3d, 0x4b, 0x3d, 0x4d, 0x65, 0x15, 0x24, 0xe3, 0x25, 0x94,
+  0xc1, 0x1d, 0x91, 0xe1, 0x17, 0x1b, 0x79, 0x53, 0xf0, 0x42, 0xa6, 0xc6,
+  0xef, 0xf3, 0x47, 0xbe, 0x27, 0xda, 0x3c, 0x7d, 0xa2, 0x95, 0x08, 0x20,
+  0x90, 0x41, 0x04, 0x74, 0x20, 0xd5, 0xd1, 0x8a, 0xe4, 0xf6, 0x2c, 0xa2,
+  0x07, 0x97, 0x58, 0xae, 0x6c, 0x4d, 0x69, 0x27, 0x95, 0xc0, 0x82, 0x43,
+  0x8c, 0xab, 0xf4, 0x5c, 0x41, 0xd2, 0x90, 0xaf, 0xd5, 0x50, 0x07, 0xd5,
+  0x5e, 0xaf, 0x58, 0xed, 0xa2, 0xef, 0xb5, 0x4a, 0x8a, 0x90, 0xef, 0xf5,
+  0xad, 0xf9, 0xab, 0xfe, 0xf1, 0xdf, 0xf5, 0xee, 0xbe, 0x46, 0xff, 0x00,
+  0xd9, 0x58, 0xcd, 0xb9, 0xda, 0xcb, 0x1e, 0x8f, 0x8f, 0x93, 0x32, 0x95,
+  0x3f, 0x21, 0x27, 0x06, 0x7d, 0xbb, 0xa5, 0xa2, 0x66, 0x3b, 0x24, 0xef,
+  0x99, 0x25, 0x6c, 0x6f, 0xc0, 0xd2, 0x7c, 0xa6, 0x1c, 0x8d, 0x25, 0xc6,
+  0x1d, 0x1a, 0x5b, 0x6a, 0x29, 0x22, 0xac, 0x04, 0x61, 0x13, 0xad, 0x77,
+  0x26, 0x67, 0xda, 0x26, 0xa1, 0xde, 0xc9, 0x7b, 0xec, 0xdd, 0x1c, 0xaa,
+  0x23, 0xc4, 0x6c, 0x74, 0x3f, 0xe1, 0x5c, 0x5c, 0x48, 0xb1, 0xc9, 0xf2,
+  0xe4, 0x5c, 0xe3, 0x45, 0x71, 0x49, 0x79, 0x3e, 0xfc, 0x10, 0x92, 0xae,
+  0x55, 0x7a, 0xf5, 0x5e, 0x55, 0xef, 0x67, 0x5c, 0xfd, 0x8d, 0x3a, 0xb0,
+  0x7a, 0xa9, 0xed, 0xe7, 0x98, 0xbe, 0x38, 0xf2, 0x7f, 0xa1, 0x57, 0x17,
+  0x8d, 0xc4, 0x8a, 0x28, 0x20, 0x82, 0x41, 0x04, 0x11, 0xe0, 0x68, 0xaf,
+  0x9a, 0x33, 0x0a, 0x28, 0xa2, 0x80, 0x28, 0xa2, 0xbd, 0x34, 0xd3, 0x8f,
+  0x2c, 0x21, 0xa6, 0xd6, 0xe2, 0x8f, 0x72, 0x52, 0x9d, 0x9a, 0x94, 0x9b,
+  0xd9, 0x03, 0xcd, 0x15, 0x39, 0x6f, 0xc4, 0xaf, 0xf3, 0x48, 0x29, 0x80,
+  0xb6, 0x50, 0x7f, 0x39, 0xff, 0x00, 0x33, 0x5f, 0x51, 0xeb, 0xfe, 0x14,
+  0xd3, 0x69, 0xe1, 0xdb, 0x28, 0x21, 0x77, 0x49, 0xa5, 0xc3, 0xe2, 0xdb,
+  0x03, 0x43, 0xfe, 0x63, 0xd4, 0xff, 0x00, 0x70, 0xaf, 0x4e, 0xdb, 0xb1,
+  0xaf, 0x6e, 0x5f, 0x76, 0x9b, 0x4b, 0xcd, 0xec, 0xbf, 0x5f, 0xd8, 0xb2,
+  0x83, 0x65, 0x7d, 0x16, 0x3b, 0xf2, 0x9f, 0x4b, 0x11, 0x99, 0x5b, 0xce,
+  0xab, 0xb9, 0x28, 0x4e, 0xc9, 0xa7, 0xbc, 0x67, 0x02, 0x51, 0x52, 0x24,
+  0xde, 0xd5, 0xca, 0x06, 0x88, 0x8e, 0x85, 0x75, 0x3f, 0x38, 0x8f, 0xb0,
+  0x7f, 0x7d, 0x3b, 0xdb, 0x2d, 0x90, 0x2d, 0x8c, 0xf6, 0x50, 0x62, 0xb6,
+  0xc2, 0x7c, 0x4a, 0x47, 0x53, 0xed, 0x3d, 0xe7, 0xeb, 0xae, 0xa2, 0x48,
+  0xaf, 0xad, 0xec, 0xff, 0x00, 0x66, 0x28, 0xd1, 0x6a, 0x77, 0x0f, 0x53,
+  0xf2, 0xe9, 0xfe, 0x7f, 0xdd, 0x8d, 0x63, 0x4d, 0x2e, 0x41, 0xb4, 0x25,
+  0xb6, 0xd2, 0xda, 0x12, 0x12, 0x94, 0x80, 0x12, 0x07, 0x70, 0x02, 0xb9,
+  0x6e, 0xd7, 0x18, 0x36, 0x9b, 0x74, 0x8b, 0x95, 0xca, 0x5b, 0x10, 0xe1,
+  0x46, 0x6c, 0xb8, 0xfb, 0xef, 0x2c, 0x25, 0x0d, 0xa4, 0x77, 0x92, 0x4f,
+  0x41, 0x4b, 0x79, 0x46, 0x7d, 0x6c, 0xb5, 0x5c, 0x7d, 0xc4, 0xb5, 0xc7,
+  0x7f, 0x20, 0xc8, 0x54, 0x3c, 0xcb, 0x5d, 0xbf, 0x4b, 0x71, 0x1e, 0x85,
+  0x3c, 0xb2, 0x79, 0x18, 0x47, 0x77, 0x9c, 0xb2, 0x3d, 0x41, 0x47, 0xa5,
+  0x70, 0x5b, 0xf0, 0xeb, 0xa5, 0xfe, 0xe6, 0xc5, 0xef, 0x88, 0x72, 0x62,
+  0xcd, 0x5c, 0x77, 0x03, 0xb0, 0xac, 0xb1, 0x49, 0x30, 0x21, 0xac, 0x1f,
+  0x35, 0x6a, 0xe6, 0x00, 0xbe, 0xe8, 0xfd, 0x25, 0x00, 0x94, 0x9f, 0x82,
+  0x90, 0x7a, 0xd7, 0xd4, 0xf0, 0x68, 0x72, 0x44, 0x8b, 0x33, 0x89, 0x37,
+  0x18, 0xd7, 0x7b, 0xc4, 0x57, 0xe0, 0xe2, 0x11, 0x1e, 0x43, 0xf6, 0xeb,
+  0x73, 0xc9, 0x28, 0x76, 0xe8, 0xea, 0x4e, 0xd3, 0x21, 0xf4, 0x9e, 0xa9,
+  0x65, 0x24, 0x02, 0xdb, 0x67, 0xaa, 0x88, 0xe7, 0x5e, 0x86, 0x93, 0x4e,
+  0xf7, 0x3b, 0x34, 0x19, 0xe9, 0xdb, 0x8d, 0xf2, 0x39, 0xe0, 0xb4, 0x74,
+  0x23, 0xff, 0x00, 0x35, 0x22, 0x00, 0xd5, 0x1a, 0x1a, 0xa9, 0x8c, 0x9c,
+  0x5e, 0x51, 0x59, 0x45, 0x49, 0x61, 0x95, 0x17, 0x12, 0xec, 0xd2, 0x6d,
+  0xd2, 0x31, 0x67, 0x54, 0xa4, 0xb8, 0xc9, 0xca, 0x2d, 0xa0, 0x2c, 0x74,
+  0x23, 0xdf, 0x87, 0x78, 0xab, 0x78, 0x77, 0x52, 0x27, 0x19, 0x47, 0xf3,
+  0x2c, 0x5f, 0xf6, 0xaa, 0xd9, 0xf7, 0xe2, 0x9e, 0xea, 0xd5, 0x2a, 0x4a,
+  0xa3, 0xcc, 0x88, 0xa7, 0x4d, 0x53, 0x58, 0x41, 0x45, 0x79, 0x24, 0x83,
+  0xa0, 0x01, 0xfa, 0xe8, 0xaa, 0x17, 0x3d, 0x52, 0x67, 0x1c, 0x7e, 0x47,
+  0xb2, 0xef, 0xa2, 0x24, 0x7f, 0x01, 0xa7, 0x3a, 0x4c, 0xe3, 0x8f, 0xc8,
+  0xf6, 0x5d, 0xf4, 0x44, 0x8f, 0xe0, 0x34, 0x03, 0x7c, 0x6f, 0x8b, 0xb7,
+  0xf3, 0x07, 0xd9, 0x5b, 0x2b, 0x5c, 0x6f, 0x8b, 0xb7, 0xf3, 0x07, 0xd9,
+  0x5b, 0x28, 0x03, 0x5d, 0x68, 0xd5, 0x14, 0x50, 0x0a, 0xd9, 0x3e, 0x07,
+  0x8e, 0xdf, 0xa7, 0x7b, 0xa6, 0xe4, 0x77, 0xad, 0xf7, 0x74, 0x8d, 0x22,
+  0xe9, 0x6e, 0x78, 0xc6, 0x96, 0x9f, 0x57, 0x68, 0x8d, 0x15, 0x0f, 0xd5,
+  0x5f, 0x32, 0x7d, 0x55, 0x14, 0x22, 0xf1, 0x37, 0x1e, 0xf8, 0x94, 0xfb,
+  0x5e, 0x63, 0x0d, 0x00, 0xe9, 0xa9, 0xc3, 0xc8, 0x66, 0x81, 0xe0, 0x03,
+  0xa8, 0x49, 0x69, 0x67, 0xda, 0x84, 0x7b, 0x7c, 0x69, 0xf7, 0x5d, 0x77,
+  0x47, 0x28, 0xa0, 0x11, 0x07, 0x13, 0x6d, 0xd6, 0xf0, 0x53, 0x95, 0xd8,
+  0x72, 0x1c, 0x64, 0xa0, 0x00, 0xa7, 0x66, 0x40, 0x53, 0xb1, 0xb7, 0xea,
+  0x7d, 0x9e, 0x76, 0xf5, 0xeb, 0x51, 0x4f, 0xd5, 0x4c, 0xb6, 0x2c, 0x9f,
+  0x1d, 0xbf, 0xa4, 0xaa, 0xc7, 0x7d, 0xb6, 0x5c, 0xf4, 0x36, 0x44, 0x59,
+  0x48, 0x70, 0x81, 0xeb, 0x09, 0x24, 0x8a, 0x96, 0xd5, 0x2e, 0x5f, 0xf0,
+  0x2c, 0x2a, 0xfc, 0xb5, 0x39, 0x77, 0xc5, 0xad, 0x12, 0xde, 0x57, 0x7b,
+  0xca, 0x8a, 0x80, 0xef, 0xd4, 0xb0, 0x02, 0x87, 0xd4, 0x68, 0x09, 0xc9,
+  0x31, 0x22, 0x49, 0x1f, 0xce, 0x62, 0x30, 0xf8, 0xff, 0x00, 0x68, 0xd8,
+  0x57, 0xdb, 0x51, 0xee, 0xe3, 0x36, 0x07, 0xb7, 0xcf, 0x69, 0x8c, 0x3e,
+  0x6a, 0x79, 0x7e, 0xca, 0x5b, 0x5f, 0x0b, 0xac, 0x6c, 0x21, 0x2d, 0xd9,
+  0x6f, 0x59, 0x55, 0x91, 0x29, 0xee, 0x4c, 0x2b, 0xe4, 0x8e, 0x41, 0xff,
+  0x00, 0x03, 0x8a, 0x5a, 0x7f, 0xc2, 0xa1, 0x32, 0xf0, 0x30, 0xb8, 0x61,
+  0xdb, 0x9f, 0x1c, 0xa6, 0xd9, 0x5a, 0xd7, 0x98, 0x2e, 0xc8, 0x82, 0xea,
+  0x97, 0xec, 0x05, 0xa4, 0xa9, 0x5f, 0x56, 0xeb, 0x1a, 0x96, 0xd4, 0x6a,
+  0x78, 0xe0, 0x9f, 0xc5, 0x26, 0x46, 0x10, 0xee, 0xac, 0x37, 0x1b, 0x27,
+  0xad, 0xb0, 0x7d, 0x4f, 0x38, 0x3f, 0xfe, 0xd5, 0x94, 0x61, 0xf8, 0xda,
+  0x4f, 0x4b, 0x62, 0x4f, 0xb5, 0xd5, 0x9f, 0xb5, 0x55, 0x4e, 0x5a, 0xb8,
+  0x99, 0x16, 0x74, 0xd1, 0x16, 0x0f, 0xe1, 0x11, 0x8b, 0x29, 0xd3, 0xf0,
+  0x53, 0x70, 0xb0, 0x25, 0x90, 0xaf, 0x62, 0x94, 0xeb, 0x60, 0xfd, 0x54,
+  0xfd, 0x0a, 0xdb, 0xc4, 0xc9, 0xb1, 0xd1, 0x26, 0x1f, 0x12, 0x31, 0xb9,
+  0x0c, 0x2c, 0x6d, 0x0e, 0x35, 0x8f, 0x73, 0x21, 0x43, 0xd2, 0x08, 0x93,
+  0xa3, 0x58, 0x7f, 0x4e, 0xb3, 0xff, 0x00, 0xaa, 0x3f, 0xf9, 0x5f, 0xc0,
+  0xd2, 0xbc, 0x87, 0x06, 0x31, 0xeb, 0x13, 0x3d, 0x5b, 0xb4, 0xc4, 0xd8,
+  0xf1, 0x53, 0x41, 0x5f, 0x6e, 0xea, 0x41, 0x96, 0x9a, 0x65, 0x1c, 0xac,
+  0xb4, 0xdb, 0x49, 0xf4, 0x21, 0x3a, 0x14, 0x88, 0x31, 0xae, 0x26, 0x39,
+  0xf9, 0x7e, 0x27, 0xc5, 0x6f, 0xff, 0x00, 0xc7, 0xc7, 0x1a, 0x4e, 0xbf,
+  0xe7, 0x71, 0x75, 0xb5, 0x58, 0x3e, 0x41, 0x2d, 0xbe, 0x5b, 0xa7, 0x13,
+  0xb2, 0x97, 0x7f, 0xfc, 0x36, 0xe2, 0x45, 0x1f, 0xf4, 0x33, 0xbf, 0xf1,
+  0xae, 0x8a, 0x74, 0x29, 0xd3, 0xf0, 0x45, 0x2f, 0x82, 0x27, 0x08, 0x79,
+  0x27, 0xd5, 0x50, 0xf9, 0x56, 0x51, 0x60, 0xc5, 0xa1, 0x22, 0x66, 0x43,
+  0x75, 0x8d, 0x6f, 0x65, 0xc5, 0x72, 0x34, 0x5d, 0x57, 0x9c, 0xe2, 0xb5,
+  0xbe, 0x54, 0x24, 0x75, 0x51, 0xd7, 0x80, 0x04, 0xd2, 0x3d, 0x8e, 0xcc,
+  0xdd, 0x87, 0x8c, 0xf0, 0x6d, 0x71, 0x2f, 0x77, 0xe9, 0xe3, 0xf9, 0x3f,
+  0x26, 0x4c, 0xb1, 0x71, 0xb9, 0xbd, 0x27, 0x9b, 0x6f, 0xb0, 0x86, 0xcf,
+  0x2a, 0x89, 0x48, 0xf8, 0x2e, 0x6b, 0x40, 0x78, 0xd4, 0x8c, 0x12, 0x32,
+  0x6e, 0x31, 0xbf, 0x3d, 0xb0, 0x95, 0xdb, 0xb1, 0x58, 0x8b, 0x84, 0xdb,
+  0x9e, 0x06, 0x7c, 0x8e, 0x55, 0x3a, 0x12, 0x7c, 0x7b, 0x36, 0x92, 0xda,
+  0x4f, 0xa0, 0xba, 0x47, 0x78, 0xad, 0x41, 0xb1, 0x59, 0xf5, 0xd2, 0xea,
+  0x4a, 0x31, 0x0c, 0x22, 0xf5, 0x73, 0x04, 0x8e, 0x59, 0x77, 0x04, 0x7b,
+  0x9b, 0x17, 0x94, 0xfe, 0x76, 0xde, 0x1d, 0xaa, 0x87, 0xcd, 0x6c, 0xd7,
+  0x93, 0x8a, 0xe6, 0x39, 0x01, 0xde, 0x5f, 0x96, 0x98, 0x90, 0xd4, 0x7c,
+  0xeb, 0x66, 0x3e, 0x95, 0x46, 0x42, 0x87, 0x5e, 0x8b, 0x90, 0xad, 0xbc,
+  0xa0, 0x47, 0x7f, 0x2f, 0x67, 0xec, 0xa7, 0xd0, 0x01, 0x1e, 0x04, 0x1f,
+  0x55, 0x67, 0x42, 0x80, 0x8a, 0xc6, 0x71, 0xdb, 0x1e, 0x37, 0x6d, 0x16,
+  0xfb, 0x0d, 0xae, 0x35, 0xba, 0x30, 0x3c, 0xca, 0x43, 0x28, 0xd7, 0x3a,
+  0xbc, 0x54, 0xa3, 0xde, 0xa5, 0x1f, 0x15, 0x12, 0x49, 0xf4, 0xd4, 0xae,
+  0xba, 0x6a, 0x8a, 0x28, 0x02, 0x8a, 0x28, 0xa0, 0x11, 0x38, 0xcb, 0xf1,
+  0x2c, 0x5f, 0xf6, 0xaa, 0xd9, 0xf7, 0xe2, 0x9e, 0xe9, 0x13, 0x8c, 0xbf,
+  0x12, 0xc5, 0xff, 0x00, 0x6a, 0xad, 0x9f, 0x7e, 0x29, 0xee, 0x80, 0xc1,
+  0xef, 0xdd, 0x14, 0x1a, 0x2a, 0x51, 0x56, 0xcc, 0xd2, 0x67, 0x1c, 0x7e,
+  0x47, 0xb2, 0xef, 0xa2, 0x24, 0x7f, 0x01, 0xa7, 0x3a, 0x4c, 0xe3, 0x8f,
+  0xc8, 0xf6, 0x5d, 0xf4, 0x44, 0x8f, 0xe0, 0x35, 0x05, 0x86, 0xf8, 0xdf,
+  0x17, 0x6f, 0xe6, 0x0f, 0xb2, 0xb6, 0x56, 0xb8, 0xdf, 0x17, 0x6f, 0xe6,
+  0x0f, 0xb2, 0xb6, 0x50, 0x05, 0x14, 0x56, 0x09, 0x3b, 0xee, 0xa0, 0x33,
+  0x58, 0x2a, 0xd7, 0x7d, 0x28, 0xe7, 0x3c, 0x48, 0xc3, 0xf0, 0xd7, 0x51,
+  0x16, 0xf5, 0x77, 0x47, 0xba, 0x2e, 0xfe, 0x42, 0xdb, 0x15, 0xb5, 0x48,
+  0x98, 0xf1, 0xf0, 0x09, 0x65, 0xb0, 0x56, 0x77, 0xd3, 0xa9, 0x00, 0x7a,
+  0xe9, 0x64, 0xe4, 0x1c, 0x56, 0xcc, 0x55, 0xc9, 0x8c, 0xe3, 0x4c, 0xe1,
+  0x16, 0xc5, 0x74, 0xf7, 0x4f, 0x21, 0x48, 0x7a, 0x62, 0x87, 0xfb, 0x38,
+  0x8d, 0xab, 0x49, 0x3f, 0xef, 0x56, 0x3d, 0x94, 0x05, 0x8d, 0x7d, 0xbd,
+  0x5a, 0x6c, 0x36, 0xc7, 0x6e, 0x77, 0xbb, 0x94, 0x4b, 0x6c, 0x26, 0x46,
+  0xdc, 0x91, 0x29, 0xd4, 0xb6, 0x84, 0xff, 0x00, 0xc4, 0xa2, 0x05, 0x57,
+  0x6b, 0xe2, 0xe4, 0x8b, 0xfa, 0x8b, 0x3c, 0x34, 0xc2, 0xaf, 0x19, 0x60,
+  0x3b, 0xd5, 0xc5, 0xd1, 0xee, 0x7d, 0xb8, 0x6b, 0xd0, 0xfb, 0xc3, 0x6b,
+  0xeb, 0xfa, 0x09, 0x57, 0xb6, 0xba, 0xac, 0x7c, 0x1d, 0xc7, 0xd3, 0x76,
+  0x66, 0xff, 0x00, 0x97, 0xcf, 0xb8, 0x66, 0xb7, 0xc6, 0xba, 0xb7, 0x2a,
+  0xf2, 0xb0, 0xb6, 0x59, 0x3f, 0xec, 0xa3, 0xa4, 0x06, 0x9b, 0x1f, 0xf0,
+  0x93, 0xeb, 0xab, 0x19, 0x29, 0x4a, 0x3c, 0xd4, 0x80, 0x00, 0x1d, 0x00,
+  0x1d, 0x05, 0x01, 0x56, 0x1c, 0x3b, 0x89, 0xb9, 0x67, 0xfa, 0xeb, 0x9d,
+  0x33, 0x62, 0x80, 0xb1, 0xe7, 0xdb, 0x31, 0x56, 0x94, 0xd2, 0xd4, 0x35,
+  0xf0, 0x57, 0x2d, 0xcd, 0xb9, 0xed, 0xe4, 0x4a, 0x37, 0x4c, 0x18, 0x8f,
+  0x0a, 0x38, 0x77, 0x8b, 0xc8, 0x13, 0x2d, 0x38, 0xa5, 0xbc, 0x4e, 0xef,
+  0x33, 0x64, 0xa4, 0xc9, 0x90, 0x4f, 0xa4, 0xba, 0xe9, 0x52, 0xf7, 0xf5,
+  0xd3, 0xa8, 0x03, 0x54, 0x6f, 0xc3, 0x54, 0x07, 0x0d, 0xda, 0xc9, 0x67,
+  0xbb, 0xb1, 0xe4, 0xf7, 0x6b, 0x54, 0x1b, 0x83, 0x3a, 0xd7, 0x67, 0x2a,
+  0x3a, 0x1d, 0x4e, 0xbd, 0x1a, 0x50, 0x22, 0xaa, 0x9c, 0xb3, 0x0d, 0x77,
+  0x86, 0x12, 0x3f, 0x96, 0xdc, 0x31, 0xb7, 0x3e, 0xd4, 0x16, 0x17, 0xcf,
+  0x7d, 0xc6, 0xe2, 0x28, 0xf9, 0x3c, 0xd8, 0xff, 0x00, 0x9e, 0xeb, 0x2d,
+  0x1e, 0x88, 0x7d, 0x03, 0xa8, 0xe5, 0xd0, 0x50, 0x04, 0x6b, 0x75, 0x70,
+  0xbc, 0xf3, 0x6c, 0xb4, 0xb7, 0x5d, 0x71, 0x08, 0x6d, 0x00, 0x95, 0x29,
+  0x6a, 0xd0, 0x48, 0x1e, 0x24, 0xf8, 0x57, 0x05, 0x9a, 0xf9, 0x65, 0xbd,
+  0xa1, 0xc7, 0xac, 0xd7, 0x68, 0x17, 0x24, 0x34, 0xa0, 0x97, 0x15, 0x16,
+  0x4a, 0x1d, 0x4a, 0x0f, 0xa0, 0xf2, 0x93, 0xa3, 0x40, 0x18, 0xcd, 0xf2,
+  0xd7, 0x91, 0xe3, 0xf0, 0x6f, 0xb6, 0x59, 0xad, 0xcc, 0xb7, 0x4d, 0x64,
+  0x3c, 0xc3, 0xe8, 0xee, 0x52, 0x4f, 0xd8, 0x7c, 0x08, 0x3d, 0xc4, 0x1a,
+  0x90, 0xd9, 0x1b, 0xd8, 0xaa, 0x93, 0x07, 0xe5, 0xe1, 0xd7, 0x16, 0xae,
+  0x58, 0x33, 0xde, 0xf3, 0x60, 0xc9, 0x9c, 0x76, 0xed, 0x8f, 0x1e, 0xe4,
+  0x35, 0x23, 0xbe, 0x54, 0x51, 0xd3, 0x43, 0xaf, 0xbe, 0xa4, 0x0f, 0x05,
+  0x2b, 0xd1, 0x56, 0x85, 0xf2, 0x1b, 0xd7, 0x1b, 0x34, 0xeb, 0x7c, 0x79,
+  0x8e, 0xc2, 0x7a, 0x4c, 0x77, 0x19, 0x44, 0x96, 0xc6, 0xd6, 0xca, 0x94,
+  0x92, 0x02, 0xc0, 0xf4, 0x8d, 0xef, 0xea, 0xa0, 0x29, 0xd8, 0x99, 0x2d,
+  0xc2, 0xe5, 0x95, 0xe4, 0x17, 0x1c, 0x6c, 0xb7, 0x2a, 0xfb, 0x90, 0x3a,
+  0x9b, 0x6d, 0x88, 0x2c, 0x05, 0xb7, 0x0e, 0xdf, 0x14, 0xad, 0x0e, 0x4e,
+  0x70, 0x8e, 0xe6, 0x8b, 0xca, 0x78, 0xa4, 0x7f, 0x48, 0x42, 0x12, 0x37,
+  0xbd, 0x8b, 0x5f, 0x0d, 0xc7, 0x60, 0xe3, 0x18, 0xe4, 0x5b, 0x34, 0x12,
+  0xb5, 0xa1, 0x90, 0x54, 0xeb, 0xce, 0x1d, 0xb8, 0xfb, 0xaa, 0x3c, 0xce,
+  0x3a, 0xb3, 0xe2, 0xb5, 0x28, 0x95, 0x13, 0xe9, 0x3e, 0x8d, 0x0a, 0x89,
+  0xe1, 0x6e, 0x01, 0x69, 0xc0, 0xac, 0x29, 0x83, 0x0d, 0xc7, 0x26, 0x4d,
+  0x75, 0x0d, 0x89, 0x93, 0xde, 0xfc, 0xa4, 0x82, 0x84, 0xf2, 0xa0, 0x7a,
+  0x12, 0x84, 0x8e, 0x89, 0x40, 0xe8, 0x3a, 0x9e, 0xa4, 0x92, 0x5b, 0xc7,
+  0x41, 0x40, 0x14, 0x51, 0x45, 0x00, 0x51, 0x45, 0x14, 0x01, 0x45, 0x14,
+  0x50, 0x08, 0x9c, 0x65, 0xf8, 0x96, 0x2f, 0xfb, 0x55, 0x6c, 0xfb, 0xf1,
+  0x4f, 0x74, 0x89, 0xc6, 0x5f, 0x89, 0x62, 0xff, 0x00, 0xb5, 0x56, 0xcf,
+  0xbf, 0x14, 0xf7, 0x40, 0x79, 0x51, 0xeb, 0x45, 0x64, 0x8d, 0x9e, 0xf3,
+  0x45, 0x0a, 0xb4, 0xf2, 0x66, 0x93, 0x38, 0xe3, 0xf2, 0x3d, 0x97, 0x7d,
+  0x11, 0x23, 0xf8, 0x0d, 0x39, 0xd2, 0x67, 0x1c, 0x7e, 0x47, 0xb2, 0xef,
+  0xa2, 0x24, 0x7f, 0x01, 0xa1, 0x61, 0xbe, 0x37, 0xc5, 0xdb, 0xf9, 0x83,
+  0xec, 0xaf, 0x64, 0xfb, 0x2a, 0x2e, 0xf5, 0x7b, 0xb5, 0xe3, 0xb8, 0xeb,
+  0xd7, 0x9b, 0xd4, 0xe6, 0x60, 0xdb, 0xe2, 0x32, 0x1c, 0x7d, 0xf7, 0x4e,
+  0x92, 0x81, 0xd0, 0x0f, 0x59, 0x24, 0x90, 0x00, 0x1d, 0x49, 0x20, 0x0d,
+  0x93, 0x55, 0xea, 0xa6, 0x71, 0x03, 0x89, 0x40, 0xa2, 0xd6, 0x64, 0x60,
+  0x98, 0xaa, 0xf5, 0xb9, 0x6f, 0x37, 0xfe, 0x98, 0x98, 0x8f, 0x1e, 0xcd,
+  0xb3, 0xd2, 0x32, 0x4f, 0x82, 0x95, 0xb5, 0xeb, 0x44, 0x04, 0xee, 0x80,
+  0x60, 0xce, 0xb8, 0x9d, 0x8d, 0x62, 0x93, 0x5b, 0xb5, 0x28, 0xca, 0xbc,
+  0xdf, 0x9e, 0xd8, 0x62, 0xcb, 0x69, 0x6b, 0xca, 0x66, 0xb9, 0xeb, 0x28,
+  0x07, 0xcc, 0x4f, 0xeb, 0x2c, 0xa4, 0x7a, 0xfa, 0x54, 0x0f, 0xb9, 0x5c,
+  0x5b, 0xcd, 0x00, 0x55, 0xea, 0xf1, 0x13, 0x01, 0xb4, 0x3a, 0x36, 0x61,
+  0x5a, 0x08, 0x93, 0x72, 0x52, 0x4f, 0xe6, 0xb9, 0x21, 0x63, 0x91, 0xa5,
+  0x6b, 0xc5, 0xb4, 0xa8, 0x8d, 0xfc, 0x2a, 0x73, 0xc1, 0xf0, 0xac, 0x5f,
+  0x0c, 0xb7, 0x18, 0x98, 0xe5, 0xa1, 0x88, 0x7d, 0xa7, 0x57, 0xdf, 0xd7,
+  0x33, 0xf2, 0x15, 0xbd, 0x95, 0x3a, 0xe9, 0xda, 0xdc, 0x56, 0xc9, 0xea,
+  0xa2, 0x69, 0x87, 0x42, 0x80, 0x56, 0xc1, 0xb0, 0x0c, 0x4f, 0x0c, 0x69,
+  0xc3, 0x60, 0xb4, 0x32, 0xcc, 0xb7, 0xb6, 0x64, 0x4d, 0x74, 0x97, 0x65,
+  0x48, 0x51, 0xea, 0x4b, 0x8f, 0x2b, 0x6b, 0x56, 0xcf, 0xa4, 0xeb, 0xd0,
+  0x05, 0x77, 0xe5, 0xf9, 0x56, 0x3b, 0x88, 0xda, 0xcd, 0xcf, 0x24, 0xbc,
+  0x44, 0xb6, 0x45, 0xdf, 0x2a, 0x56, 0xf2, 0xf4, 0xa7, 0x15, 0xfa, 0x28,
+  0x48, 0xf3, 0x96, 0xaf, 0xd5, 0x48, 0x24, 0xfa, 0x2b, 0xb2, 0xf0, 0xdd,
+  0xcd, 0xd4, 0x47, 0x4d, 0xae, 0x54, 0x78, 0xea, 0x12, 0x5b, 0x53, 0xe5,
+  0xe6, 0x4b, 0x9c, 0xcc, 0x83, 0xe7, 0xa5, 0x3a, 0x50, 0xd2, 0x88, 0xee,
+  0x27, 0x60, 0x7a, 0x0d, 0x7b, 0x93, 0x6f, 0x81, 0x2e, 0x5c, 0x69, 0x72,
+  0xa0, 0xc6, 0x7a, 0x4c, 0x55, 0x15, 0x47, 0x75, 0xc6, 0x92, 0xa5, 0xb2,
+  0x4f, 0x42, 0x52, 0x48, 0xda, 0x77, 0xea, 0xa0, 0x12, 0x71, 0x9c, 0xdf,
+  0x27, 0xcb, 0x2f, 0xd1, 0x95, 0x63, 0xc3, 0x26, 0x5b, 0xf1, 0x94, 0xa8,
+  0x99, 0x17, 0x4b, 0xde, 0xe3, 0x3b, 0x21, 0x3a, 0xe8, 0x23, 0xc7, 0xf8,
+  0x7d, 0x49, 0x07, 0x99, 0xce, 0x51, 0xaf, 0x0a, 0x71, 0x9b, 0x69, 0x89,
+  0x32, 0xed, 0x6f, 0xbb, 0x3c, 0x5f, 0x12, 0x60, 0x07, 0x7b, 0x00, 0x87,
+  0x96, 0x94, 0x7b, 0xe2, 0x42, 0x54, 0x54, 0x90, 0x74, 0xae, 0x83, 0xa7,
+  0x30, 0x3a, 0xeb, 0x50, 0x39, 0x7f, 0x11, 0x71, 0x1c, 0x5e, 0x4f, 0x90,
+  0x4e, 0xb9, 0xf9, 0x4d, 0xd5, 0x63, 0x6d, 0xdb, 0x20, 0xb6, 0x64, 0xcc,
+  0x70, 0xeb, 0x63, 0x4d, 0x23, 0x6a, 0x03, 0xf5, 0x95, 0xa4, 0xfa, 0xe9,
+  0x32, 0xe3, 0x96, 0x71, 0x13, 0x26, 0xda, 0x2d, 0xb1, 0xa3, 0x61, 0x56,
+  0xe5, 0x7f, 0x4d, 0x24, 0x22, 0x65, 0xc5, 0x43, 0xd4, 0xd8, 0x3d, 0x93,
+  0x47, 0xe7, 0x17, 0x08, 0xf4, 0x78, 0x55, 0xe1, 0x4e, 0x53, 0xf0, 0xa2,
+  0x93, 0xa9, 0x18, 0x78, 0x99, 0x67, 0x64, 0x79, 0x05, 0x8f, 0x1a, 0xb5,
+  0xae, 0xe5, 0x7f, 0xba, 0xc2, 0xb5, 0x42, 0x6f, 0xbd, 0xe9, 0x6f, 0xa5,
+  0xb4, 0x7b, 0x01, 0x27, 0xa9, 0xf5, 0x0e, 0xb5, 0x40, 0x66, 0x9f, 0x85,
+  0x35, 0xad, 0x4d, 0xb8, 0xd6, 0x01, 0x66, 0x55, 0xdf, 0x5c, 0xc9, 0xf7,
+  0x42, 0x66, 0xda, 0x8e, 0x08, 0x3a, 0x25, 0x28, 0x1e, 0x7a, 0x87, 0xb7,
+  0x93, 0xeb, 0x15, 0x3a, 0xce, 0x03, 0x89, 0xcc, 0xf2, 0xa1, 0x94, 0x44,
+  0x93, 0x92, 0xbb, 0x3a, 0x3a, 0xa3, 0xc9, 0x9d, 0x75, 0x78, 0xc8, 0x92,
+  0x94, 0x2b, 0xc5, 0xb5, 0x2b, 0xa3, 0x5a, 0xef, 0x01, 0x01, 0x35, 0xf2,
+  0xb7, 0x10, 0x30, 0xeb, 0xcf, 0xe0, 0xff, 0x00, 0xc4, 0x98, 0xee, 0xa5,
+  0x5e, 0xe9, 0x62, 0xd7, 0x25, 0x15, 0x42, 0x98, 0xa6, 0xd2, 0xa2, 0xe3,
+  0x40, 0x8e, 0x61, 0xd4, 0x69, 0x0f, 0xa0, 0x11, 0xd4, 0x68, 0xf5, 0x04,
+  0x6b, 0x7d, 0x34, 0x9d, 0x19, 0x53, 0x6b, 0x51, 0x48, 0x56, 0x55, 0x13,
+  0xd2, 0x36, 0xe4, 0x57, 0x2c, 0xeb, 0x88, 0x6e, 0x89, 0x19, 0x9d, 0xfe,
+  0x6c, 0x88, 0x0b, 0x21, 0x4d, 0xc0, 0x1e, 0xf1, 0x11, 0x43, 0x7f, 0x9a,
+  0xd2, 0x01, 0x2e, 0xfb, 0x40, 0x77, 0x5e, 0x24, 0x77, 0xd3, 0x9e, 0x26,
+  0xfc, 0xdc, 0x32, 0x74, 0x5c, 0xb6, 0xd7, 0xda, 0x49, 0x55, 0x95, 0xb0,
+  0x6e, 0x6d, 0x34, 0x94, 0xa4, 0x3d, 0x6d, 0xd0, 0x4b, 0x88, 0x3a, 0x51,
+  0x0a, 0x28, 0x00, 0x2d, 0x03, 0x99, 0x44, 0x14, 0x7c, 0x14, 0x6e, 0xba,
+  0x20, 0x45, 0x81, 0x21, 0xbf, 0x2d, 0x66, 0x42, 0x66, 0x25, 0xd4, 0x25,
+  0xe5, 0x3c, 0x09, 0x29, 0x29, 0x50, 0x04, 0x29, 0x44, 0xe8, 0x9e, 0x84,
+  0x69, 0x4b, 0xec, 0xfe, 0x79, 0xa6, 0x2b, 0x25, 0xb8, 0xb8, 0xa6, 0xa4,
+  0x06, 0x10, 0x88, 0xa1, 0xc4, 0xee, 0x43, 0x9c, 0x9c, 0xbd, 0x7f, 0x45,
+  0x4a, 0x1c, 0xbc, 0xde, 0xb4, 0x25, 0x64, 0xef, 0xf2, 0x86, 0xb7, 0x8d,
+  0x14, 0xd6, 0x0e, 0x79, 0x56, 0x79, 0xc9, 0x6c, 0x71, 0x5b, 0x19, 0x6f,
+  0x3f, 0xe1, 0xfb, 0x4e, 0xd8, 0xa6, 0x36, 0x9b, 0xa4, 0x62, 0xdd, 0xdb,
+  0x1f, 0x9e, 0xda, 0xb6, 0x1b, 0x92, 0x81, 0xce, 0xd2, 0xc2, 0xbf, 0x41,
+  0x40, 0xf2, 0x9f, 0x4a, 0x56, 0x6a, 0x53, 0x85, 0x99, 0x6b, 0x19, 0xce,
+  0x05, 0x6b, 0xc9, 0x1a, 0x6b, 0xb0, 0x72, 0x4b, 0x5c, 0xb2, 0xa3, 0x9e,
+  0xf6, 0x24, 0x20, 0x94, 0x3a, 0xd9, 0x1f, 0xaa, 0xb4, 0xa8, 0x75, 0xf0,
+  0xd1, 0xf1, 0xa4, 0xee, 0x09, 0x5c, 0x06, 0x3f, 0x73, 0x9b, 0xc3, 0x49,
+  0x4e, 0x28, 0xb1, 0x15, 0x06, 0x75, 0x85, 0x6b, 0x3d, 0x5c, 0x84, 0xa5,
+  0x79, 0xcc, 0xef, 0xc4, 0xb2, 0xe1, 0xd7, 0x7f, 0xc0, 0x52, 0x3d, 0x15,
+  0xaa, 0x12, 0x87, 0x0d, 0x78, 0xd8, 0xfc, 0x27, 0x13, 0xd9, 0xe3, 0x19,
+  0xe4, 0x8e, 0xda, 0x2a, 0x87, 0xc0, 0x8b, 0x76, 0x08, 0xf7, 0xc4, 0x1f,
+  0x40, 0x7d, 0x29, 0xe6, 0x1f, 0xac, 0x92, 0x3c, 0x6b, 0x8e, 0x51, 0x71,
+  0x78, 0x67, 0x64, 0x64, 0xa4, 0xb2, 0x8b, 0x7c, 0x74, 0x14, 0x56, 0x12,
+  0x76, 0x90, 0x6b, 0x35, 0x52, 0xc1, 0x45, 0x14, 0x50, 0x05, 0x14, 0x51,
+  0x40, 0x1d, 0x68, 0xa2, 0x8a, 0x01, 0x13, 0x8c, 0xbf, 0x12, 0xc5, 0xff,
+  0x00, 0x6a, 0xad, 0x9f, 0x7e, 0x29, 0xee, 0x91, 0x38, 0xcb, 0xf1, 0x2c,
+  0x5f, 0xf6, 0xaa, 0xd9, 0xf7, 0xe2, 0x9e, 0xe8, 0x02, 0x8a, 0xf2, 0xa2,
+  0x41, 0xe8, 0x07, 0xd6, 0x75, 0x45, 0x01, 0xea, 0x93, 0x38, 0xe3, 0xbf,
+  0xc4, 0xfe, 0x5c, 0x3f, 0xf4, 0x89, 0x1a, 0xff, 0x00, 0x90, 0xd3, 0x9d,
+  0x26, 0x71, 0xc7, 0xe4, 0x7b, 0x2e, 0xfa, 0x22, 0x47, 0xf0, 0x1a, 0x02,
+  0xbe, 0x9f, 0x7f, 0x63, 0x27, 0xe2, 0x52, 0xfd, 0xd2, 0x61, 0x4f, 0xdb,
+  0xac, 0x37, 0x37, 0x2d, 0xb6, 0x78, 0xab, 0xd7, 0x66, 0x67, 0x30, 0xca,
+  0x5c, 0x7e, 0x63, 0xa9, 0x3d, 0xe5, 0x1c, 0xe8, 0x43, 0x60, 0xef, 0x44,
+  0x95, 0x0e, 0xa7, 0xa5, 0xdb, 0x05, 0x96, 0xd9, 0x8a, 0x84, 0xa0, 0xa8,
+  0x82, 0x36, 0x54, 0x7b, 0xd4, 0x4f, 0x79, 0x3e, 0xb3, 0x5f, 0x38, 0x71,
+  0x36, 0x1c, 0xcc, 0x3f, 0x8d, 0xb6, 0xf9, 0x69, 0x98, 0xd4, 0x7b, 0x3e,
+  0x50, 0xfa, 0x6e, 0x2c, 0xad, 0xf0, 0x7b, 0x36, 0x67, 0x32, 0xcf, 0x65,
+  0x25, 0xae, 0x80, 0xeb, 0xb6, 0x60, 0x82, 0x0e, 0xba, 0xb8, 0xda, 0x47,
+  0xa6, 0xaf, 0x5c, 0x16, 0xf0, 0xc5, 0xdf, 0x1f, 0x8c, 0xf3, 0x0f, 0x07,
+  0x51, 0xd9, 0x25, 0x6d, 0xab, 0x44, 0x15, 0x36, 0xa1, 0xb4, 0xab, 0x47,
+  0xaf, 0x71, 0xf1, 0xeb, 0x5a, 0xe3, 0x34, 0xf2, 0xba, 0x33, 0x27, 0x2c,
+  0x54, 0xc3, 0xea, 0x86, 0x02, 0x75, 0xe1, 0xd2, 0xbc, 0xb8, 0xe2, 0x5b,
+  0x6d, 0x4b, 0x71, 0x49, 0x42, 0x52, 0x36, 0xa2, 0x4e, 0x80, 0x1e, 0x93,
+  0x54, 0x1f, 0x1c, 0x7f, 0x08, 0x85, 0x61, 0xb9, 0x14, 0x9c, 0x4f, 0x14,
+  0xc5, 0x9f, 0xbe, 0x5e, 0x59, 0x21, 0xb7, 0x64, 0x3c, 0x4a, 0x22, 0xb4,
+  0xb2, 0x90, 0xae, 0x5f, 0x37, 0x6a, 0x70, 0x80, 0x46, 0xc0, 0xe5, 0x03,
+  0x7a, 0xdf, 0x7d, 0x7c, 0x77, 0xc6, 0xee, 0x29, 0x71, 0x47, 0x29, 0xbb,
+  0x48, 0xb4, 0xe6, 0x17, 0xf9, 0x09, 0x8e, 0x9d, 0x1f, 0x20, 0x8b, 0xef,
+  0x51, 0x8a, 0x48, 0xd8, 0xf3, 0x52, 0x7c, 0xee, 0x84, 0x7c, 0x22, 0xa2,
+  0x3b, 0xab, 0x34, 0x8d, 0x32, 0x8f, 0xbe, 0xaf, 0x3c, 0x60, 0xc7, 0x3c,
+  0xb6, 0x45, 0xaf, 0x11, 0x62, 0x46, 0x63, 0x75, 0x60, 0xf2, 0xbc, 0xd5,
+  0xad, 0x49, 0x31, 0xd8, 0x57, 0x87, 0x6b, 0x21, 0x47, 0xb3, 0x47, 0x71,
+  0xe8, 0x0a, 0x95, 0xea, 0xa5, 0x6b, 0xa3, 0xb9, 0xb6, 0x44, 0xdb, 0xb2,
+  0x32, 0xec, 0x95, 0x18, 0xfd, 0xaf, 0xbc, 0xdb, 0xac, 0x8e, 0x96, 0x7c,
+  0xcf, 0x43, 0xd2, 0xd4, 0x03, 0x87, 0xbf, 0x44, 0x36, 0x10, 0x3d, 0xb5,
+  0xf3, 0x77, 0xe0, 0x29, 0x74, 0x4b, 0x79, 0x16, 0x4b, 0x66, 0x5b, 0x89,
+  0xdc, 0x88, 0x8d, 0x49, 0x42, 0x09, 0xe8, 0x7b, 0x35, 0x94, 0x9e, 0x9f,
+  0xff, 0x00, 0x20, 0xfe, 0xea, 0xfa, 0x1b, 0x89, 0x39, 0x26, 0x3f, 0x89,
+  0xdb, 0x5b, 0xbc, 0xde, 0xd2, 0xec, 0xb7, 0xb9, 0xbb, 0x2b, 0x7c, 0x06,
+  0x93, 0xda, 0x3b, 0x25, 0xef, 0x00, 0xdb, 0x7e, 0x2a, 0xfd, 0x63, 0xdd,
+  0xea, 0xf1, 0xee, 0xa1, 0x46, 0x1a, 0x35, 0xb3, 0x8a, 0xbd, 0x59, 0xeb,
+  0xd0, 0x89, 0x1c, 0x42, 0xdd, 0x8e, 0xdb, 0x61, 0x29, 0xac, 0x72, 0xdc,
+  0xcc, 0x46, 0x15, 0xd5, 0x6b, 0x6d, 0x82, 0x92, 0xf1, 0xfd, 0x25, 0x2c,
+  0x8d, 0xb8, 0x77, 0xe2, 0x49, 0xf6, 0xd4, 0xd8, 0xef, 0xdf, 0xd5, 0xeb,
+  0xff, 0x00, 0xdf, 0xfe, 0xfa, 0xd5, 0x28, 0xde, 0x47, 0xc7, 0x4b, 0xc5,
+  0xd1, 0x0b, 0x6e, 0x0e, 0x2f, 0x8c, 0x32, 0xe8, 0xe7, 0x8f, 0x6d, 0x98,
+  0xdb, 0xb3, 0x26, 0x2d, 0x1e, 0x1c, 0xc8, 0x68, 0x29, 0x43, 0xfb, 0x93,
+  0x56, 0x74, 0x1b, 0xe2, 0xd9, 0x87, 0x1e, 0x3d, 0xd1, 0xb7, 0x5c, 0xbd,
+  0xa5, 0x09, 0x12, 0x22, 0xc7, 0x86, 0xeb, 0x6a, 0xe7, 0x00, 0x15, 0x28,
+  0x21, 0xcd, 0x29, 0x0d, 0xf5, 0xd8, 0x52, 0xb4, 0x3c, 0x37, 0xba, 0xea,
+  0x85, 0x58, 0xbd, 0x8e, 0x49, 0xd3, 0x97, 0x2c, 0x52, 0xce, 0xf8, 0x83,
+  0x73, 0x4d, 0xe9, 0x78, 0xa6, 0x05, 0x6f, 0x66, 0xe7, 0x7b, 0x6d, 0xc0,
+  0xdc, 0xb9, 0x92, 0x12, 0x7c, 0x92, 0x0a, 0x94, 0x36, 0x12, 0x79, 0x7c,
+  0xe7, 0x5d, 0xd7, 0x5e, 0xcd, 0x20, 0x91, 0xe3, 0xdc, 0x45, 0x42, 0x71,
+  0x1f, 0x0c, 0xcd, 0xee, 0xdc, 0x10, 0xc9, 0x23, 0x66, 0xf7, 0x0b, 0xcd,
+  0xde, 0x40, 0x69, 0x12, 0xed, 0xe5, 0x56, 0xb6, 0x23, 0xc5, 0x86, 0xf3,
+  0x67, 0x98, 0x94, 0x84, 0x92, 0xf0, 0x0a, 0x4f, 0x32, 0x36, 0xa0, 0x07,
+  0x9d, 0xb2, 0x07, 0x78, 0xb5, 0xb8, 0x67, 0x62, 0xf2, 0x0c, 0x4a, 0xf6,
+  0xee, 0x2b, 0x6b, 0x89, 0x03, 0x23, 0x5d, 0xc5, 0xe6, 0x82, 0xa7, 0x28,
+  0x2c, 0x47, 0x0b, 0x58, 0x57, 0x3a, 0xb4, 0x4f, 0x36, 0xd2, 0xb0, 0xb3,
+  0xa2, 0x79, 0x95, 0xa0, 0x4e, 0x80, 0xd4, 0x8e, 0x2f, 0x8d, 0xdc, 0x71,
+  0xbc, 0x22, 0xf5, 0x74, 0xcf, 0x6e, 0xfe, 0xe8, 0xdd, 0x5d, 0x8c, 0xff,
+  0x00, 0x96, 0x48, 0x12, 0xde, 0x71, 0x92, 0xc9, 0x4f, 0x41, 0xd9, 0xa8,
+  0x84, 0x03, 0xd0, 0x9f, 0x35, 0x09, 0xd7, 0x37, 0x28, 0xf4, 0x9f, 0x3a,
+  0xbd, 0x69, 0x4d, 0xb4, 0xcf, 0x46, 0x85, 0x18, 0xc1, 0x26, 0x8a, 0x43,
+  0xf0, 0x66, 0x4a, 0xae, 0x3c, 0x26, 0xb2, 0xc6, 0x90, 0x1b, 0x66, 0xec,
+  0xd0, 0x71, 0x71, 0x15, 0x29, 0xb5, 0x3a, 0x04, 0x60, 0xe9, 0x48, 0x75,
+  0xa4, 0x28, 0x84, 0x92, 0x0e, 0xd2, 0x48, 0xee, 0x29, 0xeb, 0xd7, 0xa5,
+  0x59, 0x4c, 0xdb, 0x2e, 0x2b, 0x9c, 0x5e, 0x4b, 0x49, 0x0e, 0x21, 0x5a,
+  0x33, 0xae, 0x0b, 0x12, 0x1e, 0x23, 0x7f, 0xd1, 0xb6, 0x9f, 0x31, 0x03,
+  0xbf, 0xd1, 0xf3, 0x69, 0x62, 0xdd, 0x65, 0x5e, 0x15, 0x87, 0x18, 0x32,
+  0x16, 0x96, 0xdd, 0xc7, 0x6e, 0x91, 0xee, 0xb1, 0x47, 0x2f, 0x9c, 0xcc,
+  0x19, 0xea, 0x4a, 0x1f, 0x6b, 0xe6, 0x85, 0xad, 0xcd, 0x81, 0xd3, 0x6d,
+  0x83, 0xe1, 0x56, 0x3a, 0x18, 0x6d, 0xb7, 0x9d, 0x71, 0x3c, 0xdc, 0xee,
+  0x1f, 0x3c, 0x95, 0x13, 0xdd, 0xd3, 0xa0, 0x3d, 0x00, 0xe9, 0xdc, 0x34,
+  0x2b, 0xb6, 0xdd, 0xeb, 0x8f, 0xc0, 0xe3, 0xb8, 0x5a, 0x65, 0xb7, 0x52,
+  0x07, 0x37, 0xb7, 0xdc, 0x9c, 0x89, 0x0a, 0xf9, 0x61, 0xda, 0xaf, 0xf6,
+  0x27, 0xbc, 0xb6, 0x07, 0x5d, 0x76, 0xe4, 0x27, 0x4e, 0xb0, 0xaf, 0xd5,
+  0x75, 0xbe, 0x64, 0x6b, 0xa6, 0x8f, 0x29, 0xf0, 0xa7, 0x3c, 0x9a, 0xdd,
+  0x67, 0xe2, 0xff, 0x00, 0x08, 0x35, 0x06, 0x49, 0x43, 0x57, 0x38, 0xc8,
+  0x97, 0x6e, 0x97, 0xdc, 0xe4, 0x49, 0x29, 0x3c, 0xcd, 0x2f, 0xd2, 0x95,
+  0x21, 0xc4, 0x80, 0x47, 0xa9, 0x42, 0xa3, 0x7c, 0x7f, 0xfd, 0xd4, 0x77,
+  0x0d, 0xa7, 0x7f, 0x24, 0x78, 0x83, 0x2f, 0x16, 0x78, 0xf2, 0xd9, 0xf2,
+  0x45, 0xb9, 0x3e, 0xd4, 0x4f, 0x44, 0xb3, 0x30, 0x0e, 0x69, 0x2c, 0x0f,
+  0x40, 0x58, 0xf7, 0xd4, 0x8e, 0x9d, 0x7b, 0x5a, 0xca, 0xf2, 0x96, 0x7b,
+  0xe8, 0xd2, 0xce, 0xa6, 0x3b, 0x8c, 0x6b, 0xe0, 0xce, 0x62, 0xfe, 0x5f,
+  0x86, 0x21, 0xeb, 0xa2, 0x11, 0x1e, 0xff, 0x00, 0x6d, 0x75, 0x76, 0xfb,
+  0xdc, 0x6d, 0xe8, 0xb1, 0x31, 0xa3, 0xca, 0xe7, 0x41, 0xf9, 0xaa, 0xe8,
+  0xb4, 0xfa, 0x42, 0x85, 0x3b, 0x8e, 0xea, 0xa7, 0xf3, 0x34, 0xa3, 0x86,
+  0xdc, 0x5d, 0x83, 0x9e, 0x35, 0xef, 0x58, 0xf6, 0x50, 0xb6, 0xad, 0x59,
+  0x10, 0x1d, 0x10, 0xc4, 0xae, 0xe8, 0x92, 0xc8, 0xde, 0x86, 0xff, 0x00,
+  0x24, 0xa3, 0xdc, 0x01, 0x49, 0xab, 0x80, 0x77, 0x77, 0x6a, 0xbc, 0xf3,
+  0xd0, 0x0a, 0x28, 0xa2, 0x80, 0x28, 0xa2, 0x8a, 0x00, 0xa2, 0x8a, 0x28,
+  0x04, 0x4e, 0x32, 0xfc, 0x4b, 0x17, 0xfd, 0xaa, 0xb6, 0x7d, 0xf8, 0xa7,
+  0xba, 0x44, 0xe3, 0x2f, 0xc4, 0xb1, 0x7f, 0xda, 0xab, 0x67, 0xdf, 0x8a,
+  0x7b, 0xa0, 0x30, 0x40, 0x3d, 0xe2, 0x8a, 0xcd, 0x15, 0x00, 0x29, 0x33,
+  0x8e, 0x3f, 0x23, 0xd9, 0x77, 0xd1, 0x12, 0x3f, 0x80, 0xd3, 0x9d, 0x26,
+  0x71, 0xc7, 0xe4, 0x7b, 0x2e, 0xfa, 0x22, 0x47, 0xf0, 0x1a, 0x90, 0x47,
+  0x71, 0xcf, 0x06, 0x56, 0x7d, 0xc3, 0x27, 0xed, 0x70, 0xdc, 0x2c, 0x5e,
+  0x22, 0xf6, 0x73, 0xad, 0x12, 0x12, 0x74, 0xa6, 0x65, 0xb5, 0xd5, 0xb2,
+  0x0f, 0x86, 0xfa, 0xa7, 0xfe, 0x2a, 0xae, 0xb8, 0x23, 0xc4, 0xc9, 0x37,
+  0x9b, 0xb3, 0x6f, 0xdd, 0x96, 0xb4, 0xc8, 0xb8, 0xb6, 0xb7, 0x54, 0xd2,
+  0xc6, 0xbb, 0x09, 0x0c, 0xf2, 0xb7, 0x36, 0x31, 0xf4, 0x14, 0x2f, 0x95,
+  0xd4, 0x83, 0xbf, 0x31, 0xe1, 0xd4, 0xf2, 0x93, 0x5f, 0x42, 0xc6, 0x1f,
+  0xcd, 0xdb, 0xf9, 0x83, 0xec, 0xaf, 0x97, 0x38, 0xd5, 0x8d, 0x3b, 0x85,
+  0x71, 0xa2, 0x2d, 0xda, 0xdc, 0x43, 0x16, 0xec, 0xb2, 0x5a, 0x24, 0x44,
+  0x70, 0xab, 0x95, 0xb8, 0xd7, 0xa6, 0xc1, 0x00, 0x2c, 0x9e, 0xe4, 0x48,
+  0x42, 0x94, 0xda, 0xba, 0x8e, 0xae, 0x15, 0x77, 0x23, 0x55, 0x7a, 0x72,
+  0xd2, 0xf7, 0xe0, 0xa5, 0x48, 0x6a, 0x5e, 0xa6, 0x38, 0xf7, 0x89, 0x7b,
+  0x93, 0xc4, 0x77, 0x6e, 0x03, 0xb4, 0x5c, 0x2c, 0x97, 0xdf, 0xe1, 0xba,
+  0x56, 0x02, 0x1a, 0x94, 0x84, 0xfb, 0xf3, 0x2a, 0x3a, 0x27, 0x4a, 0x4a,
+  0x52, 0xea, 0x7b, 0x81, 0xe5, 0x70, 0x78, 0x0a, 0xa0, 0xb8, 0xfb, 0x83,
+  0xad, 0x8b, 0x14, 0x3c, 0xa2, 0x31, 0x71, 0xd5, 0xb6, 0xbe, 0xc2, 0x52,
+  0x95, 0xe6, 0xf3, 0x20, 0x9f, 0x35, 0x69, 0x0a, 0xeb, 0xca, 0x15, 0xe6,
+  0x9e, 0xa7, 0x5d, 0x37, 0xaa, 0xfb, 0x3d, 0xf8, 0x70, 0xb8, 0xa5, 0xc2,
+  0xd5, 0xdb, 0x19, 0x77, 0xb1, 0x93, 0xca, 0x89, 0x76, 0xc7, 0x5d, 0x48,
+  0x2b, 0x8d, 0x21, 0xb5, 0x6d, 0x05, 0x40, 0xef, 0xaa, 0x16, 0x0a, 0x14,
+  0x3d, 0x1c, 0xc2, 0xab, 0xfc, 0x52, 0x20, 0xc9, 0x2c, 0x4f, 0x35, 0x32,
+  0xce, 0xd6, 0xa4, 0x87, 0x21, 0x5e, 0x22, 0x38, 0xb0, 0xdb, 0x4c, 0x3a,
+  0x93, 0xc8, 0xf3, 0x2a, 0x00, 0xa9, 0xd7, 0x14, 0x0f, 0xc1, 0x2a, 0x3a,
+  0xd1, 0x4a, 0x93, 0xaa, 0xe9, 0x8d, 0x3d, 0x59, 0x83, 0x39, 0xe5, 0x53,
+  0x18, 0x99, 0xf1, 0x7f, 0x07, 0xb3, 0x17, 0x70, 0x4e, 0x21, 0x5b, 0x32,
+  0x24, 0x85, 0x29, 0x86, 0x97, 0xc9, 0x29, 0xb1, 0xde, 0xe3, 0x2b, 0x1a,
+  0x58, 0x1e, 0xbd, 0x1d, 0x8f, 0x58, 0x15, 0xf7, 0x8b, 0x96, 0xbb, 0x45,
+  0xeb, 0x29, 0xb3, 0x5f, 0x6d, 0xf2, 0x58, 0x5d, 0xce, 0x74, 0x51, 0x16,
+  0x04, 0xc5, 0xa9, 0x2a, 0x4c, 0x78, 0xaa, 0xdb, 0x8b, 0x75, 0xb4, 0x2b,
+  0xa7, 0x31, 0x1a, 0x1b, 0xf1, 0xe6, 0x48, 0x3b, 0x1b, 0x07, 0xe5, 0xfb,
+  0xcf, 0xe0, 0xd7, 0x73, 0x57, 0x11, 0xe6, 0xe3, 0xf6, 0x9b, 0xf4, 0x36,
+  0x20, 0xf9, 0x11, 0xb8, 0x42, 0x7a, 0x5f, 0x31, 0x51, 0x6f, 0xb4, 0x08,
+  0x2d, 0xab, 0x94, 0x7c, 0x24, 0x92, 0x36, 0x7c, 0x41, 0x07, 0x43, 0x7a,
+  0xab, 0x9f, 0xf0, 0x79, 0xb6, 0x5c, 0x2d, 0xf8, 0x7d, 0xc7, 0x0d, 0xc8,
+  0x63, 0x2a, 0x25, 0xfa, 0xc3, 0x2c, 0x32, 0x64, 0x20, 0xed, 0x4a, 0x68,
+  0xfb, 0xe4, 0x77, 0x1b, 0x59, 0xef, 0x48, 0x3b, 0x09, 0xf6, 0x68, 0x8e,
+  0xfa, 0xbd, 0x18, 0xcd, 0x66, 0x18, 0xe7, 0xea, 0x56, 0xb4, 0xa9, 0xc9,
+  0xa9, 0xa7, 0xc7, 0xd0, 0xb5, 0xaf, 0x37, 0x0b, 0xc6, 0x2f, 0x7d, 0xb6,
+  0x62, 0x98, 0x56, 0x2a, 0xf3, 0x30, 0xe6, 0x48, 0x4b, 0x53, 0xaf, 0xcf,
+  0xc3, 0x5c, 0xb0, 0x1d, 0x52, 0x79, 0xb9, 0x96, 0x94, 0xa9, 0x2a, 0x59,
+  0xf3, 0x81, 0x2e, 0x2d, 0x40, 0x0e, 0xa0, 0x6f, 0x5a, 0x12, 0x7c, 0x40,
+  0x61, 0x4c, 0x5d, 0x31, 0x89, 0x4f, 0xbc, 0xd3, 0xb7, 0x25, 0x97, 0x61,
+  0xc8, 0x5b, 0x4d, 0x72, 0x25, 0xe6, 0xcb, 0x45, 0xc5, 0x2b, 0x94, 0x92,
+  0x40, 0x0b, 0x6d, 0x1a, 0x1b, 0x3a, 0xe7, 0xef, 0xf1, 0xa1, 0x8c, 0xb3,
+  0x29, 0x62, 0x38, 0x61, 0xfb, 0x6d, 0xa6, 0x73, 0xc0, 0x69, 0x32, 0x44,
+  0xa5, 0xb0, 0x17, 0xe8, 0x25, 0xae, 0x45, 0x6b, 0xea, 0x57, 0xf7, 0x77,
+  0x54, 0x59, 0x4c, 0xe9, 0xb7, 0x33, 0x75, 0xbd, 0xcb, 0x6e, 0x54, 0xd0,
+  0xd9, 0x69, 0xb4, 0xb4, 0x8e, 0x46, 0x63, 0x20, 0x9d, 0xa9, 0x2d, 0x8d,
+  0x93, 0xb2, 0x40, 0xda, 0x89, 0x24, 0xe8, 0x77, 0x0e, 0x95, 0x4a, 0x56,
+  0xf5, 0x35, 0xa6, 0xcb, 0x56, 0xaf, 0x4f, 0x46, 0x16, 0xe6, 0xf8, 0x51,
+  0xe7, 0x37, 0x70, 0x5c, 0xcb, 0x2d, 0xc4, 0xc0, 0xb8, 0x3a, 0xda, 0x52,
+  0xb0, 0xa6, 0x43, 0xad, 0x48, 0x09, 0xde, 0x92, 0xa4, 0x6c, 0x1e, 0x61,
+  0xcc, 0x74, 0xa0, 0x47, 0x4e, 0x87, 0x63, 0x40, 0x72, 0x4b, 0x89, 0x2e,
+  0xe6, 0xf3, 0x6f, 0x5f, 0xee, 0x92, 0x6e, 0xaa, 0x69, 0x41, 0x6d, 0xb2,
+  0xb0, 0x1b, 0x8e, 0x85, 0x0e, 0xe2, 0x1a, 0x4f, 0x42, 0x47, 0xeb, 0xf3,
+  0x11, 0x5d, 0x85, 0xc4, 0xb4, 0x0b, 0xcb, 0x58, 0x42, 0x5b, 0x1c, 0xe5,
+  0x65, 0x5d, 0x12, 0x07, 0x5d, 0x93, 0xe0, 0x3a, 0x75, 0xde, 0xbb, 0xaa,
+  0x2f, 0x1a, 0xbb, 0xcb, 0xbf, 0xc6, 0x95, 0x76, 0x90, 0x91, 0xe4, 0xf2,
+  0x26, 0x3a, 0x60, 0xac, 0x34, 0x51, 0xda, 0xc6, 0x07, 0x48, 0x73, 0x5d,
+  0xfe, 0x76, 0x89, 0x07, 0x5d, 0x46, 0x8e, 0xba, 0xd7, 0x67, 0xbb, 0x8f,
+  0xbc, 0xce, 0x39, 0x38, 0x95, 0x49, 0x7b, 0xbc, 0x67, 0x82, 0x03, 0x8d,
+  0xf2, 0x53, 0x12, 0xd0, 0x89, 0xcb, 0x4b, 0x8b, 0x4d, 0xde, 0xc3, 0x3a,
+  0xc8, 0xe6, 0xfa, 0x8e, 0xdd, 0x1a, 0x76, 0x3f, 0xd6, 0x7d, 0xf3, 0x54,
+  0xe9, 0xa2, 0x3a, 0x13, 0xb2, 0x3b, 0xcf, 0xa6, 0x97, 0xf8, 0x98, 0x5a,
+  0x46, 0x04, 0xbb, 0x83, 0xa3, 0x9f, 0xdc, 0x4b, 0xb4, 0x0b, 0x98, 0x04,
+  0x6f, 0xcd, 0x0f, 0x25, 0xb7, 0x3a, 0x1f, 0xd4, 0x5a, 0xa9, 0x85, 0x40,
+  0x85, 0x28, 0x1e, 0xfd, 0x9a, 0xad, 0x18, 0xe9, 0x9c, 0x91, 0x6a, 0xd2,
+  0xd5, 0x18, 0xb3, 0x15, 0x09, 0x9a, 0x59, 0x5d, 0xbd, 0xd8, 0xd4, 0xc4,
+  0x29, 0x02, 0x2d, 0xce, 0x33, 0xc8, 0x97, 0x6d, 0x92, 0x7f, 0xa0, 0x94,
+  0xd1, 0xe6, 0x6d, 0x7e, 0xb1, 0xbe, 0x84, 0x78, 0xa4, 0xa8, 0x78, 0xd4,
+  0xdd, 0x1a, 0xad, 0xe4, 0x93, 0x4d, 0x33, 0x14, 0xda, 0x69, 0xa2, 0x4e,
+  0xda, 0xed, 0xa3, 0x8b, 0xfc, 0x23, 0x91, 0x0e, 0xe9, 0x14, 0xb2, 0xd5,
+  0xce, 0x33, 0x90, 0xae, 0x51, 0x4f, 0x55, 0xc4, 0x92, 0x92, 0x52, 0xe2,
+  0x0f, 0xa1, 0x48, 0x70, 0x6c, 0x1f, 0x52, 0x4d, 0x72, 0x70, 0x13, 0x24,
+  0xb9, 0x5c, 0xb1, 0x99, 0x58, 0xbe, 0x48, 0xe7, 0x3e, 0x51, 0x8b, 0x48,
+  0xf7, 0x32, 0xe6, 0x4f, 0x7b, 0xe1, 0x23, 0xde, 0x64, 0xf5, 0xea, 0x52,
+  0xeb, 0x7c, 0xaa, 0xdf, 0xa7, 0x9b, 0xd1, 0x4b, 0x76, 0x19, 0xa9, 0xc2,
+  0xf8, 0x9e, 0xdc, 0x92, 0xae, 0x4b, 0x1e, 0x58, 0xe2, 0x22, 0xcc, 0x04,
+  0xf9, 0x91, 0xee, 0x21, 0x3a, 0x65, 0xdf, 0x50, 0x75, 0x29, 0xec, 0xcf,
+  0xeb, 0x25, 0xbf, 0x4d, 0x76, 0x71, 0x83, 0x9f, 0x02, 0xcd, 0xac, 0xfc,
+  0x5b, 0x88, 0x85, 0x26, 0xde, 0x90, 0x8b, 0x4e, 0x50, 0x84, 0x0e, 0x8a,
+  0x86, 0xb5, 0x69, 0xa9, 0x07, 0xd2, 0x59, 0x71, 0x43, 0x67, 0xbf, 0x95,
+  0x44, 0x77, 0x0a, 0xf1, 0x6a, 0x41, 0xd3, 0x93, 0x89, 0xec, 0x52, 0x9e,
+  0xb8, 0xa6, 0x5b, 0xe9, 0x24, 0x80, 0x4d, 0x66, 0xbc, 0xb4, 0xb4, 0x38,
+  0xd2, 0x5c, 0x6d, 0x49, 0x5a, 0x16, 0x02, 0x92, 0xa4, 0x9d, 0x82, 0x0f,
+  0x71, 0x15, 0xea, 0xa8, 0x68, 0x14, 0x51, 0x45, 0x00, 0x51, 0x45, 0x14,
+  0x02, 0x27, 0x19, 0x7e, 0x25, 0x8b, 0xfe, 0xd5, 0x5b, 0x3e, 0xfc, 0x53,
+  0xdd, 0x22, 0x71, 0x97, 0xe2, 0x58, 0xbf, 0xed, 0x55, 0xb3, 0xef, 0xc5,
+  0x3d, 0xd0, 0x05, 0x14, 0x51, 0x50, 0x02, 0x93, 0x38, 0xe3, 0xf2, 0x3d,
+  0x97, 0x7d, 0x11, 0x23, 0xf8, 0x0d, 0x39, 0xd2, 0x67, 0x1c, 0x7e, 0x47,
+  0xb2, 0xef, 0xa2, 0x24, 0x7f, 0x01, 0xa9, 0x03, 0x7c, 0x6f, 0x8b, 0xb7,
+  0xf3, 0x07, 0xd9, 0x4a, 0x9c, 0x5f, 0xc2, 0x21, 0x71, 0x0b, 0x01, 0xb9,
+  0xe3, 0x12, 0xc8, 0x69, 0xd7, 0xdb, 0xe7, 0x87, 0x23, 0xf3, 0xa3, 0xc8,
+  0x4f, 0x56, 0xdc, 0x49, 0xef, 0x04, 0x2b, 0xbf, 0x5e, 0x04, 0x8f, 0x1a,
+  0x6b, 0x8d, 0xf1, 0x76, 0xfe, 0x60, 0xfb, 0x2b, 0x66, 0xba, 0xd0, 0x1f,
+  0x30, 0x70, 0x4f, 0x2e, 0xb8, 0x31, 0x3d, 0xbf, 0x75, 0x12, 0x63, 0xce,
+  0x7a, 0x5b, 0xb0, 0xae, 0xb1, 0xd6, 0x75, 0xe4, 0xf7, 0x86, 0x47, 0xbf,
+  0x7b, 0x13, 0x25, 0xb4, 0xf6, 0xc3, 0xd2, 0xb4, 0x3d, 0xaf, 0x0a, 0x70,
+  0xe2, 0x45, 0xa6, 0x35, 0x83, 0x38, 0x87, 0x96, 0xc6, 0x49, 0x66, 0xcd,
+  0x92, 0xad, 0xb8, 0xb3, 0xdc, 0x46, 0x93, 0xe4, 0xb3, 0xb5, 0xca, 0xc4,
+  0x8e, 0xbb, 0xe5, 0xed, 0x13, 0xef, 0x2a, 0x3e, 0x9e, 0xcf, 0xd3, 0x4a,
+  0xff, 0x00, 0x84, 0x36, 0x3a, 0xac, 0x53, 0x89, 0x51, 0xf2, 0xc8, 0x6f,
+  0x26, 0x0d, 0xa3, 0x2c, 0x2c, 0xdb, 0xee, 0x2f, 0x9e, 0x8d, 0xc2, 0xba,
+  0x34, 0x79, 0xa0, 0xcc, 0x57, 0x4e, 0x83, 0x98, 0x04, 0x28, 0xfe, 0x81,
+  0x5f, 0xe9, 0x55, 0x8b, 0x89, 0x49, 0xb6, 0xf1, 0x13, 0x02, 0xb8, 0x63,
+  0x77, 0x98, 0xab, 0x65, 0x32, 0xdb, 0x76, 0x24, 0xc8, 0x8a, 0x50, 0xed,
+  0x21, 0xc8, 0x41, 0xd3, 0x8d, 0xfa, 0x94, 0x85, 0x8e, 0x64, 0x9f, 0x50,
+  0x23, 0xc2, 0xba, 0x21, 0x37, 0xa7, 0x57, 0x58, 0xfd, 0x0e, 0x7a, 0x90,
+  0x5a, 0xb1, 0xd2, 0x5f, 0x51, 0x53, 0x88, 0x96, 0xb9, 0x8a, 0x11, 0x72,
+  0x2b, 0x4c, 0x11, 0x3e, 0x75, 0xb4, 0x38, 0x87, 0xa0, 0x68, 0x1f, 0x2f,
+  0x86, 0xe6, 0xbb, 0x66, 0x3a, 0xf4, 0x2a, 0xf3, 0x52, 0xb4, 0x6f, 0xf3,
+  0x90, 0x07, 0x8d, 0x6b, 0xc1, 0xee, 0xd6, 0xe7, 0x25, 0x88, 0xd6, 0xd9,
+  0xce, 0x4b, 0xb4, 0xce, 0x8a, 0x89, 0x36, 0x97, 0x16, 0x95, 0x29, 0x48,
+  0x4e, 0xd6, 0x1c, 0x60, 0xac, 0xf5, 0xf7, 0xb2, 0x9d, 0xf2, 0x28, 0xf3,
+  0x27, 0x98, 0x8f, 0x01, 0x52, 0x38, 0x3c, 0xeb, 0x8b, 0x90, 0xe4, 0xd9,
+  0x6f, 0xaa, 0xdd, 0xfa, 0xc8, 0xf1, 0x83, 0x71, 0x3d, 0xdd, 0xa9, 0x00,
+  0x16, 0xdf, 0x1f, 0xaa, 0xeb, 0x7c, 0xab, 0x07, 0xd3, 0xcc, 0x2b, 0x92,
+  0xe3, 0x88, 0x3c, 0x8b, 0x9c, 0x9b, 0xae, 0x2d, 0x7e, 0x91, 0x8f, 0x4b,
+  0x98, 0xae, 0x79, 0xad, 0xb7, 0x1d, 0x12, 0x22, 0xc9, 0x5f, 0xf5, 0x8a,
+  0x61, 0x5d, 0x03, 0x9f, 0xac, 0x92, 0x92, 0x7c, 0x77, 0x5e, 0x8a, 0xef,
+  0x62, 0x71, 0x3c, 0xe6, 0xf1, 0xdd, 0x90, 0xd5, 0xcc, 0x90, 0x4a, 0x7d,
+  0x03, 0x7a, 0xf4, 0xd6, 0x36, 0x08, 0x1d, 0x41, 0x1d, 0xfb, 0xdf, 0x4a,
+  0x53, 0xb8, 0x31, 0x79, 0xc7, 0x6d, 0x89, 0xba, 0x19, 0xf3, 0xb2, 0x0e,
+  0xc5, 0x3c, 0xd7, 0x36, 0x94, 0x84, 0x07, 0x1e, 0x46, 0xce, 0xdd, 0x65,
+  0x09, 0x00, 0x25, 0x69, 0xd8, 0xf3, 0x07, 0x45, 0x25, 0x24, 0x7c, 0x2e,
+  0xa6, 0x4e, 0xcd, 0x78, 0xb7, 0x5f, 0x2d, 0x2d, 0xdd, 0xad, 0x13, 0xd9,
+  0x9b, 0x09, 0xf4, 0x85, 0x21, 0xe6, 0x55, 0xb4, 0xe8, 0xf5, 0x3b, 0xf1,
+  0x49, 0xee, 0x1a, 0x20, 0x1a, 0xbe, 0xbd, 0xf0, 0xca, 0x69, 0xd8, 0xd5,
+  0x9b, 0x65, 0x10, 0x31, 0x9b, 0x58, 0x97, 0x35, 0x89, 0x92, 0xbb, 0x55,
+  0x16, 0xd9, 0x62, 0x2c, 0x72, 0xea, 0xdd, 0x57, 0xa3, 0x5d, 0xc9, 0x1e,
+  0x92, 0xa2, 0x07, 0x77, 0xb2, 0xa0, 0x31, 0x5b, 0x86, 0x7d, 0x7e, 0xbe,
+  0xc7, 0x9f, 0x73, 0x85, 0x17, 0x1d, 0xb0, 0x20, 0x29, 0x42, 0x1b, 0x88,
+  0x0b, 0x95, 0x2b, 0xa1, 0x09, 0x04, 0xab, 0xaa, 0x52, 0x0e, 0x89, 0xf3,
+  0x52, 0x7d, 0x1b, 0xef, 0xa7, 0x1e, 0x77, 0x5b, 0x49, 0xf3, 0x94, 0x95,
+  0x12, 0x41, 0x00, 0xf8, 0xfe, 0x77, 0xd5, 0xbe, 0x83, 0x7e, 0x83, 0x5c,
+  0x71, 0x6d, 0xb1, 0x63, 0x4c, 0x7e, 0x4c, 0x66, 0xb9, 0x64, 0x48, 0x57,
+  0xbe, 0xbc, 0x56, 0x56, 0xa5, 0x1d, 0x6c, 0x9d, 0x92, 0x74, 0x94, 0x8e,
+  0xe0, 0x08, 0x03, 0xaf, 0xa2, 0xab, 0x24, 0xdb, 0xce, 0x4b, 0x45, 0xa4,
+  0xb1, 0x83, 0x4f, 0x10, 0xdc, 0x67, 0xf1, 0x6b, 0x9a, 0xa5, 0xc2, 0x39,
+  0x3d, 0xc2, 0x92, 0x4a, 0x89, 0x1a, 0x4a, 0xb5, 0xe6, 0x7f, 0xd4, 0x05,
+  0x78, 0x91, 0x9b, 0x62, 0x50, 0x18, 0x40, 0x9d, 0x93, 0xda, 0x1b, 0x75,
+  0x28, 0x1d, 0xa2, 0x04, 0xa4, 0x29, 0x49, 0x3a, 0xea, 0x08, 0x49, 0x24,
+  0x52, 0xd5, 0xd6, 0xee, 0xde, 0x4f, 0x2a, 0x0d, 0xa2, 0x03, 0x25, 0xdc,
+  0x57, 0xdd, 0x46, 0x99, 0xba, 0xdc, 0x92, 0x90, 0x59, 0x79, 0xf4, 0x92,
+  0xe3, 0x51, 0x1b, 0x27, 0xa2, 0xd0, 0x5c, 0x6d, 0x01, 0x6a, 0x1d, 0x36,
+  0x94, 0x24, 0x1d, 0xa8, 0xd4, 0x9e, 0x4b, 0x17, 0x12, 0xc7, 0x67, 0x22,
+  0xe6, 0xed, 0xe7, 0xf9, 0x3d, 0x71, 0x90, 0xb1, 0xd8, 0xf9, 0x1a, 0x00,
+  0x90, 0xfe, 0xcf, 0xc1, 0x42, 0x5a, 0x48, 0x75, 0x67, 0xd0, 0x3c, 0xf4,
+  0xfa, 0x50, 0x77, 0x58, 0x4a, 0x72, 0x52, 0x94, 0xe2, 0xb2, 0x74, 0x46,
+  0x11, 0x71, 0x8c, 0x24, 0xf0, 0x6d, 0x1c, 0x4e, 0xc0, 0xd5, 0xae, 0x4c,
+  0x8d, 0x85, 0xef, 0xbb, 0x91, 0x87, 0x95, 0xf6, 0x20, 0xd7, 0xa3, 0xc4,
+  0xdc, 0x05, 0x09, 0x2a, 0x7b, 0x27, 0x87, 0x1d, 0x20, 0xeb, 0x9a, 0x42,
+  0x56, 0xc8, 0x27, 0xd0, 0x0a, 0xd2, 0x36, 0x7d, 0x5d, 0xf5, 0x2d, 0x64,
+  0xfc, 0x70, 0x64, 0x6c, 0xa1, 0xa8, 0x52, 0x17, 0x8f, 0xc0, 0x0a, 0x20,
+  0x5d, 0x6f, 0x51, 0x80, 0x9a, 0xea, 0x37, 0xd1, 0x49, 0x86, 0x83, 0xca,
+  0x85, 0x6b, 0xbc, 0xb8, 0x47, 0xa7, 0x90, 0x77, 0x54, 0xef, 0xf2, 0x67,
+  0x06, 0xc3, 0xe5, 0xc6, 0xbc, 0xe5, 0x97, 0x69, 0x37, 0xcb, 0xe6, 0xf5,
+  0x1a, 0x65, 0xe5, 0xf3, 0x2e, 0x49, 0x56, 0xc1, 0xe5, 0x8e, 0xc0, 0x1a,
+  0x49, 0xdf, 0x83, 0x48, 0x07, 0xdb, 0x59, 0x4a, 0xee, 0x4b, 0xc8, 0xd2,
+  0x36, 0x91, 0x7e, 0x68, 0x4c, 0x75, 0xbb, 0x97, 0x12, 0x63, 0x37, 0x67,
+  0xb3, 0x63, 0xb7, 0x01, 0x61, 0x90, 0xfb, 0x2a, 0x97, 0x79, 0x9c, 0x83,
+  0x15, 0xae, 0xc9, 0x2e, 0x25, 0x64, 0xc7, 0x42, 0xbd, 0xf1, 0xc5, 0x1e,
+  0x5d, 0x05, 0x04, 0x84, 0x83, 0xa3, 0xba, 0xbb, 0xef, 0x76, 0xd8, 0x37,
+  0x9b, 0x34, 0xbb, 0x4d, 0xd2, 0x23, 0x72, 0xe1, 0x4c, 0x61, 0x4c, 0x48,
+  0x65, 0xc1, 0xb4, 0xb8, 0x85, 0x0e, 0x55, 0x24, 0x8f, 0x58, 0x26, 0x93,
+  0x66, 0x64, 0x99, 0x35, 0xe1, 0x61, 0x9b, 0x4c, 0x36, 0xb1, 0xf8, 0xca,
+  0xde, 0xa4, 0x4e, 0x6f, 0xb7, 0x98, 0xb1, 0xaf, 0xe8, 0xe3, 0x24, 0xe9,
+  0x1d, 0x47, 0x7b, 0xaa, 0x1e, 0xb4, 0x50, 0x71, 0x3b, 0x84, 0xc0, 0xa7,
+  0x1f, 0xbe, 0xe5, 0x6e, 0x38, 0x76, 0x4b, 0xcb, 0xbb, 0x79, 0x31, 0x3e,
+  0xc6, 0xda, 0x48, 0x40, 0x1e, 0xa2, 0x2b, 0x9e, 0xa3, 0x9d, 0x47, 0xaa,
+  0x47, 0x45, 0x35, 0x0a, 0x6b, 0x4a, 0x22, 0xb8, 0x0b, 0x73, 0x99, 0x67,
+  0x55, 0xdb, 0x85, 0x37, 0xd9, 0x2a, 0x7a, 0xe7, 0x8a, 0xa9, 0x29, 0x84,
+  0xfb, 0xa7, 0xce, 0x99, 0x6d, 0x5e, 0xcc, 0x77, 0x7d, 0x65, 0x23, 0x6d,
+  0xab, 0x5d, 0xc5, 0x03, 0xd3, 0x56, 0xb0, 0xee, 0xaf, 0x9c, 0x38, 0xca,
+  0xbc, 0x8f, 0x87, 0x79, 0x26, 0x3b, 0xc4, 0x19, 0x6e, 0xc9, 0xbb, 0x35,
+  0x69, 0x77, 0xb0, 0x33, 0x4b, 0x68, 0x0f, 0xbd, 0x05, 0xdf, 0xcb, 0x43,
+  0x91, 0xc8, 0x02, 0x54, 0xb4, 0xe9, 0x2e, 0x36, 0xb0, 0x00, 0x25, 0x2a,
+  0x07, 0xa9, 0x05, 0x5f, 0x42, 0xdb, 0x27, 0x45, 0xb9, 0x5b, 0x63, 0x5c,
+  0x60, 0xbe, 0xdc, 0x88, 0x92, 0x99, 0x43, 0xcc, 0x3a, 0x83, 0xb4, 0xad,
+  0x0b, 0x00, 0xa5, 0x43, 0xd4, 0x41, 0x06, 0xb1, 0x36, 0x3a, 0xa8, 0xa2,
+  0x8a, 0x00, 0xa2, 0x8a, 0x28, 0x04, 0x4e, 0x32, 0xfc, 0x4b, 0x17, 0xfd,
+  0xaa, 0xb6, 0x7d, 0xf8, 0xa7, 0xba, 0x44, 0xe3, 0x2f, 0xc4, 0xb1, 0x7f,
+  0xda, 0xab, 0x67, 0xdf, 0x8a, 0x7b, 0xa0, 0x0a, 0x28, 0xa2, 0xa0, 0x05,
+  0x26, 0x71, 0xc7, 0xe4, 0x7b, 0x2e, 0xfa, 0x22, 0x47, 0xf0, 0x1a, 0x73,
+  0xa4, 0xce, 0x38, 0xfc, 0x8f, 0x65, 0xdf, 0x44, 0x48, 0xfe, 0x03, 0x52,
+  0x06, 0xf8, 0xdf, 0x17, 0x6f, 0xe6, 0x0f, 0xb2, 0xb6, 0x56, 0xb8, 0xdf,
+  0x17, 0x6f, 0xe6, 0x0f, 0xb2, 0xb6, 0x50, 0x0b, 0xbc, 0x47, 0xc5, 0x2d,
+  0xd9, 0xc6, 0x15, 0x77, 0xc5, 0xae, 0xa8, 0xdc, 0x5b, 0x8c, 0x72, 0xd7,
+  0x37, 0x79, 0x6d, 0x7d, 0xe8, 0x58, 0xf5, 0xa5, 0x40, 0x28, 0x7b, 0x2b,
+  0xe7, 0x0e, 0x13, 0xe4, 0x57, 0x3b, 0x3e, 0x4a, 0x18, 0xbd, 0x2b, 0xb0,
+  0xbd, 0x46, 0x98, 0x8c, 0x7f, 0x22, 0x04, 0xf4, 0x33, 0x9b, 0x49, 0xf2,
+  0x29, 0x87, 0xd2, 0x99, 0x0d, 0x20, 0xb4, 0x4f, 0x8a, 0x9b, 0x41, 0x3f,
+  0x0b, 0xaf, 0xd6, 0x04, 0x6c, 0xee, 0xbe, 0x75, 0xfc, 0x28, 0x71, 0x88,
+  0x96, 0x4c, 0x92, 0x27, 0x10, 0x9c, 0x4b, 0x8d, 0xd8, 0xee, 0x8c, 0x26,
+  0xc5, 0x95, 0xa9, 0xad, 0xed, 0xa6, 0x56, 0xa0, 0x63, 0xcd, 0x1a, 0xfc,
+  0xe6, 0x5d, 0x08, 0x3b, 0xef, 0xd2, 0x52, 0x3c, 0x4d, 0x5a, 0x12, 0x70,
+  0x92, 0x68, 0xac, 0xe2, 0xa7, 0x1c, 0x31, 0xa3, 0x8b, 0x0d, 0xb5, 0x69,
+  0x97, 0x6e, 0xe2, 0x9c, 0x24, 0x94, 0xc4, 0x6d, 0xa4, 0xc1, 0xc8, 0x50,
+  0x91, 0xbf, 0xe6, 0x85, 0x5e, 0x63, 0xe7, 0xd2, 0x59, 0x70, 0x92, 0x7f,
+  0x51, 0x6b, 0xf4, 0x0a, 0x91, 0xd8, 0x52, 0x76, 0x0a, 0x54, 0x9d, 0x7c,
+  0x20, 0x76, 0x35, 0xe9, 0xad, 0x1c, 0x1d, 0xbf, 0x2e, 0xfd, 0x65, 0x9d,
+  0x8e, 0xe4, 0xad, 0x32, 0xed, 0xc1, 0x85, 0xb9, 0x6e, 0xbb, 0x33, 0xa0,
+  0x5b, 0x71, 0xd0, 0x81, 0xb5, 0x8f, 0x02, 0xdb, 0xcd, 0xa9, 0x2e, 0x27,
+  0xc0, 0x85, 0x74, 0xa4, 0x76, 0xe7, 0x5f, 0x31, 0x0b, 0x83, 0xdc, 0x32,
+  0x85, 0x01, 0xcb, 0xa5, 0xee, 0x17, 0x5b, 0x43, 0xf2, 0x02, 0xbb, 0x03,
+  0x6e, 0x27, 0x4d, 0x3e, 0xfb, 0x80, 0x75, 0x0d, 0x7e, 0x49, 0x40, 0x0e,
+  0x65, 0x29, 0x03, 0x5d, 0xfb, 0x1d, 0xf4, 0x2a, 0x28, 0x37, 0x1e, 0x8f,
+  0x74, 0x70, 0x56, 0xa6, 0xe6, 0xb5, 0x75, 0x5b, 0x32, 0x53, 0x89, 0x79,
+  0x14, 0xab, 0x3c, 0x38, 0xb6, 0xdb, 0x53, 0xed, 0xb1, 0x78, 0xba, 0x2d,
+  0xc4, 0xc7, 0x75, 0x63, 0x98, 0x46, 0x69, 0x09, 0x2a, 0x7a, 0x41, 0x4f,
+  0xe7, 0x72, 0xa0, 0x69, 0x23, 0xc5, 0x45, 0x20, 0xf4, 0xde, 0x97, 0xb1,
+  0xcc, 0x42, 0xd5, 0x6f, 0xc9, 0x67, 0x58, 0x12, 0xbb, 0x94, 0x09, 0x26,
+  0x3a, 0x67, 0xdb, 0xa7, 0xc7, 0x94, 0x5a, 0x94, 0xa6, 0xd4, 0x40, 0x79,
+  0xb7, 0x14, 0x9f, 0x35, 0xc2, 0x97, 0x7a, 0xe9, 0x41, 0x40, 0x07, 0x07,
+  0x80, 0x15, 0x1d, 0x27, 0x14, 0x5c, 0x4e, 0x28, 0xb7, 0x2a, 0x7c, 0xb7,
+  0xae, 0x72, 0x9e, 0xb4, 0x36, 0xb9, 0x97, 0x17, 0xbc, 0xd0, 0x49, 0x9c,
+  0xc8, 0x52, 0x52, 0x37, 0xca, 0xdb, 0x69, 0x6d, 0x04, 0x04, 0xfa, 0x09,
+  0x24, 0x92, 0x49, 0xa6, 0xb7, 0xef, 0x71, 0x32, 0x1b, 0xfc, 0x37, 0x70,
+  0xfb, 0x4c, 0xec, 0xaa, 0xe7, 0x6e, 0x53, 0xa8, 0x4b, 0x90, 0x48, 0x44,
+  0x36, 0xfb, 0x44, 0x72, 0xad, 0x0e, 0xc9, 0x5f, 0xbd, 0x81, 0xd0, 0x1d,
+  0x27, 0x99, 0x5b, 0x48, 0xe9, 0xd2, 0xb5, 0x72, 0x59, 0x72, 0x9e, 0xd8,
+  0x32, 0x51, 0x78, 0x4a, 0x3b, 0xe4, 0xda, 0xac, 0x77, 0x32, 0x6d, 0x7c,
+  0x90, 0xb3, 0xc4, 0xad, 0xa1, 0xa0, 0x8f, 0x2a, 0xb2, 0x32, 0xeb, 0x80,
+  0x0e, 0xef, 0x39, 0x2a, 0x40, 0x3f, 0xf2, 0xee, 0x96, 0xee, 0xb1, 0x6d,
+  0x2f, 0x5c, 0x7d, 0xc8, 0xbe, 0xe4, 0xb7, 0xfc, 0xe6, 0xe6, 0x01, 0xff,
+  0x00, 0x41, 0x5a, 0x99, 0x4a, 0x50, 0xaf, 0xf7, 0xad, 0xb0, 0x12, 0x00,
+  0xf5, 0xba, 0xb0, 0x9f, 0x4d, 0x58, 0x8d, 0xf0, 0xf2, 0xf7, 0x75, 0x8a,
+  0xe4, 0xbe, 0x21, 0xe5, 0x48, 0x83, 0x6e, 0x09, 0xe6, 0x76, 0xd7, 0x65,
+  0x71, 0x51, 0x98, 0x09, 0x1e, 0x0f, 0x49, 0x56, 0x9c, 0x58, 0xd7, 0x7f,
+  0x2f, 0x66, 0x2a, 0x52, 0xd7, 0x7d, 0xb0, 0x58, 0x2d, 0xf1, 0xac, 0x9c,
+  0x35, 0xc5, 0x11, 0x2d, 0x97, 0x5d, 0x0c, 0xb2, 0xb8, 0xe9, 0x4c, 0x68,
+  0x6a, 0x57, 0x5e, 0x65, 0x17, 0x48, 0xdb, 0xba, 0x00, 0x92, 0xa4, 0x25,
+  0x7e, 0x3b, 0x3b, 0xae, 0x6a, 0x97, 0x31, 0xe2, 0x08, 0xea, 0xa7, 0x6b,
+  0x27, 0xbc, 0xc8, 0x3b, 0x4e, 0x0b, 0x9b, 0x5f, 0xed, 0xe9, 0x83, 0x74,
+  0x7e, 0x1e, 0x13, 0x61, 0xd2, 0x12, 0x2d, 0xd6, 0xc0, 0x87, 0xe6, 0x14,
+  0x21, 0x5c, 0xc9, 0x05, 0xd2, 0x3b, 0x26, 0x74, 0x40, 0x23, 0xb3, 0x4a,
+  0x88, 0xf0, 0x50, 0xa9, 0x9b, 0x24, 0x6e, 0x1d, 0x60, 0xb2, 0xe4, 0xb7,
+  0x8d, 0xda, 0x9f, 0xbc, 0x5f, 0xca, 0x7f, 0x9c, 0xae, 0x1a, 0x55, 0x3e,
+  0x7b, 0x87, 0xb8, 0xf6, 0xaf, 0x28, 0x9e, 0x4d, 0x9f, 0x05, 0xa9, 0x23,
+  0xd5, 0x5b, 0x9d, 0xb1, 0x5f, 0x72, 0x85, 0x2c, 0x5e, 0xef, 0x0b, 0x93,
+  0x10, 0x9d, 0x2a, 0x34, 0x5e, 0x68, 0xf0, 0xfd, 0x69, 0xd0, 0x3d, 0xa3,
+  0xa0, 0x1f, 0x15, 0x2b, 0x94, 0xfe, 0x88, 0xae, 0xe6, 0xda, 0xc5, 0x6c,
+  0xcd, 0x1b, 0x70, 0x9a, 0x48, 0x6b, 0x6a, 0x54, 0x6b, 0x73, 0x2a, 0xe4,
+  0x6b, 0x43, 0x64, 0xa9, 0x0c, 0xa4, 0xf2, 0xf4, 0xf1, 0x3a, 0xac, 0x24,
+  0x9b, 0x79, 0x9b, 0x36, 0x86, 0x23, 0xb4, 0x11, 0xc8, 0xc5, 0xd3, 0x2b,
+  0xc9, 0xdd, 0x72, 0x3b, 0x6f, 0x0c, 0x70, 0xa0, 0x02, 0xe4, 0x06, 0xd2,
+  0x0c, 0xe4, 0xa0, 0xec, 0x05, 0x29, 0xc7, 0x13, 0xca, 0x90, 0x7a, 0xe8,
+  0xb6, 0x95, 0xf5, 0xfc, 0xfa, 0x85, 0x98, 0xc4, 0x1c, 0x5a, 0xfb, 0x3d,
+  0xc5, 0xa1, 0x8f, 0x29, 0x66, 0x10, 0x93, 0x21, 0xd9, 0x4b, 0x70, 0x3f,
+  0x3c, 0x12, 0x41, 0x6d, 0x12, 0x16, 0x76, 0xa2, 0x34, 0x8f, 0x37, 0x67,
+  0xaa, 0xc0, 0x09, 0x14, 0xe9, 0x76, 0xb6, 0x48, 0x7a, 0xd6, 0xd5, 0xd2,
+  0xd1, 0x2b, 0xca, 0x67, 0x43, 0x49, 0x91, 0x6d, 0x73, 0x63, 0xdf, 0x50,
+  0x40, 0x25, 0x95, 0x1e, 0xe5, 0x21, 0x60, 0x01, 0xea, 0x3c, 0xa7, 0xc0,
+  0x54, 0xcc, 0x05, 0x5b, 0x2f, 0x50, 0xe0, 0x5d, 0x9a, 0x65, 0xa7, 0xd1,
+  0xc8, 0x1d, 0x8c, 0xb7, 0x10, 0x0a, 0x9a, 0xe6, 0x1d, 0x75, 0xe2, 0x95,
+  0x78, 0x1f, 0x66, 0xaa, 0x9a, 0xb4, 0xec, 0x8b, 0xe9, 0xd5, 0xbb, 0x23,
+  0xaf, 0xb2, 0x11, 0x69, 0xc3, 0xe4, 0xdc, 0xed, 0x4c, 0xa1, 0x9e, 0x46,
+  0x12, 0xe9, 0x51, 0x68, 0x92, 0x86, 0xfa, 0x73, 0x2c, 0xa4, 0xe8, 0x9e,
+  0x54, 0x95, 0x2b, 0x47, 0xd1, 0x48, 0x37, 0x34, 0x4c, 0x91, 0x2a, 0x6b,
+  0xa8, 0x8f, 0xe5, 0x51, 0xa2, 0x2f, 0x4e, 0x4f, 0xba, 0xca, 0x71, 0x29,
+  0x3e, 0x71, 0x1c, 0xfc, 0xfc, 0xe8, 0x42, 0x46, 0x87, 0x37, 0xbd, 0x27,
+  0xa2, 0x4a, 0x0f, 0x52, 0x48, 0x16, 0xeb, 0x8d, 0xa1, 0xd6, 0xd6, 0xdb,
+  0x89, 0x0a, 0x42, 0x81, 0x0a, 0x4a, 0xba, 0x82, 0x0f, 0x81, 0x07, 0xec,
+  0xa5, 0x17, 0x31, 0x1c, 0x26, 0xca, 0x91, 0x71, 0x9e, 0xdb, 0x48, 0x8d,
+  0x0c, 0x73, 0x36, 0x67, 0xcb, 0x52, 0xd8, 0x8c, 0x3d, 0x21, 0x2b, 0x57,
+  0x22, 0x40, 0xf0, 0x3e, 0x15, 0x55, 0xbf, 0x24, 0xf8, 0x78, 0x34, 0x5d,
+  0x2c, 0xf2, 0x32, 0x7e, 0x14, 0x5c, 0xec, 0x93, 0x16, 0xa9, 0x2e, 0xbf,
+  0x19, 0xe6, 0xa2, 0xc8, 0x74, 0xef, 0xb6, 0xe5, 0x24, 0xc7, 0x78, 0xfa,
+  0x49, 0xd3, 0x6a, 0x27, 0xc4, 0xee, 0x90, 0x7f, 0x06, 0x7b, 0xfa, 0xac,
+  0xee, 0x1e, 0x1c, 0x5c, 0x14, 0xa4, 0xb0, 0xa8, 0x2d, 0xde, 0xb1, 0xb5,
+  0xac, 0xec, 0x39, 0x01, 0xf1, 0xcc, 0xa6, 0x01, 0x3d, 0xea, 0x65, 0xc2,
+  0xa4, 0x7c, 0xde, 0x5f, 0x0a, 0x73, 0xb9, 0xe6, 0x17, 0x3c, 0x9a, 0x03,
+  0xf0, 0x78, 0x7d, 0x67, 0x93, 0x30, 0x3c, 0x92, 0xd2, 0x6f, 0x32, 0x47,
+  0x61, 0x09, 0xad, 0x82, 0x39, 0xd0, 0x55, 0xe7, 0xbb, 0xaf, 0xd4, 0x49,
+  0x1e, 0xba, 0x82, 0xe2, 0xa6, 0x0f, 0x2a, 0xd1, 0xc3, 0xfc, 0x76, 0xf3,
+  0x88, 0x23, 0xb7, 0xc8, 0x70, 0x26, 0xd1, 0x22, 0xdf, 0xe6, 0xf2, 0xaa,
+  0x63, 0x0d, 0xa0, 0x26, 0x43, 0x0a, 0xd7, 0xf5, 0x8d, 0x83, 0xd3, 0xf4,
+  0x80, 0xf4, 0xd1, 0xac, 0x12, 0x9e, 0x4b, 0x84, 0x51, 0x50, 0xf8, 0x6e,
+  0x45, 0x6c, 0xca, 0xf1, 0x6b, 0x6e, 0x47, 0x67, 0x7b, 0xb6, 0x81, 0x71,
+  0x8e, 0x99, 0x0c, 0xab, 0x5d, 0x74, 0xa1, 0xdc, 0x47, 0x82, 0x81, 0xe8,
+  0x47, 0x81, 0x06, 0xa6, 0x07, 0x75, 0x41, 0x21, 0x45, 0x14, 0x50, 0x08,
+  0x9c, 0x65, 0xf8, 0x96, 0x2f, 0xfb, 0x55, 0x6c, 0xfb, 0xf1, 0x4f, 0x74,
+  0x89, 0xc6, 0x5f, 0x89, 0x62, 0xff, 0x00, 0xb5, 0x56, 0xcf, 0xbf, 0x14,
+  0xf7, 0x40, 0x1e, 0x26, 0x8a, 0xf2, 0xa4, 0x82, 0x7a, 0xd1, 0x4c, 0x11,
+  0x94, 0x7a, 0xa4, 0xce, 0x38, 0xfc, 0x8f, 0x65, 0xdf, 0x44, 0x48, 0xfe,
+  0x03, 0x4e, 0x74, 0x99, 0xc7, 0x1f, 0x91, 0xec, 0xbb, 0xe8, 0x89, 0x1f,
+  0xc0, 0x68, 0x48, 0xdf, 0x1b, 0xe2, 0xed, 0xfc, 0xc1, 0xf6, 0x56, 0xca,
+  0xd7, 0x1b, 0xe2, 0xed, 0xfc, 0xc1, 0xf6, 0x56, 0xca, 0x00, 0xa8, 0xdc,
+  0xa2, 0xc9, 0x6e, 0xc8, 0xf1, 0xe9, 0xf6, 0x1b, 0xb3, 0x01, 0xf8, 0x37,
+  0x06, 0x17, 0x1d, 0xf6, 0xcf, 0x8a, 0x54, 0x34, 0x75, 0xe8, 0x23, 0xbc,
+  0x1f, 0x02, 0x05, 0x49, 0x50, 0x46, 0xe8, 0x0f, 0x98, 0x78, 0x35, 0x12,
+  0xe5, 0x6a, 0xbf, 0x5c, 0x71, 0xa9, 0x31, 0x5e, 0x93, 0x96, 0xe3, 0x4b,
+  0x6a, 0xd3, 0x3e, 0x40, 0x92, 0x1b, 0x4c, 0x8b, 0x5a, 0x52, 0xb7, 0x21,
+  0x4d, 0xe4, 0x57, 0xe5, 0x54, 0x01, 0x4b, 0x5b, 0x1d, 0x42, 0x4a, 0x7b,
+  0xf5, 0xd2, 0xea, 0xbe, 0x63, 0x16, 0x6c, 0xe6, 0x14, 0x2b, 0x84, 0x97,
+  0x26, 0x41, 0xb9, 0x45, 0x4a, 0x90, 0xc4, 0xe8, 0x2f, 0x76, 0x6f, 0xb4,
+  0x15, 0xae, 0x64, 0x83, 0xd5, 0x2a, 0x42, 0xb4, 0x0f, 0x2a, 0x82, 0x87,
+  0xab, 0x75, 0x5b, 0xfe, 0x14, 0x56, 0x24, 0x58, 0xe6, 0xc0, 0xe2, 0x9c,
+  0x78, 0x4b, 0x95, 0x12, 0x2b, 0x0a, 0xb4, 0xe5, 0x31, 0x5a, 0xe8, 0xa9,
+  0x76, 0xb7, 0xcf, 0x2a, 0x95, 0xd3, 0xbd, 0x4d, 0x28, 0xf3, 0x27, 0xd0,
+  0x48, 0x3e, 0x15, 0xd7, 0xc3, 0xec, 0xe2, 0x4d, 0x9b, 0x1a, 0xbd, 0x43,
+  0x9e, 0xfa, 0x27, 0xdc, 0xed, 0x2c, 0x37, 0xd9, 0xbe, 0x0e, 0xd1, 0x3d,
+  0x0e, 0x24, 0x2a, 0x24, 0x90, 0x7f, 0x45, 0xd4, 0xa9, 0x3c, 0xc7, 0xc1,
+  0x41, 0x60, 0xf7, 0x56, 0xf1, 0x7a, 0xa1, 0x8e, 0xab, 0x74, 0x63, 0x35,
+  0x89, 0xe7, 0xa3, 0xd9, 0x93, 0x33, 0xb8, 0x67, 0x8a, 0x42, 0x3e, 0xeb,
+  0xf1, 0x13, 0x25, 0x95, 0x7e, 0x65, 0xae, 0x8d, 0xb5, 0x73, 0x75, 0xb6,
+  0x22, 0x0d, 0x1d, 0x8d, 0xb0, 0xd8, 0x4a, 0x5d, 0x57, 0x41, 0xf0, 0xf9,
+  0xb6, 0x7b, 0x85, 0x4b, 0xff, 0x00, 0x29, 0x6e, 0x0e, 0x46, 0x6a, 0xdf,
+  0x88, 0x63, 0xed, 0x5b, 0xa1, 0x25, 0x01, 0x2c, 0x3b, 0x35, 0x82, 0xde,
+  0x93, 0xe1, 0xd9, 0xc5, 0x4e, 0x95, 0xad, 0x77, 0x73, 0x96, 0xfd, 0x84,
+  0x57, 0xa4, 0x5a, 0x62, 0xc1, 0x71, 0xe9, 0xf7, 0x29, 0x4d, 0xbd, 0x36,
+  0x1b, 0x7c, 0xf3, 0xaf, 0x52, 0x92, 0x14, 0xe3, 0x67, 0x5b, 0x28, 0x64,
+  0x11, 0xef, 0x69, 0xeb, 0xa0, 0x94, 0xf5, 0xf4, 0xec, 0x9d, 0x9e, 0xaf,
+  0x76, 0xcd, 0xa2, 0x3a, 0x1e, 0x8d, 0x8f, 0xad, 0xa6, 0x1d, 0x58, 0x4b,
+  0x66, 0x64, 0xa4, 0xb3, 0x26, 0x5a, 0xbf, 0x45, 0xa6, 0xc8, 0x25, 0x4a,
+  0xd0, 0xe8, 0x95, 0x14, 0x13, 0xd0, 0x55, 0x5a, 0x4b, 0x79, 0xee, 0xc9,
+  0x59, 0x7b, 0x43, 0x64, 0x29, 0xdd, 0xe2, 0x39, 0xee, 0xaa, 0xff, 0x00,
+  0x94, 0x88, 0xb8, 0xde, 0xa5, 0x44, 0x60, 0xcc, 0x71, 0x52, 0x92, 0x84,
+  0xb0, 0xc3, 0x69, 0x03, 0x65, 0xa6, 0xce, 0x9b, 0x2a, 0xea, 0x35, 0xa0,
+  0xa5, 0x6c, 0xe8, 0xa8, 0x1a, 0x67, 0xca, 0xd9, 0x66, 0xd2, 0x6c, 0x19,
+  0x33, 0x2b, 0x75, 0xd8, 0xd0, 0xa4, 0x28, 0x48, 0x52, 0x94, 0x4e, 0xda,
+  0x7d, 0x01, 0x1c, 0xe7, 0x7d, 0xc0, 0x1e, 0xcf, 0xd8, 0x37, 0x4c, 0xa1,
+  0x9b, 0x2e, 0x45, 0x0a, 0x15, 0xc1, 0x71, 0xa3, 0x4f, 0x8e, 0x42, 0x5f,
+  0x8c, 0xb7, 0x1b, 0xe6, 0xd6, 0xc7, 0x42, 0x37, 0xdd, 0xe1, 0xf5, 0x8f,
+  0x55, 0x73, 0xb1, 0x75, 0xc7, 0xb2, 0x36, 0xa4, 0xda, 0xdb, 0x9b, 0x1a,
+  0x62, 0x56, 0x1c, 0x61, 0xf8, 0xea, 0x24, 0x29, 0x40, 0x12, 0x85, 0x8e,
+  0x53, 0xa3, 0xae, 0xf1, 0xb1, 0xd3, 0xae, 0xf7, 0xdd, 0x51, 0xef, 0x1f,
+  0x1d, 0x0b, 0x7b, 0xb5, 0xf3, 0x35, 0x65, 0xad, 0x16, 0xf1, 0x07, 0xd3,
+  0x05, 0xa7, 0x54, 0xcb, 0x61, 0x0b, 0x5b, 0x4c, 0x13, 0xce, 0xe3, 0x01,
+  0x69, 0x53, 0x89, 0x4e, 0x8e, 0xf6, 0x50, 0x14, 0x06, 0xbb, 0xf7, 0xaa,
+  0x8f, 0x5e, 0x61, 0x8b, 0x5b, 0x61, 0x35, 0x16, 0xcd, 0xd9, 0xca, 0x5b,
+  0x9f, 0x90, 0x87, 0x01, 0xae, 0x65, 0xaf, 0xd8, 0x84, 0x8d, 0x8f, 0x6e,
+  0xb5, 0xe9, 0xae, 0x4c, 0x5a, 0xf6, 0xab, 0x03, 0xea, 0xc5, 0x6f, 0xcf,
+  0xab, 0xb6, 0x8a, 0x79, 0x22, 0xbe, 0xbe, 0x8a, 0x90, 0xcf, 0xe6, 0x2c,
+  0x0f, 0x1e, 0x9d, 0x0e, 0xbb, 0x94, 0x15, 0xe1, 0x5e, 0xae, 0x39, 0xde,
+  0x23, 0x64, 0x9c, 0xb8, 0x16, 0xe6, 0x0c, 0xfb, 0xb3, 0xbe, 0x71, 0x85,
+  0x6c, 0x8d, 0xda, 0x48, 0x70, 0xfa, 0x54, 0x94, 0x8d, 0x8f, 0x6a, 0xb4,
+  0x3d, 0x75, 0x3a, 0x1e, 0x73, 0x8c, 0x94, 0xd6, 0xb1, 0x8c, 0xe0, 0x9b,
+  0xc1, 0x21, 0x4f, 0x83, 0x8f, 0xa1, 0x8b, 0x83, 0x6d, 0xb0, 0xb2, 0xf3,
+  0xae, 0x37, 0x19, 0x27, 0x7d, 0x83, 0x6a, 0x59, 0x52, 0x5b, 0x27, 0xc7,
+  0x40, 0xeb, 0xd5, 0xdd, 0xd7, 0x5b, 0xa5, 0xb7, 0x33, 0x2c, 0x7b, 0x0f,
+  0xba, 0xdf, 0x20, 0x5c, 0x27, 0xb4, 0xdb, 0x1e, 0x54, 0x89, 0x11, 0x9a,
+  0x49, 0x2b, 0x5a, 0x94, 0xf2, 0x76, 0xb4, 0x21, 0x23, 0x65, 0x47, 0x9c,
+  0x29, 0x5a, 0x48, 0x27, 0xcf, 0xee, 0xa0, 0xc3, 0xe2, 0x0e, 0x57, 0xb3,
+  0x3a, 0x43, 0x78, 0x7d, 0xad, 0x47, 0x5d, 0x83, 0x1c, 0x92, 0x27, 0x38,
+  0x9f, 0x5a, 0xba, 0xb6, 0xd7, 0x4d, 0x78, 0x38, 0x7e, 0x6d, 0x6e, 0xb5,
+  0xc1, 0xc1, 0xb0, 0xc7, 0x1f, 0x55, 0xad, 0xa6, 0x27, 0x5f, 0x56, 0xb4,
+  0xb4, 0xe1, 0xf2, 0x84, 0xc8, 0xb8, 0x48, 0x5a, 0xb4, 0x90, 0x95, 0x29,
+  0x67, 0x98, 0x0e, 0x83, 0xa6, 0xc2, 0x40, 0xf0, 0x00, 0x55, 0x70, 0x97,
+  0x25, 0xd3, 0x6c, 0xd6, 0x9b, 0xd6, 0x7f, 0x92, 0x91, 0xee, 0x25, 0x8d,
+  0xbc, 0x76, 0x0a, 0xbb, 0xa6, 0x5e, 0x01, 0xed, 0x88, 0xf1, 0xe5, 0x8e,
+  0x93, 0xcd, 0xbf, 0x9e, 0x51, 0xec, 0xaf, 0x5f, 0xc8, 0x9b, 0x0d, 0xb9,
+  0xa5, 0xdf, 0xf3, 0x4b, 0x8b, 0xd9, 0x0c, 0x98, 0xa9, 0xed, 0x94, 0xfd,
+  0xcf, 0xce, 0x61, 0x92, 0x3c, 0x5b, 0x60, 0x0e, 0x40, 0x7c, 0x07, 0x45,
+  0x2b, 0x7d, 0xc4, 0x9a, 0xdd, 0x94, 0x5c, 0xf2, 0xf8, 0x56, 0xa5, 0x4b,
+  0x92, 0xc5, 0xba, 0x0c, 0x27, 0x56, 0xdb, 0x72, 0x1d, 0x8e, 0xea, 0x96,
+  0xf4, 0x06, 0x94, 0xb4, 0x85, 0x3a, 0x49, 0x01, 0x2b, 0xe5, 0x49, 0x3d,
+  0xc0, 0x68, 0xf5, 0xea, 0x07, 0x5d, 0x13, 0x2c, 0x38, 0xbd, 0xc9, 0x33,
+  0xa0, 0x59, 0xdc, 0x8c, 0x32, 0x0b, 0x7b, 0xe8, 0x70, 0x49, 0x92, 0xb5,
+  0x38, 0xf7, 0x6e, 0x8e, 0x57, 0x00, 0x75, 0x44, 0xf3, 0x29, 0xb3, 0xe6,
+  0xec, 0x77, 0x68, 0xf4, 0xd7, 0x4a, 0x8d, 0x4d, 0xf0, 0x4a, 0x8a, 0x5c,
+  0x9d, 0x97, 0xfc, 0x96, 0xfd, 0x0e, 0xc1, 0x26, 0xe5, 0x0f, 0x18, 0x71,
+  0x88, 0xa8, 0x48, 0x4a, 0x1c, 0x92, 0xf0, 0x0e, 0xb4, 0x0e, 0x87, 0x6a,
+  0xa6, 0x40, 0x3e, 0x62, 0x77, 0xcc, 0x41, 0x50, 0x56, 0x81, 0xe8, 0x3b,
+  0xab, 0x51, 0xb5, 0xc0, 0x98, 0x99, 0x5e, 0x45, 0x92, 0x4c, 0x7a, 0xfb,
+  0x15, 0x40, 0x26, 0x73, 0xb3, 0x09, 0x4a, 0x1e, 0xd0, 0x50, 0x4f, 0x66,
+  0x92, 0x1b, 0xe4, 0x3b, 0x00, 0xa4, 0x24, 0x74, 0x57, 0xac, 0x1a, 0x8f,
+  0xb4, 0x66, 0x37, 0x79, 0xee, 0xbe, 0xb5, 0xda, 0x44, 0xfb, 0x7c, 0xc8,
+  0xe8, 0x7d, 0x88, 0xe1, 0x87, 0x52, 0xe2, 0x02, 0xdb, 0x4e, 0xda, 0x59,
+  0x5a, 0x03, 0x3d, 0x9e, 0xf9, 0x8f, 0x69, 0xcf, 0xd4, 0x1f, 0x83, 0x50,
+  0x36, 0x9b, 0x6d, 0xbe, 0x3a, 0xa2, 0xa6, 0xdf, 0x7f, 0x85, 0x72, 0xbd,
+  0xba, 0xc3, 0x70, 0xd4, 0xd5, 0xa8, 0x36, 0x99, 0x0e, 0x04, 0xa3, 0xb8,
+  0xbe, 0x49, 0xf7, 0xb4, 0x84, 0xeb, 0xb5, 0xe5, 0xe7, 0x00, 0x00, 0x15,
+  0xbd, 0x26, 0xa3, 0x65, 0xc9, 0x3b, 0xbe, 0x0e, 0x1e, 0x0a, 0xdc, 0xc6,
+  0x23, 0x9f, 0xc9, 0xc2, 0xd6, 0xd7, 0x93, 0x58, 0xf2, 0x64, 0xbd, 0x79,
+  0xc7, 0xdb, 0xdf, 0x9b, 0x19, 0xf0, 0xa2, 0x26, 0xc2, 0x1e, 0x1a, 0x4b,
+  0x9b, 0x71, 0x3a, 0xd7, 0x9a, 0xaf, 0xee, 0xbd, 0x53, 0xdc, 0x2a, 0x92,
+  0xe3, 0x1e, 0x31, 0x90, 0xbb, 0x86, 0x5b, 0x1a, 0x81, 0x12, 0xd5, 0x0a,
+  0xe3, 0x68, 0x94, 0x89, 0x58, 0xf3, 0xf0, 0xb9, 0xcf, 0x92, 0x4c, 0x47,
+  0xe4, 0xda, 0x71, 0x4b, 0xea, 0xb4, 0x3c, 0x36, 0xd9, 0x3e, 0x6e, 0xd4,
+  0xb4, 0xec, 0x1d, 0xee, 0xac, 0x6e, 0x16, 0xe6, 0x50, 0x73, 0xcc, 0x12,
+  0xdb, 0x93, 0xc0, 0x41, 0x64, 0x49, 0x6f, 0x4f, 0xc7, 0x51, 0xf3, 0xe3,
+  0xbe, 0x93, 0xca, 0xe3, 0x4a, 0x1e, 0x05, 0x2a, 0x04, 0x75, 0xf0, 0xd1,
+  0xf1, 0xa8, 0x24, 0x68, 0xa2, 0x81, 0xdd, 0x45, 0x00, 0x89, 0xc6, 0x5f,
+  0x89, 0x62, 0xff, 0x00, 0xb5, 0x56, 0xcf, 0xbf, 0x14, 0xf7, 0x48, 0x9c,
+  0x65, 0xf8, 0x96, 0x2f, 0xfb, 0x55, 0x6c, 0xfb, 0xf1, 0x4f, 0x74, 0x07,
+  0x95, 0x10, 0x0f, 0x52, 0x07, 0xb6, 0x8a, 0xc9, 0x1d, 0x68, 0xa8, 0x18,
+  0x46, 0x69, 0x33, 0x8e, 0x3f, 0x23, 0xd9, 0x77, 0xd1, 0x12, 0x3f, 0x80,
+  0xd3, 0x9d, 0x26, 0x71, 0xc7, 0xe4, 0x7b, 0x2e, 0xfa, 0x22, 0x47, 0xf0,
+  0x1a, 0x90, 0x37, 0xc6, 0xf8, 0xbb, 0x7f, 0x30, 0x7d, 0x95, 0xb2, 0xb5,
+  0xc6, 0xf8, 0xbb, 0x7f, 0x30, 0x7d, 0x95, 0xb2, 0x80, 0x28, 0xa2, 0x8a,
+  0x03, 0x96, 0xe9, 0x0a, 0x2d, 0xca, 0xdf, 0x26, 0xdf, 0x39, 0x86, 0xe4,
+  0x45, 0x94, 0xd2, 0x99, 0x7d, 0xa5, 0x8d, 0xa5, 0xc4, 0x28, 0x10, 0xa4,
+  0x91, 0xe8, 0x20, 0x9a, 0xf8, 0xda, 0xe3, 0x06, 0xe1, 0x84, 0xca, 0xbd,
+  0xe2, 0x73, 0x24, 0x2f, 0xb4, 0xc5, 0xd8, 0x54, 0x54, 0xba, 0xb5, 0x12,
+  0x5e, 0xb1, 0x49, 0x73, 0x9e, 0x24, 0x8d, 0xf8, 0xf9, 0x2c, 0x92, 0x02,
+  0xbf, 0x55, 0xc5, 0x78, 0x26, 0xbe, 0xd3, 0xd5, 0x52, 0xff, 0x00, 0x84,
+  0xee, 0x3e, 0xfc, 0x7b, 0x7c, 0x0e, 0x26, 0x5a, 0x20, 0x26, 0x74, 0xfc,
+  0x68, 0x38, 0x9b, 0x8c, 0x32, 0x9e, 0x61, 0x70, 0xb5, 0x3a, 0x39, 0x65,
+  0x30, 0xa1, 0xe3, 0xe6, 0x92, 0xa1, 0xbe, 0xef, 0x38, 0xd4, 0xa7, 0x87,
+  0x92, 0x1a, 0xca, 0xc0, 0xd9, 0x8f, 0x4c, 0x63, 0x39, 0xc0, 0x24, 0xbd,
+  0x09, 0xc1, 0x1d, 0xeb, 0x83, 0x45, 0x44, 0xf7, 0x86, 0x24, 0x00, 0x02,
+  0x90, 0xaf, 0x5a, 0x1c, 0x49, 0x04, 0x7a, 0x3d, 0xbb, 0xa8, 0x35, 0xe3,
+  0xf7, 0x97, 0xef, 0x82, 0x5a, 0xec, 0x97, 0x17, 0xee, 0x4b, 0x5f, 0x94,
+  0x11, 0x2e, 0x7e, 0xed, 0xd1, 0x5d, 0x56, 0x8a, 0x96, 0x00, 0xf3, 0x97,
+  0xa2, 0x94, 0xe9, 0x1d, 0x7a, 0x01, 0xbd, 0x68, 0x6a, 0xbd, 0xe0, 0x62,
+  0xe7, 0x40, 0x99, 0x2e, 0xd9, 0x88, 0xdf, 0x18, 0x2f, 0xc6, 0xec, 0x96,
+  0xc3, 0x53, 0xb9, 0x95, 0x16, 0xef, 0x6f, 0x75, 0x3c, 0xd0, 0xe4, 0x12,
+  0x9f, 0x39, 0xb7, 0x83, 0x7e, 0xf4, 0xa7, 0x12, 0x0f, 0x9c, 0xce, 0x94,
+  0x09, 0xd6, 0xad, 0xe7, 0xa4, 0x71, 0x56, 0x6a, 0xfb, 0x36, 0xad, 0x18,
+  0xa5, 0xa9, 0x24, 0xf5, 0x7d, 0x77, 0x17, 0xa4, 0x94, 0x8f, 0x48, 0x40,
+  0x65, 0x1c, 0xc7, 0xda, 0xa4, 0xee, 0xb4, 0x97, 0x39, 0x7d, 0x4c, 0xa3,
+  0xc6, 0x17, 0x41, 0xaa, 0xdb, 0x1e, 0x2d, 0xa2, 0xd4, 0xdc, 0x65, 0xba,
+  0xda, 0x52, 0x9e, 0x75, 0x2d, 0x4a, 0x3c, 0xa9, 0x2a, 0x51, 0x2a, 0x5a,
+  0xb4, 0x4f, 0x40, 0x4a, 0x94, 0x75, 0xe1, 0xba, 0xae, 0x63, 0xdd, 0xf1,
+  0x96, 0xaf, 0x32, 0x15, 0x83, 0xd8, 0xe6, 0xe5, 0x77, 0x30, 0xf1, 0x2d,
+  0xba, 0xcf, 0x9d, 0x16, 0x0a, 0xb9, 0x74, 0xa4, 0x26, 0x42, 0xf4, 0x96,
+  0xd2, 0x76, 0x49, 0x4a, 0x49, 0x3b, 0x27, 0xa7, 0x85, 0x48, 0xdc, 0xb0,
+  0xfb, 0x5b, 0x4d, 0x0b, 0x8f, 0x10, 0xf2, 0x49, 0x57, 0xd4, 0x95, 0x84,
+  0x88, 0xee, 0x0e, 0xc2, 0x22, 0xd5, 0xde, 0x12, 0x23, 0xb7, 0xb2, 0xe9,
+  0xef, 0xf3, 0x54, 0x57, 0xbf, 0x01, 0x52, 0x3f, 0xca, 0x44, 0xf6, 0xf0,
+  0xf1, 0xbb, 0x05, 0xad, 0xcb, 0x5c, 0x97, 0x50, 0xa5, 0x23, 0xcb, 0x60,
+  0xa9, 0xa6, 0x63, 0xc6, 0x40, 0xf3, 0x9d, 0x08, 0x1a, 0x0a, 0x1b, 0x29,
+  0x48, 0x4e, 0xd2, 0x76, 0xa1, 0xbd, 0x78, 0xd3, 0xba, 0xbd, 0x4d, 0x31,
+  0x26, 0x45, 0x4e, 0xc3, 0x2e, 0xd9, 0x34, 0x65, 0x4a, 0xe2, 0x4d, 0xf6,
+  0x3b, 0x76, 0xe4, 0x12, 0xb3, 0x6c, 0xb7, 0x9e, 0xcd, 0x84, 0x27, 0xd0,
+  0xe4, 0x85, 0x0e, 0xd1, 0x5d, 0x3b, 0xca, 0x7b, 0x31, 0xed, 0xef, 0x3d,
+  0xb6, 0x6b, 0xbe, 0x19, 0x8f, 0x43, 0x62, 0xcb, 0x85, 0xdb, 0x61, 0xf6,
+  0xd2, 0x57, 0xd9, 0xc5, 0x89, 0x15, 0xae, 0xc1, 0x32, 0x08, 0x07, 0x6b,
+  0xed, 0x0a, 0x74, 0xb4, 0xa4, 0x02, 0x54, 0xb1, 0xcc, 0x40, 0x1e, 0x24,
+  0xea, 0x8c, 0x8e, 0xdb, 0x2e, 0x0c, 0xbb, 0x44, 0xeb, 0xcd, 0xdd, 0xfb,
+  0xbd, 0x99, 0x12, 0xd2, 0x27, 0x35, 0x21, 0xa6, 0x92, 0x84, 0x2d, 0x63,
+  0x91, 0xa7, 0x00, 0x4a, 0x53, 0xef, 0x69, 0x5a, 0x86, 0xc1, 0x27, 0x5d,
+  0x0f, 0x81, 0xdf, 0x1e, 0x53, 0x95, 0x44, 0xb8, 0x40, 0x76, 0x33, 0x31,
+  0xa6, 0xb1, 0x90, 0xdb, 0x66, 0x03, 0x09, 0xa5, 0xc7, 0x5b, 0x6e, 0x29,
+  0xe0, 0xa2, 0x11, 0xca, 0x08, 0x1c, 0xe8, 0x71, 0x3c, 0xc0, 0x94, 0xed,
+  0x3c, 0xaa, 0x3d, 0x7c, 0x43, 0x79, 0x0d, 0xa2, 0x75, 0xe5, 0x09, 0xc9,
+  0x9a, 0x89, 0x0d, 0xdb, 0xe4, 0xf8, 0x66, 0xce, 0xf4, 0x94, 0x22, 0xe8,
+  0x88, 0x0d, 0xad, 0xb5, 0xb0, 0xc9, 0xd8, 0x1a, 0x70, 0xaf, 0x6a, 0x6c,
+  0xa8, 0xa4, 0x2c, 0xe9, 0x27, 0x97, 0x64, 0x68, 0x6e, 0xb9, 0xae, 0x93,
+  0x71, 0x69, 0xf8, 0x9c, 0x89, 0xd6, 0x01, 0x12, 0x14, 0x8b, 0x13, 0x8e,
+  0x48, 0x8e, 0x52, 0xc0, 0x40, 0x8a, 0xfb, 0x64, 0x82, 0x85, 0x80, 0x07,
+  0x2f, 0x3e, 0x8a, 0x0a, 0x4f, 0x52, 0x15, 0xd0, 0x6f, 0xbb, 0x86, 0xea,
+  0xac, 0x95, 0x84, 0x5c, 0x2d, 0xd7, 0x69, 0x66, 0x34, 0x2b, 0xa2, 0xdd,
+  0x69, 0x84, 0x3e, 0xda, 0x1d, 0x7d, 0x28, 0x73, 0x7c, 0xe8, 0x69, 0xb6,
+  0x4a, 0x94, 0xf9, 0x01, 0x5e, 0x6a, 0x94, 0x11, 0xcb, 0xd3, 0x98, 0x2a,
+  0xb3, 0x1e, 0x1d, 0xae, 0x45, 0xfb, 0xc8, 0xa0, 0x44, 0x99, 0x6d, 0x7d,
+  0x96, 0xd3, 0x31, 0xf7, 0xef, 0x21, 0x6e, 0x96, 0x93, 0xbe, 0x46, 0xd4,
+  0xd2, 0x16, 0xa2, 0x85, 0x2c, 0xe8, 0x80, 0xb3, 0xcd, 0xc9, 0xa0, 0x35,
+  0xd4, 0x0a, 0x61, 0x2f, 0x52, 0x77, 0x61, 0x75, 0xbc, 0x65, 0x2b, 0x5d,
+  0xd3, 0xca, 0x9b, 0x44, 0x3b, 0x2c, 0xb6, 0x88, 0x6f, 0xdd, 0x56, 0x92,
+  0xc8, 0x8c, 0xb5, 0xa3, 0x45, 0x2a, 0x5f, 0x31, 0xed, 0x53, 0xde, 0x52,
+  0x84, 0x27, 0x98, 0x95, 0x00, 0x48, 0xd1, 0xad, 0x46, 0xd9, 0x69, 0x97,
+  0x39, 0x8b, 0x55, 0xad, 0xe9, 0x97, 0x5b, 0x9b, 0xd1, 0x42, 0x5c, 0x6e,
+  0xe0, 0xc9, 0x88, 0x83, 0x1d, 0xb4, 0x80, 0x16, 0xf2, 0x83, 0x49, 0x79,
+  0xe6, 0xb9, 0x88, 0xd2, 0x0a, 0x94, 0x92, 0x49, 0x04, 0xe8, 0x13, 0x5d,
+  0xf9, 0x63, 0xb3, 0x31, 0x0b, 0x94, 0x4c, 0x8e, 0x52, 0xee, 0x39, 0x2c,
+  0x34, 0x32, 0xb6, 0x63, 0xb6, 0xe2, 0x5a, 0x2e, 0xb0, 0xfa, 0x88, 0x25,
+  0x69, 0xe5, 0x4a, 0x76, 0x14, 0x84, 0xab, 0x43, 0x5b, 0xd8, 0xe5, 0x1f,
+  0x0c, 0x01, 0x9c, 0x9e, 0xe9, 0x6e, 0xca, 0xd8, 0xb6, 0x2b, 0x1e, 0x91,
+  0x2d, 0x37, 0x49, 0x0a, 0x53, 0x29, 0xec, 0x42, 0x98, 0x7d, 0x31, 0x5c,
+  0x1c, 0xae, 0xa9, 0x5b, 0x4e, 0xdb, 0x48, 0xe8, 0xa0, 0xa5, 0x27, 0xe1,
+  0xa1, 0x3a, 0x07, 0xb8, 0xc6, 0xfd, 0x42, 0xc6, 0x76, 0x3d, 0x64, 0xb1,
+  0xe7, 0x5a, 0x97, 0x6b, 0x39, 0x1c, 0x86, 0x6e, 0x78, 0xf2, 0x0a, 0xca,
+  0xe3, 0x46, 0x83, 0xc8, 0x90, 0xf2, 0x53, 0xef, 0x2d, 0xf2, 0x02, 0x79,
+  0x9b, 0x24, 0x10, 0x90, 0x7f, 0x3f, 0x90, 0x75, 0xde, 0x86, 0xcc, 0xc2,
+  0xe3, 0x68, 0xbb, 0xe1, 0xd0, 0x32, 0x4b, 0x1c, 0x94, 0xa2, 0x53, 0x0b,
+  0x47, 0xb9, 0x6e, 0xb2, 0x00, 0x52, 0xcb, 0xba, 0x4a, 0x99, 0x6f, 0xa6,
+  0x94, 0x54, 0x9d, 0x8d, 0x0e, 0xe2, 0x90, 0x7f, 0x36, 0xb8, 0x15, 0xee,
+  0xd0, 0xb6, 0x44, 0xc7, 0xf2, 0x89, 0x6e, 0x2c, 0x95, 0x36, 0xeb, 0xad,
+  0x36, 0x80, 0xf4, 0xd9, 0x49, 0x6d, 0x61, 0x49, 0x09, 0x6d, 0x91, 0xca,
+  0xda, 0x76, 0x9d, 0x15, 0x92, 0x77, 0xa3, 0xd1, 0x35, 0xd7, 0x60, 0xb7,
+  0xc4, 0xb9, 0xde, 0x64, 0x2e, 0xc0, 0xc3, 0xb6, 0x56, 0xe0, 0x14, 0xc7,
+  0x7a, 0x4c, 0xb6, 0xd4, 0xec, 0xd4, 0xb8, 0xa4, 0xf3, 0x29, 0xa6, 0xbb,
+  0x62, 0xa0, 0xd2, 0x42, 0x54, 0x36, 0x40, 0x21, 0x5b, 0xe9, 0xd0, 0x6c,
+  0xb6, 0x5c, 0x05, 0x97, 0xc9, 0xcf, 0x70, 0x99, 0x7b, 0x7b, 0x11, 0x36,
+  0x5c, 0x91, 0xf4, 0xc6, 0x0f, 0x28, 0x33, 0x26, 0xe5, 0x35, 0x86, 0xe3,
+  0x02, 0x90, 0xa1, 0xd1, 0x96, 0x50, 0xe2, 0xd4, 0xb7, 0x48, 0x1b, 0x04,
+  0x10, 0x90, 0x41, 0x23, 0xc0, 0x52, 0xde, 0x39, 0x78, 0xb7, 0xe1, 0x7c,
+  0x74, 0x90, 0xc4, 0x09, 0x04, 0xe2, 0xd9, 0xd3, 0xca, 0x5a, 0x02, 0x90,
+  0xa4, 0x08, 0x77, 0x94, 0x24, 0x17, 0x10, 0x52, 0xad, 0x29, 0x3d, 0xb3,
+  0x7a, 0x5f, 0x51, 0xd5, 0x43, 0xa7, 0x4a, 0x6d, 0x9c, 0x6e, 0x18, 0xbe,
+  0x47, 0x32, 0x53, 0xd1, 0x65, 0xe4, 0xd2, 0x9c, 0x8a, 0x85, 0xda, 0x82,
+  0x8b, 0x61, 0xfe, 0xc5, 0xb5, 0x7f, 0x38, 0x69, 0x04, 0x04, 0x82, 0xe0,
+  0x0b, 0xe7, 0x1d, 0x01, 0x58, 0xd2, 0x76, 0x4a, 0x77, 0x4b, 0xfc, 0x51,
+  0xb1, 0x46, 0xe2, 0x4c, 0x66, 0xad, 0xb6, 0xc4, 0x49, 0xb7, 0xde, 0x25,
+  0xc5, 0x53, 0xea, 0xed, 0x11, 0xca, 0xec, 0x07, 0x99, 0xdb, 0x91, 0x24,
+  0x38, 0x01, 0xf3, 0x16, 0x1c, 0xf3, 0x40, 0xef, 0x52, 0x1d, 0x5f, 0x78,
+  0x1d, 0x0f, 0x7d, 0xc2, 0xc7, 0x05, 0xcc, 0x93, 0xb1, 0xba, 0xcd, 0x23,
+  0xf0, 0x57, 0x34, 0x73, 0x36, 0xc1, 0x63, 0xcf, 0x9e, 0xcf, 0x92, 0xde,
+  0xa1, 0x2d, 0x50, 0x2f, 0x31, 0x08, 0xd2, 0x98, 0x9a, 0xd1, 0xe5, 0x71,
+  0x24, 0x78, 0x02, 0x7c, 0xe1, 0xea, 0x50, 0xf4, 0x53, 0xc0, 0xa8, 0x24,
+  0x44, 0xe3, 0x2f, 0xc4, 0xb1, 0x7f, 0xda, 0xab, 0x67, 0xdf, 0x8a, 0x7b,
+  0xa4, 0x4e, 0x32, 0xfc, 0x4b, 0x17, 0xfd, 0xaa, 0xb6, 0x7d, 0xf8, 0xa7,
+  0xba, 0x00, 0xa2, 0x8a, 0x28, 0x02, 0x93, 0x38, 0xe3, 0xf2, 0x3d, 0x97,
+  0x7d, 0x11, 0x23, 0xf8, 0x0d, 0x39, 0xd2, 0x67, 0x1c, 0x7e, 0x47, 0xb2,
+  0xef, 0xa2, 0x24, 0x7f, 0x01, 0xa0, 0x1b, 0xe3, 0x7c, 0x5d, 0xbf, 0x98,
+  0x3e, 0xca, 0xd9, 0x5a, 0xe3, 0x7c, 0x5d, 0xbf, 0x98, 0x3e, 0xca, 0xd9,
+  0x40, 0x14, 0x51, 0x45, 0x00, 0x56, 0xb9, 0x0d, 0xb4, 0xfb, 0x4e, 0x32,
+  0xf3, 0x68, 0x75, 0xb7, 0x12, 0x52, 0xb4, 0x28, 0x6c, 0x28, 0x11, 0xd4,
+  0x11, 0xe8, 0x22, 0xb6, 0x50, 0x46, 0xe8, 0x0f, 0x8d, 0xe5, 0x43, 0x93,
+  0xc2, 0x6e, 0x21, 0xcb, 0xb4, 0x27, 0xb7, 0xec, 0xf1, 0xc4, 0xae, 0x75,
+  0xb1, 0x5d, 0x49, 0x99, 0x8f, 0xbe, 0xef, 0x33, 0xec, 0x8e, 0xed, 0xae,
+  0x2b, 0xa7, 0xb6, 0x1f, 0xaa, 0x1d, 0xf0, 0xd5, 0x7d, 0x29, 0x22, 0xf4,
+  0xed, 0xd8, 0x5a, 0x62, 0xc4, 0xbb, 0xa2, 0xdf, 0x1e, 0x63, 0x2b, 0x71,
+  0xf9, 0x6d, 0xf2, 0xa9, 0x6a, 0xd1, 0x6d, 0x29, 0x43, 0x65, 0x5b, 0x00,
+  0xab, 0xb4, 0x07, 0x98, 0x82, 0x75, 0xad, 0x75, 0x3b, 0x0b, 0x5f, 0x84,
+  0xc6, 0x29, 0x2e, 0xed, 0x89, 0xc7, 0xcb, 0x2c, 0x31, 0x9b, 0x7b, 0x23,
+  0xc5, 0x5c, 0x55, 0xc2, 0x23, 0x6b, 0x40, 0x50, 0x94, 0xc7, 0x2e, 0xa4,
+  0x46, 0x50, 0xf1, 0x43, 0x8d, 0xf3, 0x02, 0x9f, 0x1d, 0x6b, 0xc6, 0xab,
+  0xbe, 0x0f, 0x3f, 0x65, 0xc8, 0xac, 0xab, 0xc1, 0x9e, 0x90, 0xe2, 0xed,
+  0x6a, 0x8e, 0xdd, 0xc7, 0x1e, 0x92, 0xb5, 0xed, 0xc1, 0x01, 0xd5, 0x1e,
+  0xcd, 0x25, 0x43, 0x47, 0x99, 0x87, 0x02, 0x98, 0x5e, 0x88, 0x20, 0xa1,
+  0x27, 0x7d, 0xc6, 0xb5, 0x87, 0x7a, 0x3a, 0x4c, 0xa7, 0xdd, 0x96, 0xaf,
+  0xcc, 0xb5, 0xf3, 0x08, 0xa7, 0x0b, 0x76, 0x26, 0x59, 0x1d, 0x37, 0x0b,
+  0xac, 0x78, 0xad, 0xad, 0x87, 0xe3, 0x48, 0x96, 0xb7, 0x8a, 0x14, 0xe1,
+  0x48, 0x4b, 0xc8, 0x2e, 0x12, 0x42, 0xb6, 0x02, 0x08, 0x04, 0x0d, 0x2f,
+  0x7a, 0x1a, 0x3b, 0xf5, 0x93, 0xdd, 0x6d, 0x19, 0x44, 0x68, 0x11, 0xec,
+  0xaa, 0x71, 0xfb, 0xa0, 0x79, 0xb5, 0x32, 0x1a, 0x0a, 0x4a, 0x98, 0x69,
+  0x7a, 0x4b, 0xa5, 0xc2, 0x9e, 0xad, 0xa0, 0xb4, 0xa5, 0x8e, 0xba, 0x24,
+  0x81, 0xad, 0x90, 0x35, 0xc9, 0x0a, 0xc9, 0x72, 0x6a, 0x5a, 0x2c, 0xad,
+  0xca, 0x7a, 0xfc, 0x6d, 0xa5, 0x0b, 0x59, 0x94, 0xe2, 0x9a, 0x8a, 0xd3,
+  0x9a, 0xe6, 0x41, 0x74, 0xa8, 0xad, 0xc7, 0xdc, 0xd6, 0x94, 0x13, 0xbe,
+  0x51, 0xb0, 0x4e, 0x8e, 0xb5, 0xee, 0x0a, 0x2d, 0xe6, 0xf5, 0x22, 0xd3,
+  0x96, 0x08, 0x76, 0xce, 0x49, 0x0d, 0x31, 0x0a, 0xd9, 0x11, 0xc2, 0xd4,
+  0x59, 0x5c, 0xe8, 0x2a, 0x0e, 0xe8, 0x04, 0x95, 0x95, 0x14, 0x38, 0x9e,
+  0x53, 0xb0, 0x9e, 0xcc, 0x8e, 0xbb, 0xd9, 0xcf, 0x2b, 0x84, 0x69, 0xbf,
+  0x2c, 0xe7, 0x72, 0xdf, 0x77, 0x65, 0x11, 0xb1, 0xdb, 0xc2, 0x9c, 0xba,
+  0x3e, 0x5b, 0x42, 0x9f, 0x62, 0x22, 0xbb, 0x67, 0xe5, 0x34, 0x95, 0x12,
+  0x90, 0xeb, 0xab, 0x4b, 0x6d, 0xb2, 0xd9, 0x29, 0x00, 0xe8, 0x6d, 0x5a,
+  0x3a, 0x3d, 0xf5, 0xd1, 0x6f, 0x66, 0x12, 0xf2, 0x09, 0x76, 0xf5, 0x5b,
+  0x93, 0x88, 0x88, 0xec, 0xb6, 0xb9, 0x09, 0x8d, 0xd9, 0x87, 0xe5, 0x17,
+  0x56, 0xae, 0x50, 0xdb, 0xa9, 0xea, 0x1a, 0xf3, 0x34, 0x79, 0x79, 0x4f,
+  0x31, 0xd6, 0xc6, 0xba, 0xe9, 0xbf, 0x2d, 0x78, 0x54, 0xe9, 0x0e, 0x63,
+  0x22, 0x0a, 0x18, 0xba, 0x21, 0x12, 0x5a, 0x43, 0xc5, 0x7d, 0x92, 0x0b,
+  0x2b, 0x42, 0x5d, 0x68, 0x29, 0x29, 0x57, 0x66, 0x85, 0x25, 0xcd, 0xa5,
+  0x5a, 0x29, 0x42, 0x81, 0xd8, 0x00, 0xf4, 0x32, 0x26, 0x1a, 0xce, 0x13,
+  0x01, 0xe9, 0x2d, 0xb5, 0x02, 0x23, 0x1c, 0xe1, 0xdb, 0x83, 0xe9, 0x53,
+  0x4d, 0xad, 0x4a, 0xe5, 0x28, 0x6d, 0xad, 0xa9, 0x0a, 0x59, 0x0b, 0x4a,
+  0x55, 0xce, 0x92, 0x91, 0xe6, 0x8e, 0x52, 0x77, 0x53, 0xcf, 0x21, 0x7a,
+  0x1b, 0x72, 0x36, 0x64, 0xe1, 0x73, 0xdd, 0xba, 0x59, 0x48, 0x96, 0x99,
+  0x90, 0xcc, 0x78, 0x88, 0x9f, 0x35, 0x4a, 0x4c, 0x77, 0x9b, 0x25, 0xd5,
+  0x36, 0x97, 0x1c, 0x3d, 0x03, 0x88, 0x0b, 0xd6, 0xce, 0x82, 0xd0, 0x91,
+  0xd0, 0x1e, 0x9a, 0x72, 0x67, 0xd9, 0xcf, 0x1a, 0x83, 0x12, 0x04, 0x1e,
+  0x69, 0x6b, 0x49, 0x4c, 0xa1, 0xdb, 0x10, 0x18, 0x8e, 0xb4, 0x12, 0xa4,
+  0x3c, 0xb4, 0x6c, 0x21, 0x5c, 0xe9, 0x6d, 0x49, 0x48, 0x25, 0x41, 0x48,
+  0x0a, 0xd6, 0x87, 0x5e, 0xeb, 0x5c, 0x2b, 0x8c, 0x9b, 0x82, 0x9e, 0x87,
+  0x1d, 0xab, 0xc1, 0x82, 0xa7, 0x18, 0x44, 0x89, 0x4a, 0xf2, 0x58, 0x2d,
+  0x2f, 0x5c, 0xae, 0x06, 0x9a, 0x48, 0x52, 0x9c, 0x57, 0x52, 0x92, 0xb5,
+  0x6f, 0xf3, 0x82, 0x4f, 0x78, 0xad, 0x56, 0x85, 0xda, 0x2e, 0x4b, 0x2c,
+  0xe4, 0xea, 0x4c, 0x17, 0x55, 0x31, 0xf8, 0x91, 0xec, 0xa8, 0x7f, 0xb3,
+  0x8e, 0xc1, 0x6b, 0x44, 0xec, 0x23, 0x41, 0xc2, 0x52, 0x52, 0xbe, 0x65,
+  0x7e, 0x6a, 0xc6, 0x80, 0xa8, 0xf4, 0x43, 0x18, 0xdd, 0x9e, 0x11, 0x1e,
+  0x43, 0x92, 0x23, 0x59, 0x27, 0x34, 0xe5, 0xe0, 0x5b, 0x56, 0x97, 0x15,
+  0x02, 0x17, 0xbe, 0x6d, 0xc0, 0x9f, 0x35, 0x72, 0xa4, 0x3a, 0x10, 0x92,
+  0xad, 0x1e, 0x60, 0x80, 0x12, 0x49, 0xd1, 0xea, 0x3a, 0x57, 0x45, 0x85,
+  0x16, 0xfb, 0x83, 0xaf, 0xb6, 0xe1, 0x56, 0x35, 0x08, 0x4f, 0x30, 0xda,
+  0xb5, 0x45, 0xe4, 0x88, 0xe3, 0xaf, 0x21, 0x1c, 0xca, 0xed, 0x16, 0xd9,
+  0xd9, 0x24, 0x12, 0x52, 0x10, 0xa0, 0x39, 0x00, 0x3e, 0x76, 0xfa, 0x46,
+  0x48, 0xbb, 0xcb, 0xc2, 0x2e, 0x09, 0xb5, 0xdb, 0x5c, 0x81, 0x22, 0x02,
+  0xe5, 0x19, 0xc9, 0x12, 0xa5, 0x76, 0x6b, 0x7a, 0x3b, 0xdc, 0xc1, 0x49,
+  0xed, 0x57, 0xb1, 0xce, 0xda, 0xd3, 0xd0, 0x28, 0xf9, 0xe8, 0x20, 0x03,
+  0xb4, 0x9a, 0xd3, 0x92, 0xa6, 0xdd, 0x7e, 0x9a, 0xf5, 0xc6, 0xe8, 0x20,
+  0x43, 0xb7, 0x4a, 0x69, 0xa4, 0xa5, 0xb9, 0xb0, 0x9c, 0x71, 0x73, 0x9e,
+  0x6d, 0x4b, 0xe5, 0x75, 0x96, 0x92, 0xa4, 0xbd, 0xb4, 0xa5, 0x5a, 0x0b,
+  0x1a, 0x2a, 0xde, 0x80, 0x29, 0xd1, 0xa9, 0xf5, 0x61, 0x3e, 0x88, 0x90,
+  0x7e, 0x65, 0xc3, 0x0d, 0xbb, 0xdc, 0x59, 0x86, 0xca, 0x2f, 0x0e, 0xca,
+  0x71, 0xb9, 0x6d, 0x2a, 0x54, 0xb0, 0x97, 0xde, 0x8a, 0x90, 0x1b, 0x53,
+  0x08, 0x5a, 0xf4, 0x14, 0xe3, 0x6a, 0x01, 0x40, 0x28, 0xf9, 0xc9, 0x5f,
+  0x53, 0xbe, 0xfe, 0x6b, 0xec, 0x37, 0x33, 0x5b, 0xda, 0x24, 0x58, 0x5b,
+  0x7e, 0x32, 0xd2, 0xca, 0x57, 0x2e, 0x43, 0x72, 0x43, 0x69, 0x6d, 0xf6,
+  0xd6, 0x92, 0xc8, 0x0e, 0xa5, 0x2b, 0x47, 0x6c, 0x02, 0x9d, 0x49, 0xd0,
+  0x58, 0x01, 0x5a, 0x3f, 0x9b, 0xae, 0xeb, 0x65, 0xb6, 0xec, 0x51, 0x22,
+  0x6f, 0xf2, 0x69, 0x37, 0x2e, 0x66, 0x12, 0x82, 0x6e, 0xce, 0xa1, 0x82,
+  0xe3, 0x60, 0xf3, 0x76, 0x4c, 0xb0, 0x94, 0xa8, 0x36, 0x36, 0x01, 0xf3,
+  0xc8, 0x24, 0xeb, 0x98, 0x9d, 0x74, 0xf3, 0x61, 0x56, 0x35, 0x77, 0x66,
+  0xdc, 0x9b, 0xf4, 0xe5, 0xbd, 0x71, 0x9b, 0x0d, 0x52, 0xd9, 0x88, 0x1d,
+  0x5b, 0x4c, 0xc4, 0x6c, 0x1e, 0x55, 0x21, 0xb4, 0x20, 0x84, 0xa4, 0xb6,
+  0x4f, 0x29, 0x3d, 0x55, 0xb4, 0xf7, 0xd1, 0x79, 0x24, 0x1e, 0xdb, 0xb3,
+  0xc3, 0x71, 0xdd, 0xb9, 0xcd, 0xd4, 0xfb, 0x5b, 0x99, 0x2f, 0x90, 0xa5,
+  0x6c, 0x25, 0x86, 0x02, 0x53, 0x15, 0x85, 0x13, 0xa7, 0x09, 0x75, 0xd2,
+  0x0b, 0xce, 0xf4, 0xd7, 0x9a, 0x00, 0x4f, 0x51, 0xa4, 0x9a, 0xdf, 0x89,
+  0x37, 0x6f, 0xbb, 0xc7, 0x42, 0x3c, 0xb1, 0xfb, 0x2b, 0x4f, 0x17, 0x9c,
+  0x62, 0xcf, 0x0b, 0xf9, 0xa2, 0xda, 0x4a, 0x16, 0x5b, 0x2a, 0x78, 0xa7,
+  0xcf, 0x53, 0x9b, 0x1e, 0x77, 0x50, 0x90, 0x7a, 0x10, 0x7b, 0xcc, 0x6d,
+  0xbf, 0x2c, 0x95, 0x88, 0xcf, 0x67, 0x19, 0x7a, 0x33, 0x52, 0x60, 0xc2,
+  0x0b, 0x60, 0xcb, 0x0b, 0xf3, 0xc9, 0x3c, 0xae, 0x34, 0xe2, 0x81, 0xea,
+  0xbd, 0xa1, 0x7a, 0x50, 0x47, 0x32, 0xf9, 0x82, 0x8f, 0x2e, 0x88, 0xae,
+  0x94, 0x61, 0xf2, 0xb2, 0x0b, 0xf3, 0xd9, 0x2a, 0xa1, 0xb1, 0x6c, 0x25,
+  0xd4, 0xb9, 0x19, 0x32, 0x59, 0x74, 0x39, 0xbe, 0x44, 0x87, 0x1c, 0x28,
+  0x6d, 0xd4, 0x68, 0x28, 0xa1, 0x3e, 0xf6, 0xe7, 0x36, 0xf9, 0x41, 0x20,
+  0x12, 0x45, 0x31, 0xd5, 0x8c, 0xf4, 0x42, 0x54, 0x59, 0xb2, 0x78, 0x6b,
+  0xc7, 0x74, 0xcc, 0x9a, 0xe9, 0x5d, 0x9b, 0x27, 0x71, 0x9b, 0x6d, 0xd5,
+  0xfe, 0x81, 0x02, 0x61, 0x49, 0xf2, 0x39, 0x67, 0xb8, 0x02, 0xea, 0x12,
+  0xa6, 0x96, 0x75, 0xd5, 0x6d, 0x95, 0x78, 0x81, 0x5f, 0x42, 0x27, 0xaa,
+  0x77, 0x55, 0xf6, 0x4d, 0x82, 0xda, 0x72, 0x0b, 0x15, 0xdf, 0x11, 0xb9,
+  0xba, 0xec, 0xd7, 0x2f, 0x11, 0xb9, 0xe5, 0xce, 0x70, 0x8e, 0xd5, 0xb7,
+  0x11, 0xae, 0xc9, 0x68, 0x4a, 0x40, 0x08, 0x08, 0x57, 0x54, 0x81, 0xad,
+  0x7a, 0xce, 0xc9, 0xcf, 0x00, 0xb2, 0x4b, 0xae, 0x43, 0xc3, 0xe4, 0x35,
+  0x90, 0x68, 0xdf, 0x6c, 0xb2, 0xdf, 0xb3, 0xdd, 0x17, 0xbd, 0x87, 0x24,
+  0x47, 0x57, 0x21, 0x5e, 0xff, 0x00, 0x58, 0x72, 0xa8, 0xfa, 0xc9, 0xa8,
+  0x69, 0xa0, 0x9a, 0x66, 0xee, 0x32, 0xfc, 0x4b, 0x17, 0xfd, 0xaa, 0xb6,
+  0x7d, 0xf8, 0xa7, 0xba, 0x44, 0xe3, 0x27, 0xc4, 0x71, 0x7f, 0xda, 0xab,
+  0x67, 0xdf, 0x8a, 0x7b, 0xa8, 0x24, 0x28, 0xac, 0x6f, 0x47, 0xa9, 0x14,
+  0x50, 0x19, 0xa4, 0xce, 0x38, 0xfc, 0x8f, 0x65, 0xdf, 0x44, 0x48, 0xfe,
+  0x03, 0x4e, 0x74, 0x99, 0xc7, 0x1f, 0x91, 0xec, 0xbb, 0xe8, 0x89, 0x1f,
+  0xc0, 0x68, 0x06, 0xf8, 0xdf, 0x17, 0x6f, 0xe6, 0x0f, 0xb2, 0xb6, 0x56,
+  0xb8, 0xdf, 0x17, 0x6f, 0xe6, 0x0f, 0xb2, 0xb6, 0x50, 0x05, 0x14, 0x51,
+  0x40, 0x14, 0x51, 0x45, 0x01, 0xe5, 0x40, 0x6f, 0x64, 0x6f, 0xd1, 0x5f,
+  0x22, 0x66, 0x56, 0x29, 0x9c, 0x37, 0xe2, 0x5c, 0xbb, 0x55, 0xa9, 0x82,
+  0x5b, 0x8c, 0xb7, 0xf2, 0x4c, 0x5d, 0xa1, 0xd0, 0x48, 0x8c, 0xa1, 0xfe,
+  0x93, 0xb6, 0xa7, 0xfe, 0x11, 0xdb, 0x20, 0x78, 0x14, 0x0e, 0xf2, 0xaa,
+  0xfa, 0xf7, 0x5d, 0x77, 0x55, 0xa7, 0xe1, 0x11, 0x88, 0x4f, 0xc9, 0xb0,
+  0x74, 0xdc, 0x71, 0xef, 0x33, 0x28, 0xc7, 0xa4, 0x26, 0xeb, 0x65, 0x74,
+  0x0d, 0xab, 0xb6, 0x6f, 0xaa, 0x9b, 0xf5, 0x85, 0xa4, 0x14, 0xeb, 0xb8,
+  0x9d, 0x6e, 0xa5, 0x3c, 0x3c, 0xa2, 0x1a, 0xca, 0xc3, 0x39, 0x58, 0xbc,
+  0x5c, 0x6e, 0xb6, 0x06, 0xb2, 0x1c, 0x4e, 0x63, 0xef, 0xa2, 0x77, 0x93,
+  0xcb, 0x0e, 0x34, 0xc7, 0x6c, 0x95, 0x72, 0xa4, 0x75, 0x5a, 0x01, 0xe6,
+  0x28, 0x71, 0xbd, 0x24, 0x94, 0xed, 0x49, 0x52, 0x47, 0x4e, 0xfa, 0xd3,
+  0x96, 0x47, 0xb7, 0x64, 0x13, 0xe3, 0x9c, 0xae, 0xe2, 0xdd, 0x99, 0xb8,
+  0xcc, 0xa8, 0x30, 0xdb, 0xaa, 0x6f, 0xca, 0x9c, 0x25, 0x6d, 0xac, 0x38,
+  0xe2, 0x13, 0xcc, 0x1a, 0x6d, 0x1d, 0x98, 0xd1, 0xde, 0xf6, 0x49, 0x25,
+  0x3d, 0xc5, 0x03, 0xf0, 0x78, 0xcc, 0xa0, 0xc7, 0xb8, 0xb7, 0x12, 0x22,
+  0x15, 0x12, 0xcd, 0x7a, 0x4b, 0x97, 0x2b, 0x43, 0x24, 0x79, 0xb1, 0xce,
+  0xff, 0x00, 0x9e, 0xc2, 0xf5, 0x16, 0x5e, 0x25, 0x49, 0x4f, 0xe8, 0x2d,
+  0x26, 0xad, 0x7c, 0x66, 0xfd, 0x6a, 0xb2, 0x3b, 0x02, 0xc3, 0x36, 0xdd,
+  0x26, 0x3c, 0xc9, 0xcd, 0x6d, 0xd9, 0x4b, 0x68, 0xac, 0x4b, 0x94, 0x14,
+  0xa0, 0xe2, 0x54, 0xb1, 0xf0, 0x96, 0x48, 0xe6, 0xd1, 0xef, 0x4a, 0x86,
+  0xba, 0x77, 0x6b, 0x35, 0x9c, 0x38, 0xf5, 0x32, 0x83, 0x4b, 0x2a, 0x5d,
+  0x0f, 0x78, 0xcc, 0x5b, 0xbc, 0x80, 0x6f, 0x96, 0x64, 0x44, 0x58, 0x7d,
+  0xae, 0x56, 0x27, 0x5d, 0x54, 0xa7, 0x1e, 0x92, 0xd7, 0x7a, 0x42, 0x10,
+  0xdf, 0x2a, 0x18, 0x69, 0x47, 0x44, 0x72, 0xef, 0x7d, 0x09, 0x4e, 0xc5,
+  0x73, 0xe3, 0x32, 0xb1, 0xb9, 0x8e, 0xc6, 0x56, 0x4d, 0xe4, 0xf2, 0x32,
+  0x19, 0xa2, 0x40, 0x75, 0xb9, 0xa9, 0x0b, 0x0c, 0xa9, 0xa5, 0x00, 0xeb,
+  0x0d, 0x85, 0x0d, 0x24, 0x24, 0x29, 0x3d, 0xc3, 0x6a, 0x1a, 0x51, 0xde,
+  0xf7, 0x51, 0x96, 0xd5, 0x5e, 0xe3, 0xde, 0x55, 0xfc, 0x9a, 0x7e, 0x74,
+  0xcb, 0x04, 0x27, 0x9d, 0x8b, 0x1d, 0x2d, 0x21, 0xa5, 0x32, 0xa6, 0xb9,
+  0x42, 0xf4, 0x87, 0x16, 0xe2, 0x79, 0x3b, 0x35, 0xa9, 0x48, 0xe7, 0xd2,
+  0xd2, 0x52, 0x90, 0x06, 0x94, 0x9e, 0xba, 0xe7, 0x2b, 0x1d, 0x94, 0xd4,
+  0xab, 0xcd, 0xf6, 0x6b, 0xd2, 0xa6, 0x2e, 0x68, 0x7d, 0x84, 0x5b, 0x3b,
+  0x43, 0x19, 0x2f, 0x04, 0x25, 0xb6, 0x9a, 0x43, 0xfc, 0xbc, 0x85, 0xd2,
+  0x12, 0x91, 0xce, 0x0a, 0x4e, 0xce, 0x86, 0x87, 0x4a, 0xc9, 0x63, 0x93,
+  0x5d, 0xfa, 0x1b, 0x99, 0x99, 0x79, 0xc7, 0xee, 0xc6, 0xcf, 0x8c, 0x29,
+  0x32, 0x6d, 0x96, 0xd7, 0xc8, 0xf2, 0x61, 0x15, 0xd7, 0x90, 0x58, 0x7c,
+  0x07, 0x12, 0x9e, 0x66, 0xc2, 0x8a, 0x5d, 0x41, 0xe6, 0xd7, 0x30, 0xe5,
+  0x52, 0x14, 0x01, 0x20, 0xf5, 0x39, 0xbd, 0xc6, 0x6a, 0xeb, 0x75, 0x91,
+  0x26, 0xe6, 0x86, 0xd8, 0x9a, 0xe9, 0x8e, 0xa6, 0x2d, 0x6d, 0xc2, 0x6a,
+  0x74, 0x82, 0xa6, 0x82, 0xf9, 0x5e, 0x71, 0x07, 0x61, 0xa5, 0xf9, 0xe3,
+  0x4a, 0xe6, 0x00, 0x04, 0xf5, 0x27, 0xc2, 0x55, 0xfb, 0x06, 0x4f, 0x1b,
+  0x17, 0x96, 0xcd, 0x9a, 0xe1, 0x02, 0xdf, 0x24, 0x36, 0xa5, 0x26, 0xdb,
+  0x0d, 0x80, 0x5b, 0x20, 0xef, 0x69, 0x53, 0xaa, 0x3c, 0xea, 0x75, 0x49,
+  0xfe, 0x93, 0xcd, 0xf3, 0xba, 0x90, 0x6b, 0x7c, 0x0c, 0xab, 0x1e, 0xb2,
+  0xdb, 0x10, 0xa8, 0x16, 0x0b, 0xb3, 0x76, 0xf7, 0x58, 0x4c, 0x96, 0x5c,
+  0x85, 0x6c, 0x75, 0xf4, 0x39, 0xcc, 0x3c, 0xee, 0x65, 0x36, 0x93, 0xca,
+  0xe0, 0x20, 0x85, 0x73, 0x90, 0x7a, 0x6f, 0x7a, 0xeb, 0x4c, 0x92, 0x92,
+  0x36, 0x58, 0xf1, 0xfb, 0xe8, 0x71, 0xe7, 0xd7, 0x2c, 0x5a, 0xd7, 0x2b,
+  0x97, 0xb7, 0x79, 0x4b, 0x12, 0x67, 0x3a, 0x90, 0x4e, 0x92, 0x56, 0x40,
+  0x69, 0xa0, 0x37, 0xf0, 0x50, 0x82, 0x91, 0xb3, 0xae, 0xbb, 0x35, 0x3f,
+  0x6c, 0xb4, 0xda, 0x2c, 0x85, 0xd7, 0xd9, 0x6c, 0x99, 0x2b, 0x47, 0xbf,
+  0x49, 0x79, 0x6a, 0x75, 0xf7, 0x40, 0xfd, 0x25, 0x2b, 0x6a, 0x23, 0xd5,
+  0xdd, 0xe8, 0x14, 0x82, 0xac, 0xc3, 0x3a, 0xcb, 0xd6, 0x23, 0xe1, 0xf6,
+  0x2f, 0x72, 0x20, 0x13, 0xa5, 0x5c, 0x66, 0x29, 0x0e, 0xb8, 0x47, 0x4f,
+  0x82, 0x06, 0xda, 0x49, 0xf5, 0xed, 0xd2, 0x3c, 0x51, 0xba, 0x9b, 0xc6,
+  0xb8, 0x7e, 0x98, 0xf1, 0x94, 0x6f, 0xf7, 0x17, 0xee, 0x2e, 0x3e, 0x42,
+  0xa4, 0x36, 0x1d, 0x51, 0x4b, 0xe7, 0xfd, 0xaa, 0xcf, 0x9e, 0xe8, 0xfd,
+  0x52, 0x43, 0x7e, 0x84, 0x01, 0xa1, 0x50, 0x49, 0x2e, 0xac, 0xba, 0xd9,
+  0x21, 0x45, 0x8b, 0x33, 0x32, 0xaf, 0x32, 0x47, 0x9a, 0x5a, 0x88, 0xdf,
+  0x44, 0x1f, 0xd7, 0x5a, 0xb4, 0x94, 0x7b, 0x14, 0x77, 0xea, 0xa8, 0x36,
+  0x30, 0x69, 0x97, 0x15, 0x22, 0x7d, 0xd6, 0x44, 0x68, 0x72, 0x7c, 0xbd,
+  0xc9, 0xcd, 0xc7, 0x66, 0x3b, 0x72, 0x04, 0x45, 0x2f, 0x5f, 0x93, 0x71,
+  0xc4, 0xed, 0x2b, 0x3a, 0xda, 0xba, 0x14, 0xec, 0x9e, 0x9e, 0x25, 0xbd,
+  0xd9, 0x16, 0xbb, 0x34, 0x34, 0x30, 0x90, 0xcc, 0x66, 0x90, 0x34, 0xdb,
+  0x2d, 0x20, 0x0d, 0x7a, 0x82, 0x45, 0x25, 0x66, 0xbc, 0x47, 0xb7, 0x59,
+  0x5b, 0x6c, 0x4a, 0x96, 0x88, 0x21, 0xf3, 0xca, 0xc3, 0x41, 0x25, 0xd9,
+  0x2f, 0x9f, 0x43, 0x6d, 0xa7, 0x6a, 0x51, 0xf5, 0x24, 0x13, 0xec, 0xad,
+  0x69, 0xd1, 0x94, 0xf7, 0x5c, 0x79, 0x98, 0xce, 0xb4, 0x61, 0xb7, 0x51,
+  0xb6, 0x0c, 0x6b, 0x46, 0x37, 0x01, 0x4d, 0xa5, 0xd5, 0x24, 0xb8, 0xe1,
+  0x75, 0xd7, 0x1e, 0x70, 0xb8, 0xf3, 0xee, 0x10, 0x01, 0x5a, 0x89, 0xea,
+  0xa5, 0x74, 0x03, 0xd0, 0x00, 0x00, 0x68, 0x00, 0x2a, 0x26, 0xe5, 0x92,
+  0x3c, 0xf7, 0xbd, 0x42, 0x41, 0x65, 0x04, 0xeb, 0x9c, 0x80, 0x54, 0x7d,
+  0x9e, 0x03, 0xed, 0xaa, 0xba, 0xff, 0x00, 0x94, 0x5c, 0xa3, 0x34, 0xdd,
+  0xeb, 0x2c, 0x9f, 0x17, 0x03, 0xc7, 0xcf, 0x9c, 0xa9, 0x17, 0x87, 0x02,
+  0xee, 0x72, 0x87, 0xa1, 0x98, 0xe9, 0x27, 0x93, 0x7d, 0xdb, 0x57, 0x31,
+  0xd7, 0xe6, 0x8a, 0x81, 0xfc, 0x6e, 0x66, 0x19, 0xb3, 0x6e, 0xc3, 0xe0,
+  0x16, 0x07, 0x22, 0x5b, 0x68, 0xf3, 0x1e, 0xc8, 0xaf, 0x49, 0x4b, 0x4c,
+  0xa3, 0xae, 0xbd, 0xed, 0x2a, 0x20, 0x28, 0xf8, 0xf5, 0x3b, 0xfd, 0x4a,
+  0xd5, 0x7b, 0xaa, 0x5b, 0xbe, 0xf3, 0xfd, 0x0c, 0xa4, 0xab, 0x55, 0xf4,
+  0x45, 0xb9, 0x75, 0xc9, 0x2c, 0x7c, 0x3c, 0xc5, 0xa7, 0x65, 0x59, 0x7d,
+  0xc1, 0xb8, 0x2c, 0x84, 0x79, 0x89, 0x71, 0x5e, 0xfa, 0xf1, 0xd7, 0x44,
+  0x21, 0x3d, 0xea, 0x52, 0x8e, 0xb4, 0x3c, 0x3b, 0xfb, 0xb6, 0x6b, 0x9b,
+  0xf0, 0x6f, 0xb3, 0x5c, 0xed, 0xbc, 0x37, 0x17, 0x5b, 0xdb, 0x45, 0x9b,
+  0xae, 0x47, 0x3a, 0x45, 0xf2, 0x63, 0x47, 0xbd, 0xb5, 0x49, 0x5f, 0x3a,
+  0x52, 0x7d, 0x61, 0x1c, 0x80, 0x8f, 0x03, 0xb1, 0x4b, 0xdc, 0x3b, 0xe0,
+  0x44, 0x66, 0xae, 0x4d, 0x65, 0x9c, 0x54, 0xba, 0x39, 0x9c, 0x65, 0x9b,
+  0xe6, 0x4b, 0x93, 0x09, 0x5c, 0x48, 0x7d, 0x76, 0x12, 0xcb, 0x47, 0xcd,
+  0xe9, 0xd3, 0xa9, 0x1a, 0xd8, 0xd8, 0x02, 0xae, 0xc0, 0x3a, 0x77, 0x56,
+  0x15, 0x26, 0xe7, 0x27, 0x26, 0x6f, 0x4e, 0x0a, 0x11, 0xd2, 0x84, 0x5e,
+  0x32, 0x7c, 0x47, 0x17, 0xfd, 0xaa, 0xb6, 0x7d, 0xf8, 0xa7, 0xba, 0x44,
+  0xe3, 0x20, 0xd4, 0x1c, 0x5c, 0x7f, 0xf7, 0x55, 0xb3, 0xef, 0xc5, 0x3d,
+  0xd5, 0x0b, 0x9e, 0x57, 0xdf, 0xd0, 0x91, 0x45, 0x64, 0x8d, 0x9a, 0x28,
+  0x43, 0xc9, 0x9a, 0x4c, 0xe3, 0x8f, 0xc8, 0xf6, 0x5d, 0xf4, 0x44, 0x8f,
+  0xe0, 0x34, 0xe7, 0x50, 0x1c, 0x45, 0xb2, 0xc8, 0xc9, 0x30, 0x5b, 0xe6,
+  0x3f, 0x11, 0xd6, 0xd9, 0x91, 0x70, 0x82, 0xec, 0x66, 0x9c, 0x73, 0x7c,
+  0x89, 0x52, 0xd2, 0x40, 0x2a, 0xd7, 0x5d, 0x6e, 0x84, 0x93, 0x71, 0xbe,
+  0x2e, 0xdf, 0xcc, 0x1f, 0x65, 0x6c, 0xaa, 0xfd, 0xbf, 0xc7, 0x2a, 0x1b,
+  0x4a, 0x03, 0x58, 0x11, 0x09, 0x1a, 0xdf, 0x69, 0x2f, 0xaf, 0xfd, 0x35,
+  0xeb, 0x9b, 0x8c, 0xbf, 0xd4, 0xe0, 0x3f, 0xbd, 0x97, 0xfe, 0x5a, 0x01,
+  0xfa, 0x8a, 0x41, 0xe7, 0xe3, 0x2f, 0xf5, 0x58, 0x0f, 0xef, 0x65, 0xff,
+  0x00, 0x96, 0x8e, 0x6e, 0x32, 0xff, 0x00, 0x53, 0x80, 0xfe, 0xf6, 0x5f,
+  0xf9, 0x68, 0x07, 0xea, 0x29, 0x07, 0x9b, 0x8c, 0xbf, 0xd4, 0xe0, 0x3f,
+  0xbd, 0x97, 0xfe, 0x5a, 0x39, 0xf8, 0xcb, 0xfd, 0x56, 0x03, 0xfb, 0xd9,
+  0x7f, 0xe5, 0xa0, 0x1f, 0xa8, 0x23, 0x74, 0x83, 0xcf, 0xc6, 0x5f, 0xea,
+  0xb0, 0x1f, 0xde, 0x4b, 0xff, 0x00, 0x2d, 0x1c, 0xfc, 0x65, 0xfe, 0xab,
+  0x01, 0xfd, 0xe4, 0xbf, 0xf2, 0xd0, 0x14, 0x97, 0x15, 0x71, 0x49, 0x58,
+  0x87, 0x12, 0xe5, 0x5a, 0xac, 0xc8, 0x4b, 0x31, 0xf2, 0x49, 0x26, 0xfd,
+  0x8b, 0x2f, 0x5a, 0x44, 0x7b, 0xdb, 0x29, 0xf7, 0xf8, 0xbb, 0xee, 0x4a,
+  0x24, 0xb5, 0xb4, 0xf5, 0xe8, 0x49, 0x00, 0x7c, 0x1a, 0xb3, 0x2c, 0x37,
+  0x9b, 0x06, 0x55, 0x83, 0xc5, 0xc8, 0x5a, 0xb7, 0x31, 0x29, 0xf9, 0x4c,
+  0x33, 0xe4, 0xe2, 0x43, 0x8a, 0x42, 0x3c, 0xe5, 0xa5, 0x1c, 0x8f, 0x80,
+  0x47, 0x30, 0x6d, 0x44, 0xec, 0x1f, 0xd1, 0x23, 0xa5, 0x70, 0x71, 0x73,
+  0x0c, 0xe2, 0xb6, 0x77, 0x88, 0xb9, 0x6b, 0x94, 0x30, 0xc8, 0xf2, 0xa3,
+  0x3c, 0xdc, 0xdb, 0x7c, 0x98, 0xae, 0xc9, 0x0f, 0x47, 0x92, 0xd2, 0xb9,
+  0x90, 0xb4, 0x15, 0x27, 0x5b, 0xef, 0x1d, 0x7a, 0x75, 0x35, 0x5f, 0xf0,
+  0xb7, 0x26, 0x8e, 0xbb, 0x82, 0x15, 0x36, 0x30, 0x8d, 0x6b, 0xcb, 0x5f,
+  0x75, 0x46, 0x3a, 0xba, 0x22, 0x05, 0xe9, 0x03, 0x53, 0xa1, 0x11, 0xde,
+  0x8e, 0xd0, 0xe9, 0xe4, 0x0e, 0x9b, 0xe6, 0x20, 0x75, 0xad, 0xa9, 0x62,
+  0x59, 0x83, 0xeb, 0xf5, 0x32, 0xab, 0x98, 0xe2, 0x6b, 0xa7, 0xd0, 0xbb,
+  0xaf, 0xd8, 0xcc, 0xc7, 0xf1, 0xc7, 0x84, 0x6b, 0xf4, 0xab, 0x84, 0x86,
+  0x39, 0x43, 0x90, 0x92, 0x50, 0xd4, 0x57, 0xd0, 0x85, 0x02, 0xa8, 0xdd,
+  0x92, 0x46, 0x90, 0x14, 0x01, 0x47, 0x7f, 0x30, 0xd8, 0xd9, 0x22, 0xb5,
+  0x8c, 0xaa, 0xd7, 0x7a, 0xb5, 0xcf, 0x85, 0x75, 0xb7, 0xaa, 0x1d, 0x95,
+  0xc4, 0x21, 0x31, 0xe5, 0x1f, 0x35, 0x0f, 0x34, 0xb4, 0x05, 0x20, 0xb4,
+  0x40, 0x3b, 0x75, 0x2a, 0xf3, 0x79, 0x13, 0xe7, 0x25, 0x43, 0xbb, 0xbb,
+  0x7a, 0x2d, 0x38, 0xeb, 0x8e, 0x4f, 0x9d, 0x2e, 0x35, 0xf2, 0x34, 0x06,
+  0x27, 0xbc, 0x1f, 0x7c, 0xb4, 0x55, 0xdb, 0x73, 0x84, 0xf2, 0xa9, 0x49,
+  0x42, 0xd4, 0x5b, 0x6d, 0x64, 0x6b, 0x99, 0x41, 0x24, 0x12, 0x37, 0xa0,
+  0x69, 0x86, 0x1c, 0x3c, 0x36, 0xc4, 0x96, 0x97, 0x0a, 0x0d, 0xbd, 0x0f,
+  0x32, 0xd8, 0x6d, 0x0e, 0x34, 0xca, 0x54, 0xe9, 0x00, 0x6b, 0xaa, 0xb5,
+  0xb2, 0x75, 0xe2, 0x4d, 0x46, 0x86, 0x9e, 0x31, 0xb8, 0xf7, 0x89, 0xac,
+  0xb7, 0xb0, 0xaf, 0x8b, 0xd8, 0xf3, 0x56, 0xe7, 0xfb, 0xae, 0x97, 0x0c,
+  0x65, 0xdc, 0x63, 0xb2, 0xf4, 0xc6, 0xe5, 0xc8, 0x05, 0xae, 0xdc, 0x34,
+  0x84, 0x17, 0x0b, 0x49, 0x6c, 0x2c, 0x2f, 0x49, 0x1b, 0x6f, 0x9c, 0x27,
+  0x7b, 0x3b, 0x1b, 0xd5, 0x34, 0xda, 0xb0, 0x7c, 0x7a, 0x24, 0x66, 0x53,
+  0x2e, 0x13, 0x57, 0x09, 0x28, 0xda, 0xdd, 0x7d, 0xf4, 0x03, 0xdb, 0x38,
+  0x54, 0x54, 0xa5, 0xa9, 0x3f, 0x07, 0x7b, 0x51, 0xd7, 0x4e, 0x9d, 0x00,
+  0xee, 0xa2, 0x46, 0x54, 0x80, 0x9d, 0x45, 0x8a, 0x48, 0x00, 0xf9, 0xce,
+  0x2b, 0xa0, 0xf6, 0xeb, 0xff, 0x00, 0x35, 0x5d, 0x5d, 0xb8, 0xb3, 0x06,
+  0xe5, 0x70, 0x55, 0xaa, 0xc2, 0xec, 0xdc, 0xa2, 0xe2, 0x09, 0x06, 0x05,
+  0x81, 0xae, 0xdf, 0x93, 0xc3, 0xdf, 0x1c, 0x04, 0x36, 0xd8, 0xdf, 0x8a,
+  0xd6, 0x2b, 0x4f, 0xb3, 0xcf, 0x99, 0xec, 0x67, 0xf6, 0x88, 0x7e, 0x0d,
+  0xcb, 0x66, 0x7d, 0xe2, 0xdd, 0x01, 0x1d, 0x99, 0x70, 0x2d, 0x69, 0xee,
+  0x6d, 0xbe, 0xba, 0xff, 0x00, 0xb0, 0xa4, 0x1c, 0xd7, 0x89, 0x96, 0xfb,
+  0x4b, 0xad, 0xc4, 0x93, 0x38, 0x31, 0x2a, 0x47, 0x48, 0xf0, 0x22, 0xb6,
+  0xa7, 0xe6, 0x3e, 0x7c, 0x39, 0x5b, 0x40, 0x2b, 0x3f, 0xdc, 0x07, 0xaf,
+  0xc6, 0xa9, 0x0e, 0x23, 0x71, 0x3d, 0x16, 0x82, 0xa8, 0xd9, 0x4e, 0x55,
+  0x1e, 0xc8, 0xe9, 0x25, 0x3e, 0xe0, 0x62, 0xee, 0x22, 0x75, 0xcd, 0x5d,
+  0xfe, 0x63, 0xd2, 0xcf, 0xbd, 0x47, 0x3b, 0xef, 0xe4, 0x05, 0x5d, 0x7a,
+  0x1a, 0xe3, 0xe1, 0xe5, 0x87, 0x8c, 0xb9, 0x84, 0x59, 0x3f, 0x8b, 0xfc,
+  0x5e, 0x17, 0x0a, 0xec, 0x32, 0x92, 0xa5, 0x2a, 0xeb, 0x24, 0x2d, 0xcb,
+  0x8c, 0xde, 0xa3, 0x5d, 0xa3, 0xee, 0x6d, 0xe5, 0x6f, 0x5b, 0xda, 0x42,
+  0x53, 0x4d, 0x54, 0xe9, 0xf8, 0x56, 0x5f, 0x9b, 0x1a, 0x2a, 0x54, 0xf1,
+  0x3c, 0x21, 0xcb, 0x39, 0xce, 0xa5, 0x5b, 0x23, 0x2e, 0x5e, 0x53, 0x7d,
+  0x87, 0xc3, 0xd8, 0x4b, 0x47, 0x3a, 0x1a, 0x92, 0x53, 0x32, 0xfb, 0x21,
+  0x3d, 0x3a, 0xa2, 0x32, 0x49, 0x43, 0x3b, 0xde, 0xb9, 0x96, 0x54, 0x47,
+  0x88, 0x14, 0x85, 0x88, 0x5d, 0xf8, 0x8b, 0x9a, 0xce, 0x77, 0xf1, 0x29,
+  0x83, 0x39, 0x61, 0x8d, 0x23, 0x68, 0x7f, 0x31, 0xbf, 0xab, 0xb7, 0x9c,
+  0xfa, 0x77, 0xa3, 0xa7, 0x9c, 0x05, 0x29, 0x1f, 0xa8, 0xd8, 0x56, 0xb5,
+  0xd3, 0x54, 0xcf, 0x80, 0xfe, 0x0b, 0xd7, 0xcc, 0x76, 0xf0, 0x6f, 0x77,
+  0xa4, 0xe2, 0xb9, 0x75, 0xd7, 0xb5, 0xed, 0x43, 0xd7, 0x79, 0x12, 0x94,
+  0xdf, 0x30, 0x3b, 0x0a, 0x2d, 0x84, 0xe9, 0x67, 0xe7, 0x95, 0x0a, 0xbc,
+  0x59, 0x6f, 0x8c, 0x0c, 0x34, 0x86, 0x99, 0x8d, 0xc3, 0xf6, 0xdb, 0x6d,
+  0x21, 0x28, 0x4a, 0x57, 0x2d, 0x21, 0x29, 0x1d, 0xc0, 0x00, 0x9e, 0x83,
+  0xa7, 0x75, 0x65, 0x3a, 0xb2, 0x9f, 0x2c, 0xda, 0x14, 0xa3, 0x0e, 0x0a,
+  0xfb, 0x02, 0xfc, 0x18, 0xf1, 0xd8, 0xd7, 0x04, 0xe4, 0x1c, 0x4a, 0xbb,
+  0x4e, 0xce, 0xef, 0xeb, 0x57, 0x3b, 0x8b, 0x9c, 0xea, 0x8c, 0x60, 0xae,
+  0x9d, 0x39, 0x09, 0x25, 0x7a, 0x3d, 0x34, 0xa2, 0x53, 0xa1, 0xf0, 0x45,
+  0x5f, 0x70, 0xe1, 0xc5, 0x87, 0x11, 0xa8, 0x90, 0xe3, 0xb5, 0x1a, 0x3b,
+  0x29, 0x08, 0x6d, 0xa6, 0x90, 0x10, 0x94, 0x24, 0x78, 0x00, 0x3a, 0x01,
+  0xec, 0xa4, 0x7d, 0xf1, 0x93, 0xfa, 0xac, 0x07, 0xf7, 0x92, 0xff, 0x00,
+  0xcb, 0x59, 0x0a, 0xe3, 0x2f, 0xf5, 0x38, 0x0f, 0xef, 0x65, 0xff, 0x00,
+  0x96, 0xb3, 0x2e, 0x3e, 0xe8, 0x56, 0x47, 0x4a, 0x41, 0xe7, 0xe3, 0x2f,
+  0xf5, 0x58, 0x0f, 0xef, 0x65, 0xff, 0x00, 0x96, 0x8e, 0x7e, 0x32, 0xff,
+  0x00, 0x55, 0x80, 0xfe, 0xf2, 0x5f, 0xf9, 0x68, 0x0f, 0x7c, 0x65, 0xf8,
+  0x96, 0x2f, 0xfb, 0x55, 0x6c, 0xfb, 0xf1, 0x4f, 0x75, 0x58, 0xdd, 0xac,
+  0x5c, 0x4d, 0xc8, 0x66, 0x59, 0x5a, 0xbe, 0xaf, 0x10, 0x62, 0x04, 0x1b,
+  0xb4, 0x6b, 0x83, 0xa6, 0x12, 0xa4, 0x17, 0x54, 0x19, 0x58, 0x57, 0x2a,
+  0x42, 0xc6, 0xba, 0xea, 0xac, 0xea, 0x00, 0xa2, 0xb0, 0x49, 0xf0, 0xa2,
+  0x80, 0xcd, 0x1a, 0xeb, 0x45, 0x14, 0x01, 0x45, 0x14, 0x50, 0x05, 0x14,
+  0x51, 0x40, 0x14, 0x51, 0x45, 0x00, 0x51, 0x45, 0x14, 0x01, 0x5f, 0x2b,
+  0x7e, 0x11, 0x38, 0x75, 0xcf, 0x0a, 0xc9, 0xef, 0x79, 0x7c, 0x1c, 0x7d,
+  0xeb, 0xf6, 0x09, 0x91, 0x86, 0x9c, 0xc8, 0xe0, 0x43, 0x51, 0x4c, 0xa8,
+  0x12, 0xdb, 0xdf, 0x24, 0xe6, 0x08, 0xf8, 0x0b, 0x1f, 0x0b, 0x98, 0x74,
+  0xdf, 0x30, 0x57, 0x42, 0x0d, 0x7d, 0x53, 0x58, 0x52, 0x42, 0xba, 0x28,
+  0x6c, 0x1e, 0x84, 0x50, 0x1f, 0x19, 0xe3, 0x3c, 0x46, 0xe2, 0x5c, 0x7b,
+  0x12, 0x2e, 0x96, 0x9b, 0x64, 0x1e, 0x28, 0x63, 0xcd, 0x68, 0x79, 0x75,
+  0xad, 0x65, 0xab, 0x93, 0x49, 0xf0, 0x12, 0x23, 0x8d, 0xa9, 0x0e, 0x01,
+  0xde, 0x42, 0x08, 0xdf, 0xe7, 0x10, 0x76, 0x58, 0xec, 0xdc, 0x52, 0xcb,
+  0xb2, 0x08, 0xcb, 0x7e, 0xd5, 0xc3, 0x29, 0x76, 0x88, 0x6d, 0x90, 0x97,
+  0xae, 0x99, 0x1c, 0xe4, 0xdb, 0xe1, 0x32, 0x77, 0xd4, 0xa9, 0x6a, 0x4e,
+  0xd5, 0xeb, 0x09, 0xd9, 0xf5, 0x55, 0x8d, 0xc4, 0x0f, 0xc1, 0xd7, 0x05,
+  0xc8, 0xee, 0xc6, 0xfb, 0x65, 0x72, 0xe3, 0x87, 0xde, 0xf7, 0xbf, 0x2d,
+  0xb1, 0xbd, 0xe4, 0xfc, 0xc7, 0xd2, 0xa4, 0x01, 0xad, 0xf8, 0xec, 0x68,
+  0x93, 0xd4, 0x9a, 0xe6, 0xb4, 0x7e, 0x0d, 0xb8, 0x6a, 0xee, 0xcd, 0xdd,
+  0xf3, 0x4b, 0xce, 0x49, 0x9c, 0xce, 0x6c, 0x0e, 0x53, 0x7c, 0xb8, 0x29,
+  0xd6, 0xc6, 0xbf, 0x50, 0x6b, 0x63, 0xa0, 0xe8, 0x49, 0x1e, 0xaa, 0xdd,
+  0x5c, 0xd4, 0x4b, 0x19, 0x30, 0x76, 0xd4, 0xdb, 0xcb, 0x45, 0x4d, 0x17,
+  0x3f, 0x72, 0x6d, 0xc3, 0xdc, 0xeb, 0x42, 0x2e, 0x9c, 0x5e, 0xc9, 0x04,
+  0x80, 0xf0, 0x62, 0xcc, 0xca, 0xe1, 0x59, 0xa0, 0x10, 0x85, 0x23, 0xb3,
+  0x2b, 0xef, 0x79, 0x1e, 0x79, 0x27, 0x9f, 0xcd, 0x3a, 0x1d, 0xd4, 0xe9,
+  0x03, 0x83, 0xfc, 0x55, 0xcc, 0xed, 0xcd, 0xc3, 0xcd, 0xf2, 0xe8, 0x18,
+  0x56, 0x3c, 0x47, 0xfa, 0xb7, 0x8a, 0x47, 0x0d, 0x23, 0x93, 0xa7, 0x9a,
+  0xb7, 0x3b, 0xbc, 0x07, 0x7f, 0x38, 0xaf, 0xa1, 0x6c, 0xf6, 0x9b, 0x5d,
+  0x9a, 0x0a, 0x60, 0x5a, 0x2d, 0xd1, 0x2d, 0xf1, 0x11, 0xf0, 0x59, 0x8a,
+  0xca, 0x5a, 0x40, 0xf6, 0x25, 0x20, 0x0a, 0xec, 0x00, 0x0a, 0xca, 0x53,
+  0x94, 0xb9, 0x35, 0x8c, 0x23, 0x1e, 0x11, 0x5f, 0x70, 0xe3, 0x82, 0xfc,
+  0x36, 0xc0, 0x43, 0x4e, 0xe3, 0xd8, 0xcc, 0x51, 0x35, 0xb1, 0xf1, 0xe9,
+  0x43, 0xb7, 0x92, 0x4f, 0xa7, 0x9d, 0x7b, 0xe5, 0x3f, 0x37, 0x43, 0xd5,
+  0x56, 0x0f, 0x28, 0xac, 0x81, 0xae, 0xea, 0x2a, 0xa5, 0x8c, 0x68, 0x56,
+  0x68, 0xa2, 0x80, 0x28, 0xa2, 0x8a, 0x00, 0xa2, 0x8a, 0x28, 0x03, 0x42,
+  0x8a, 0x28, 0xa0, 0x30, 0x52, 0x0f, 0x7d, 0x15, 0x9a, 0x28, 0x02, 0x8a,
+  0x28, 0xa0, 0x0a, 0x28, 0xa2, 0x80, 0x28, 0xa2, 0x8a, 0x00, 0xa2, 0x8a,
+  0x28, 0x02, 0x8a, 0x28, 0xa0, 0x0a, 0x28, 0xa2, 0x80, 0x35, 0x45, 0x14,
+  0x50, 0x05, 0x14, 0x51, 0x40, 0x14, 0x51, 0x45, 0x00, 0x51, 0x45, 0x14,
+  0x01, 0x45, 0x14, 0x50, 0x05, 0x14, 0x51, 0x40, 0x14, 0x51, 0x45, 0x00,
+  0x51, 0x45, 0x14, 0x07, 0xff, 0xd9
+};
diff --git a/camera/libcameraservice/FakeCamera.cpp b/camera/libcameraservice/FakeCamera.cpp
new file mode 100644
index 0000000..3592eab
--- /dev/null
+++ b/camera/libcameraservice/FakeCamera.cpp
@@ -0,0 +1,404 @@
+#define LOG_TAG "FakeCamera"
+#include <utils/Log.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include "FakeCamera.h"
+
+namespace android {
+
+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 = (ALPHA*(pixels & 0x001F) + BETA*(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 = (ALPHA*(pixels & 0x001F) + BETA*(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[(((R_ds-G_ds)<<SHIFT2) + DELTA*tmp)>>(SHIFT2+2)];
+            v = cr_tab[(((B_ds-G_ds)<<SHIFT2) - GAMMA*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++;
+}
+
+
+status_t FakeCamera::dump(int fd, const Vector<String16>& args)
+{
+    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());
+    return NO_ERROR;
+}
+
+
+}; // namespace android
diff --git a/camera/libcameraservice/FakeCamera.h b/camera/libcameraservice/FakeCamera.h
new file mode 100644
index 0000000..77c994c
--- /dev/null
+++ b/camera/libcameraservice/FakeCamera.h
@@ -0,0 +1,51 @@
+/*
+**
+** 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 <ui/CameraHardwareInterface.h>
+
+namespace android {
+
+class FakeCamera {
+public:
+    FakeCamera(int width, int height);
+    ~FakeCamera();
+
+    void setSize(int width, int height);
+    void getNextFrameAsRgb565(uint16_t *buffer);
+    void getNextFrameAsYuv422(uint8_t *buffer);
+    status_t dump(int fd, const Vector<String16>& args);
+
+private:
+    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/cmds/runtime/Android.mk b/cmds/runtime/Android.mk
new file mode 100644
index 0000000..00fa8a2
--- /dev/null
+++ b/cmds/runtime/Android.mk
@@ -0,0 +1,29 @@
+ifeq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	ServiceManager.cpp \
+	SignalHandler.cpp \
+	main_runtime.cpp 
+
+LOCAL_SHARED_LIBRARIES := \
+	libutils \
+	libandroid_runtime \
+	libcutils \
+	libui \
+	libsystem_server \
+	libhardware
+
+LOCAL_C_INCLUDES := \
+	$(JNI_H_INCLUDE)
+
+ifeq ($(TARGET_OS),linux)
+	LOCAL_CFLAGS += -DXP_UNIX
+endif
+
+LOCAL_MODULE:= runtime
+
+include $(BUILD_EXECUTABLE)
+endif
diff --git a/cmds/runtime/MODULE_LICENSE_APACHE2 b/cmds/runtime/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/runtime/MODULE_LICENSE_APACHE2
diff --git a/cmds/runtime/NOTICE b/cmds/runtime/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/cmds/runtime/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/cmds/runtime/ServiceManager.cpp b/cmds/runtime/ServiceManager.cpp
new file mode 100644
index 0000000..758a95c
--- /dev/null
+++ b/cmds/runtime/ServiceManager.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+
+#define LOG_TAG "ServiceManager"
+
+#include "ServiceManager.h"
+#include "SignalHandler.h"
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/String8.h>
+#include <utils/ProcessState.h>
+
+#include <private/utils/Static.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+namespace android {
+
+BServiceManager::BServiceManager()
+{
+}
+
+sp<IBinder> BServiceManager::getService(const String16& name) const
+{
+    AutoMutex _l(mLock);
+    ssize_t i = mServices.indexOfKey(name);
+    LOGV("ServiceManager: getService(%s) -> %d\n", String8(name).string(), i);
+    if (i >= 0) return mServices.valueAt(i);
+    return NULL;
+}
+
+sp<IBinder> BServiceManager::checkService(const String16& name) const
+{
+    AutoMutex _l(mLock);
+    ssize_t i = mServices.indexOfKey(name);
+    LOGV("ServiceManager: getService(%s) -> %d\n", String8(name).string(), i);
+    if (i >= 0) return mServices.valueAt(i);
+    return NULL;
+}
+
+status_t BServiceManager::addService(const String16& name, const sp<IBinder>& service)
+{
+    AutoMutex _l(mLock);
+    LOGI("ServiceManager: addService(%s, %p)\n", String8(name).string(), service.get());
+    const ssize_t res = mServices.add(name, service);
+    if (res >= NO_ERROR) {
+        mChanged.broadcast();
+        return NO_ERROR;
+    }
+    return res;
+}
+
+Vector<String16> BServiceManager::listServices()
+{
+    Vector<String16> res;
+
+    AutoMutex _l(mLock);
+    const size_t N = mServices.size();
+    for (size_t i=0; i<N; i++) {
+        res.add(mServices.keyAt(i));
+    }
+
+    return res;
+}
+
+}; // namespace android
diff --git a/cmds/runtime/ServiceManager.h b/cmds/runtime/ServiceManager.h
new file mode 100644
index 0000000..d09cec8
--- /dev/null
+++ b/cmds/runtime/ServiceManager.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+#ifndef ANDROID_SERVICE_MANAGER_H
+#define ANDROID_SERVICE_MANAGER_H
+
+#include <utils/IServiceManager.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BServiceManager : public BnServiceManager
+{
+public:
+                                BServiceManager();
+    
+    virtual sp<IBinder>         getService( const String16& name) const;
+    virtual sp<IBinder>         checkService( const String16& name) const;
+    virtual status_t            addService( const String16& name,
+                                            const sp<IBinder>& service);
+    virtual Vector<String16>    listServices();
+
+    
+private:
+    mutable Mutex               mLock;
+    mutable Condition           mChanged;
+    sp<IPermissionController>   mPermissionController;
+    KeyedVector<String16, sp<IBinder> > mServices;
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_SERVICE_MANAGER_H
diff --git a/cmds/runtime/SignalHandler.cpp b/cmds/runtime/SignalHandler.cpp
new file mode 100644
index 0000000..cccaabf
--- /dev/null
+++ b/cmds/runtime/SignalHandler.cpp
@@ -0,0 +1,249 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+
+#define LOG_TAG "SignalHandler"
+
+#include "SignalHandler.h"
+
+#include <utils/Atomic.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+namespace android {
+
+class SignalHandler::ProcessThread : public Thread
+{
+public:
+    ProcessThread(SignalHandler& sh)
+        : Thread(false)
+        , mOwner(sh)
+    {
+    }
+
+    virtual bool threadLoop()
+    {
+        char buffer[32];
+        read(mOwner.mAvailMsg[0], buffer, sizeof(buffer));
+
+        LOGV("Signal command processing thread woke up!");
+
+        if (mOwner.mLostCommands) {
+            LOGE("Lost %d signals!", mOwner.mLostCommands);
+            mOwner.mLostCommands = 0;
+        }
+
+        int cur;
+        while ((cur=mOwner.mCommandBottom) != mOwner.mCommandTop) {
+            if (mOwner.mCommands[cur].filled == 0) {
+                LOGV("Command at %d is not yet filled", cur);
+                break;
+            }
+
+            LOGV("Processing command at %d, top is %d",
+                 cur, mOwner.mCommandTop);
+            processCommand(mOwner.mCommands[cur]);
+            mOwner.mCommands[cur].filled = 0;
+
+            int next = mOwner.mCommandBottom+1;
+            if (next >= COMMAND_QUEUE_SIZE) {
+                next = 0;
+            }
+
+            mOwner.mCommandBottom = next;
+        }
+
+        return true;
+    }
+
+    void processCommand(const CommandEntry& entry)
+    {
+        switch (entry.signum) {
+        case SIGCHLD: {
+            mOwner.mLock.lock();
+            ssize_t i = mOwner.mChildHandlers.indexOfKey(entry.info.si_pid);
+            ChildHandler ch;
+            if (i >= 0) {
+                ch = mOwner.mChildHandlers.valueAt(i);
+                mOwner.mChildHandlers.removeItemsAt(i);
+            }
+            mOwner.mLock.unlock();
+
+            LOGD("SIGCHLD: pid=%d, handle index=%d", entry.info.si_pid, i);
+
+            if (i >= 0) {
+                int res = waitpid(entry.info.si_pid, NULL, WNOHANG);
+                LOGW_IF(res == 0,
+                        "Received SIGCHLD, but pid %d is not yet stopped",
+                        entry.info.si_pid);
+                if (ch.handler) {
+                    ch.handler(entry.info.si_pid, ch.userData);
+                }
+            } else {
+                LOGW("Unhandled SIGCHLD for pid %d", entry.info.si_pid);
+            }
+        } break;
+        }
+    }
+
+    SignalHandler& mOwner;
+};
+
+
+Mutex SignalHandler::mInstanceLock;
+SignalHandler* SignalHandler::mInstance = NULL;
+
+status_t SignalHandler::setChildHandler(pid_t childPid,
+                                        int tag,
+                                        child_callback_t handler,
+                                        void* userData)
+{
+    SignalHandler* const self = getInstance();
+
+    self->mLock.lock();
+
+    // First make sure this child hasn't already exited.
+    pid_t res = waitpid(childPid, NULL, WNOHANG);
+    if (res != 0) {
+        if (res < 0) {
+            LOGW("setChildHandler waitpid of %d failed: %d (%s)",
+                 childPid, res, strerror(errno));
+        } else {
+            LOGW("setChildHandler waitpid of %d said %d already dead",
+                 childPid, res);
+        }
+
+        // Some kind of error...  just handle the exit now.
+        self->mLock.unlock();
+
+        if (handler) {
+            handler(childPid, userData);
+        }
+
+        // Return an error code -- 0 means it already exited.
+        return (status_t)res;
+    }
+
+    ChildHandler entry;
+    entry.childPid = childPid;
+    entry.tag = tag;
+    entry.handler = handler;
+    entry.userData = userData;
+
+    // Note: this replaces an existing entry for this pid, if there already
+    // is one.  This is the required behavior.
+    LOGD("setChildHandler adding pid %d, tag %d, handler %p, data %p",
+         childPid, tag, handler, userData);
+    self->mChildHandlers.add(childPid, entry);
+
+    self->mLock.unlock();
+
+    return NO_ERROR;
+}
+
+void SignalHandler::killAllChildren(int tag)
+{
+    SignalHandler* const self = getInstance();
+
+    AutoMutex _l (self->mLock);
+    const size_t N = self->mChildHandlers.size();
+    for (size_t i=0; i<N; i++) {
+        const ChildHandler& ch(self->mChildHandlers.valueAt(i));
+        if (tag == 0 || ch.tag == tag) {
+            const pid_t pid = ch.childPid;
+            LOGI("Killing child %d (tag %d)\n", pid, ch.tag);
+            kill(pid, SIGKILL);
+        }
+    }
+}
+
+SignalHandler::SignalHandler()
+    : mCommandTop(0)
+    , mCommandBottom(0)
+    , mLostCommands(0)
+{
+    memset(mCommands, 0, sizeof(mCommands));
+
+    int res = pipe(mAvailMsg);
+    LOGE_IF(res != 0, "Unable to create signal handler pipe: %s", strerror(errno));
+
+    mProcessThread = new ProcessThread(*this);
+    mProcessThread->run("SignalHandler", PRIORITY_HIGHEST);
+
+    struct sigaction sa;
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_sigaction = sigAction;
+    sa.sa_flags = SA_NOCLDSTOP|SA_SIGINFO;
+    sigaction(SIGCHLD, &sa, NULL);
+}
+
+SignalHandler::~SignalHandler()
+{
+}
+
+SignalHandler* SignalHandler::getInstance()
+{
+    AutoMutex _l(mInstanceLock);
+    if (mInstance == NULL) {
+        mInstance = new SignalHandler();
+    }
+    return mInstance;
+}
+
+void SignalHandler::sigAction(int signum, siginfo_t* info, void*)
+{
+    static const char wakeupMsg[1] = { 0xff };
+
+    // If our signal handler is being called, then we know we have
+    // already initialized the SignalHandler class and thus mInstance
+    // is valid.
+    SignalHandler* const self = mInstance;
+
+    // XXX This is not safe!
+    #if 0
+    LOGV("Signal %d: signo=%d, errno=%d, code=%d, pid=%d\n",
+           signum,
+           info->si_signo, info->si_errno, info->si_code,
+           info->si_pid);
+    #endif
+
+    int32_t oldTop, newTop;
+
+    // Find the next command slot...
+    do {
+        oldTop = self->mCommandTop;
+
+        newTop = oldTop + 1;
+        if (newTop >= COMMAND_QUEUE_SIZE) {
+            newTop = 0;
+        }
+
+        if (newTop == self->mCommandBottom) {
+            // The buffer is filled up!  Ouch!
+            // XXX This is not safe!
+            #if 0
+            LOGE("Command buffer overflow!  newTop=%d\n", newTop);
+            #endif
+            android_atomic_add(1, &self->mLostCommands);
+            write(self->mAvailMsg[1], wakeupMsg, sizeof(wakeupMsg));
+            return;
+        }
+    } while(android_atomic_cmpxchg(oldTop, newTop, &(self->mCommandTop)));
+
+    // Fill in the command data...
+    self->mCommands[oldTop].signum = signum;
+    self->mCommands[oldTop].info = *info;
+
+    // And now make this command available.
+    self->mCommands[oldTop].filled = 1;
+
+    // Wake up the processing thread.
+    write(self->mAvailMsg[1], wakeupMsg, sizeof(wakeupMsg));
+}
+
+}; // namespace android
+
diff --git a/cmds/runtime/SignalHandler.h b/cmds/runtime/SignalHandler.h
new file mode 100644
index 0000000..7f4ef8e
--- /dev/null
+++ b/cmds/runtime/SignalHandler.h
@@ -0,0 +1,137 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+#ifndef ANDROID_SIGNAL_HANDLER_H
+#define ANDROID_SIGNAL_HANDLER_H
+
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+#include <signal.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+enum {
+    DEFAULT_PROCESS_TAG = 1
+};
+
+class SignalHandler
+{
+public:
+    typedef void (*child_callback_t)(pid_t child, void* userData);
+
+    /**
+     * Set a handler for when a child process exits.  By calling
+     * this, a waitpid() will be done when the child exits to remove
+     * it from the zombie state.  You can also optionally specify a
+     * handler to be called when the child exits.
+     * 
+     * If there is already a handler for this child process, it is
+     * replaced by this new handler.  In this case the old handler's
+     * function is not called.
+     * 
+     * @param childPid Process ID of child to watch.
+     * @param childTag User-defined tag for this child.  Must be
+     *                 greater than zero.
+     * @param handler If non-NULL, this will be called when the
+     *                child exits.  It may be called in either a
+     *                separate signal handling thread, or
+     *                immediately if the child has already exited.
+     * @param userData Propageted as-is to handler.
+     * 
+     * @return status_t NO_ERROR if all is well.
+     */
+    static status_t             setChildHandler(pid_t childPid,
+                                                int childTag = DEFAULT_PROCESS_TAG,
+                                                child_callback_t handler = NULL,
+                                                void* userData = NULL);
+
+    /**
+     * Kill all of the child processes for which we have a waiting
+     * handler, whose tag is the given value.  If tag is 0, all
+     * children are killed.
+     * 
+     * @param tag
+     */
+    static void                 killAllChildren(int tag = 0);
+
+private:
+                                SignalHandler();
+                                ~SignalHandler();
+
+    static SignalHandler*       getInstance();
+
+    static void                 sigAction(int, siginfo_t*, void*);
+
+    // --------------------------------------------------
+    // Shared state...  all of this is protected by mLock.
+    // --------------------------------------------------
+
+    mutable Mutex                       mLock;
+
+    struct ChildHandler
+    {
+        pid_t childPid;
+        int tag;
+        child_callback_t handler;
+        void* userData;
+    };
+    KeyedVector<pid_t, ChildHandler>    mChildHandlers;
+
+    // --------------------------------------------------
+    // Commmand queue...  data is inserted by the signal
+    // handler using atomic ops, and retrieved by the
+    // signal processing thread.  Because these are touched
+    // by the signal handler, no lock is used.
+    // --------------------------------------------------
+
+    enum {
+        COMMAND_QUEUE_SIZE = 64
+    };
+    struct CommandEntry
+    {
+        int filled;
+        int signum;
+        siginfo_t info;
+    };
+
+    // The top of the queue.  This is incremented atomically by the
+    // signal handler before placing a command in the queue.
+    volatile int32_t                    mCommandTop;
+
+    // The bottom of the queue.  Only modified by the processing
+    // thread; the signal handler reads it only to determine if the
+    // queue is full.
+    int32_t                             mCommandBottom;
+
+    // Incremented each time we receive a signal and don't have room
+    // for it on the command queue.
+    volatile int32_t                    mLostCommands;
+
+    // The command processing thread.
+    class ProcessThread;
+    sp<Thread>                          mProcessThread;
+
+    // Pipe used to tell command processing thread when new commands.
+    // are available.  The thread blocks on the read end, the signal
+    // handler writes when it enqueues new commands.
+    int                                 mAvailMsg[2];
+
+    // The commands.
+    CommandEntry                        mCommands[COMMAND_QUEUE_SIZE];
+
+    // --------------------------------------------------
+    // Singleton.
+    // --------------------------------------------------
+
+    static Mutex                        mInstanceLock;
+    static SignalHandler*               mInstance;
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_SIGNAL_HANDLER_H
diff --git a/cmds/runtime/main_runtime.cpp b/cmds/runtime/main_runtime.cpp
new file mode 100644
index 0000000..1531a9e
--- /dev/null
+++ b/cmds/runtime/main_runtime.cpp
@@ -0,0 +1,514 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+// Main entry point for runtime.
+//
+
+#include "ServiceManager.h"
+#include "SignalHandler.h"
+
+#include <utils.h>
+#include <utils/IPCThreadState.h>
+#include <utils/ProcessState.h>
+#include <utils/Log.h>  
+#include <cutils/zygote.h>
+
+#include <cutils/properties.h>
+
+#include <private/utils/Static.h>
+
+#include <ui/ISurfaceComposer.h>
+
+#include <android_runtime/AndroidRuntime.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <linux/capability.h>
+#include <linux/ioctl.h>
+#ifdef HAVE_ANDROID_OS
+# include <linux/android_alarm.h>
+#endif
+
+#undef LOG_TAG
+#define LOG_TAG "runtime"
+
+static const char* ZYGOTE_ARGV[] = { 
+    "--setuid=1000",
+    "--setgid=1000",
+    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
+    /* CAP_SYS_TTY_CONFIG & CAP_SYS_RESOURCE & CAP_NET_BROADCAST &
+     * CAP_NET_ADMIN & CAP_NET_RAW & CAP_NET_BIND_SERVICE  & CAP_KILL &
+     * CAP_SYS_BOOT
+     */
+    "--capabilities=88161312,88161312",
+    "--runtime-init",
+    "--nice-name=system_server",
+    "com.android.server.SystemServer"
+};
+
+using namespace android;
+
+extern "C" status_t system_init();
+
+enum {
+    SYSTEM_PROCESS_TAG = DEFAULT_PROCESS_TAG+1
+};
+
+extern Mutex gEventQMutex;
+extern Condition gEventQCondition;
+
+namespace android {
+
+extern status_t app_init(const char* className);
+extern void set_finish_init_func(void (*func)());
+
+
+/**
+ * This class is used to kill this process (runtime) when the system_server dies.
+ */
+class GrimReaper : public IBinder::DeathRecipient {
+public: 
+    GrimReaper() { }
+
+    virtual void binderDied(const wp<IBinder>& who)
+    {
+        LOGI("Grim Reaper killing runtime...");
+        kill(getpid(), SIGKILL);
+    }
+};
+
+extern void QuickTests();
+
+/*
+ * Print usage info.
+ */
+static void usage(const char* argv0)
+{
+    fprintf(stderr,
+        "Usage: runtime [-g gamma] [-l logfile] [-n] [-s]\n"
+        "               [-j app-component] [-v app-verb] [-d app-data]\n"
+        "\n"
+        "-l: File to send log messages to\n"
+        "-n: Don't print to stdout/stderr\n"
+        "-s: Force single-process mode\n"
+        "-j: Custom home app component name\n"
+        "-v: Custom home app intent verb\n"
+        "-d: Custom home app intent data\n"
+    );
+    exit(1);
+}
+
+// Selected application to run.
+static const char* gInitialApplication = NULL;
+static const char* gInitialVerb = NULL;
+static const char* gInitialData = NULL;
+
+static void writeStringToParcel(Parcel& parcel, const char* str)
+{
+    if (str) {
+        parcel.writeString16(String16(str));
+    } else {
+        parcel.writeString16(NULL, 0);
+    }
+}
+
+/*
+ * Starting point for program logic.
+ *
+ * Returns with an exit status code (0 on success, nonzero on error).
+ */
+static int run(sp<ProcessState>& proc)
+{
+    // Temporary hack to call startRunning() on the activity manager.
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> am;
+    while ((am = sm->getService(String16("activity"))) == NULL) {
+        LOGI("Waiting for activity manager...");
+    }
+    Parcel data, reply;
+    // XXX Need to also supply a package name for this to work again.
+    // IActivityManager::getInterfaceDescriptor() is the token for invoking on this interface;
+    // hardcoding it here avoids having to link with the full Activity Manager library
+    data.writeInterfaceToken(String16("android.app.IActivityManager"));
+    writeStringToParcel(data, NULL);
+    writeStringToParcel(data, gInitialApplication);
+    writeStringToParcel(data, gInitialVerb);
+    writeStringToParcel(data, gInitialData);
+LOGI("run() sending FIRST_CALL_TRANSACTION to activity manager");
+    am->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply);
+
+    if (proc->supportsProcesses()) {
+        // Now we link to the Activity Manager waiting for it to die. If it does kill ourself.
+        // initd will restart this process and bring the system back up.
+        sp<GrimReaper> grim = new GrimReaper();
+        am->linkToDeath(grim, grim.get(), 0);
+
+        // Now join the thread pool. Note this is needed so that the message enqueued in the driver
+        // for the linkToDeath gets processed.
+        IPCThreadState::self()->joinThreadPool();
+    } else {
+        // Keep this thread running forever...
+        while (1) {
+            usleep(100000);
+        }
+    }
+    return 1;
+}
+
+
+};  // namespace android
+
+
+/*
+ * Post-system-process initialization.
+ * 
+ * This function continues initialization after the system process
+ * has been initialized.  It needs to be separate because the system
+ * initialization needs to care of starting the Android runtime if it is not
+ * running in its own process, which doesn't return until the runtime is
+ * being shut down.  So it will call back to here from inside of Dalvik,
+ * to allow us to continue booting up.
+ */
+static void finish_system_init(sp<ProcessState>& proc)
+{
+    // If we are running multiprocess, we now need to have the
+    // thread pool started here.  We don't do this in boot_init()
+    // because when running single process we need to start the
+    // thread pool after the Android runtime has been started (so
+    // the pool uses Dalvik threads).
+    if (proc->supportsProcesses()) {
+        proc->startThreadPool();
+    }
+}
+
+
+// This function can be used to enforce security to different
+// root contexts.  For now, we just give every access.
+static bool contextChecker(
+    const String16& name, const sp<IBinder>& caller, void* userData)
+{
+    return true;
+}
+
+/*
+ * Initialization of boot services.
+ *
+ * This is where we perform initialization of all of our low-level
+ * boot services.  Most importantly, here we become the context
+ * manager and use that to publish the service manager that will provide
+ * access to all other services.
+ */
+static void boot_init()
+{
+    LOGI("Entered boot_init()!\n");
+    
+    sp<ProcessState> proc(ProcessState::self());
+    LOGD("ProcessState: %p\n", proc.get());
+    proc->becomeContextManager(contextChecker, NULL);
+    
+    if (proc->supportsProcesses()) {
+        LOGI("Binder driver opened.  Multiprocess enabled.\n");
+    } else {
+        LOGI("Binder driver not found.  Processes not supported.\n");
+    }
+    
+    sp<BServiceManager> sm = new BServiceManager;
+    proc->setContextObject(sm);
+}
+
+/*
+ * Redirect stdin/stdout/stderr to /dev/null.
+ */
+static void redirectStdFds(void)
+{
+    int fd = open("/dev/null", O_RDWR, 0);
+    if (fd < 0) {
+        LOGW("Unable to open /dev/null: %s\n", strerror(errno));
+    } else {
+        dup2(fd, 0);
+        dup2(fd, 1);
+        dup2(fd, 2);
+        close(fd);
+    }
+}
+
+static int hasDir(const char* dir)
+{
+    struct stat s;
+    int res = stat(dir, &s);
+    if (res == 0) {
+        return S_ISDIR(s.st_mode);
+    }
+    return 0;
+}
+
+static void validateTime()
+{
+#if HAVE_ANDROID_OS
+    int fd;
+    int res;
+    time_t min_time = 1167652800; // jan 1 2007, type 'date -ud "1/1 12:00" +%s' to get value for current year
+    struct timespec ts;
+    
+    fd = open("/dev/alarm", O_RDWR);
+    if(fd < 0) {
+        LOGW("Unable to open alarm driver: %s\n", strerror(errno));
+        return;
+    }
+    res = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &ts);
+    if(res < 0) {
+        LOGW("Unable to read rtc, %s\n", strerror(errno));
+    }
+    else if(ts.tv_sec >= min_time) {
+        goto done;
+    }
+    LOGW("Invalid time detected, %ld set to %ld\n", ts.tv_sec, min_time);
+    ts.tv_sec = min_time;
+    ts.tv_nsec = 0;
+    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
+    if(res < 0) {
+        LOGW("Unable to set rtc to %ld: %s\n", ts.tv_sec, strerror(errno));
+    }
+done:
+    close(fd);
+#endif
+}
+
+#ifndef HAVE_ANDROID_OS
+class QuickRuntime : public AndroidRuntime
+{
+public:
+    QuickRuntime() {}
+
+    virtual void onStarted()
+    {
+        printf("QuickRuntime: onStarted\n");
+    }
+};
+#endif
+
+static status_t start_process(const char* name);
+
+static void restart_me(pid_t child, void* userData)
+{
+    start_process((const char*)userData);
+}
+
+static status_t start_process(const char* name)
+{
+    String8 path(name);
+    Vector<const char*> args;
+    String8 leaf(path.getPathLeaf());
+    String8 parentDir(path.getPathDir());
+    args.insertAt(leaf.string(), 0);
+    args.add(parentDir.string());
+    args.add(NULL);
+    pid_t child = fork();
+    if (child < 0) {
+        status_t err = errno;
+        LOGE("*** fork of child %s failed: %s", leaf.string(), strerror(err));
+        return -errno;
+    } else if (child == 0) {
+        LOGI("Executing: %s", path.string());
+        execv(path.string(), const_cast<char**>(args.array()));
+        int err = errno;
+        LOGE("Exec failed: %s\n", strerror(err));
+        _exit(err);
+    } else {
+        SignalHandler::setChildHandler(child, DEFAULT_PROCESS_TAG,
+                restart_me, (void*)name);
+    }
+    return -errno;
+}
+
+/*
+ * Application entry point.
+ *
+ * Parse arguments, set some values, and pass control off to Run().
+ *
+ * This is redefined to "SDL_main" on SDL simulator builds, and
+ * "runtime_main" on wxWidgets builds.
+ */
+extern "C"
+int main(int argc, char* const argv[])
+{
+    bool singleProcess = false;
+    const char* logFile = NULL;
+    int ic;
+    int result = 1;
+    pid_t systemPid;
+    
+    sp<ProcessState> proc;
+
+#ifndef HAVE_ANDROID_OS
+    /* Set stdout/stderr to unbuffered for MinGW/MSYS. */
+    //setvbuf(stdout, NULL, _IONBF, 0);
+    //setvbuf(stderr, NULL, _IONBF, 0);
+    
+    LOGI("commandline args:\n");
+    for (int i = 0; i < argc; i++)
+        LOGI("  %2d: '%s'\n", i, argv[i]);
+#endif
+
+    while (1) {
+        ic = getopt(argc, argv, "g:j:v:d:l:ns");
+        if (ic < 0)
+            break;
+
+        switch (ic) {
+        case 'g':
+            break;
+        case 'j':
+            gInitialApplication = optarg;
+            break;
+        case 'v':
+            gInitialVerb = optarg;
+            break;
+        case 'd':
+            gInitialData = optarg;
+            break;
+        case 'l':
+            logFile = optarg;
+            break;
+        case 'n':
+            redirectStdFds();
+            break;
+        case 's':
+            singleProcess = true;
+            break;
+        case '?':
+        default:
+            LOGE("runtime: unrecognized flag -%c\n", ic);
+            usage(argv[0]);
+            break;
+        }
+    }
+    if (optind < argc) {
+        LOGE("runtime: extra stuff: %s\n", argv[optind]);
+        usage(argv[0]);
+    }
+
+    if (singleProcess) {
+        ProcessState::setSingleProcess(true);
+    }
+
+    if (logFile != NULL) {
+        android_logToFile(NULL, logFile);
+    }
+
+    /*
+     * Set up ANDROID_* environment variables.
+     *
+     * TODO: the use of $ANDROID_PRODUCT_OUT will go away soon.
+     */
+    static const char* kSystemDir = "/system";
+    static const char* kDataDir = "/data";
+    static const char* kAppSubdir = "/app";
+    const char* out = NULL;
+#ifndef HAVE_ANDROID_OS
+    //out = getenv("ANDROID_PRODUCT_OUT");
+#endif
+    if (out == NULL)
+        out = "";
+
+    char* systemDir = (char*) malloc(strlen(out) + strlen(kSystemDir) +1);
+    char* dataDir = (char*) malloc(strlen(out) + strlen(kDataDir) +1);
+
+    sprintf(systemDir, "%s%s", out, kSystemDir);
+    sprintf(dataDir, "%s%s", out, kDataDir);
+    setenv("ANDROID_ROOT", systemDir, 1);
+    setenv("ANDROID_DATA", dataDir, 1);
+
+    char* assetDir = (char*) malloc(strlen(systemDir) + strlen(kAppSubdir) +1);
+    sprintf(assetDir, "%s%s", systemDir, kAppSubdir);
+
+    LOGI("Startup: sys='%s' asset='%s' data='%s'\n",
+        systemDir, assetDir, dataDir);
+    free(systemDir);
+    free(dataDir);
+
+#ifdef HAVE_ANDROID_OS
+    /* set up a process group for easier killing on the device */
+    setpgid(0, getpid());
+#endif
+
+    // Change to asset dir.  This is only necessary if we've changed to
+    // a different directory, but there's little harm in doing it regardless.
+    //
+    // Expecting assets to live in the current dir is not a great idea,
+    // because some of our code or one of our libraries could change the
+    // directory out from under us.  Preserve the behavior for now.
+    if (chdir(assetDir) != 0) {
+        LOGW("WARNING: could not change dir to '%s': %s\n",
+             assetDir, strerror(errno));
+    }
+    free(assetDir);
+
+#if 0
+    // Hack to keep libc from beating the filesystem to death.  It's
+    // hitting /etc/localtime frequently, 
+    //
+    // This statement locks us into Pacific time.  We could do better,
+    // but there's not much point until we're sure that the library
+    // can't be changed to do more along the lines of what we want.
+#ifndef XP_WIN
+    setenv("TZ", "PST+8PDT,M4.1.0/2,M10.5.0/2", true);
+#endif
+#endif
+
+    /* track our progress through the boot sequence */
+    const int LOG_BOOT_PROGRESS_START = 3000;
+    LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, 
+        ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
+
+    validateTime();
+
+    proc = ProcessState::self();
+    
+    boot_init();
+    
+    /* If we are in multiprocess mode, have zygote spawn the system
+     * server process and call system_init(). If we are running in
+     * single process mode just call system_init() directly.
+     */
+    if (proc->supportsProcesses()) {
+        // If stdio logging is on, system_server should not inherit our stdio
+        // The dalvikvm instance will copy stdio to the log on its own
+        char propBuf[PROPERTY_VALUE_MAX];
+        bool logStdio = false;
+        property_get("log.redirect-stdio", propBuf, "");
+        logStdio = (strcmp(propBuf, "true") == 0);
+
+        zygote_run_oneshot((int)(!logStdio), 
+                sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]), 
+                ZYGOTE_ARGV);
+
+        //start_process("/system/bin/mediaserver");
+
+    } else {
+#ifndef HAVE_ANDROID_OS
+        QuickRuntime* runt = new QuickRuntime();
+        runt->start("com/android/server/SystemServer", 
+                    false /* spontaneously fork system server from zygote */);
+#endif
+    }
+
+    //printf("+++ post-zygote\n");
+
+    finish_system_init(proc);
+    run(proc);
+    
+bail:
+    if (proc != NULL) {
+        proc->setContextObject(NULL);
+    }
+    
+    return 0;
+}
diff --git a/cmds/surfaceflinger/Android.mk b/cmds/surfaceflinger/Android.mk
new file mode 100644
index 0000000..37c3d94
--- /dev/null
+++ b/cmds/surfaceflinger/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	main_surfaceflinger.cpp 
+
+LOCAL_SHARED_LIBRARIES := \
+	libsurfaceflinger \
+	libutils
+
+LOCAL_C_INCLUDES := \
+	$(LOCAL_PATH)/../../libs/surfaceflinger
+
+LOCAL_MODULE:= surfaceflinger
+
+include $(BUILD_EXECUTABLE)
diff --git a/cmds/surfaceflinger/main_surfaceflinger.cpp b/cmds/surfaceflinger/main_surfaceflinger.cpp
new file mode 100644
index 0000000..7c89578
--- /dev/null
+++ b/cmds/surfaceflinger/main_surfaceflinger.cpp
@@ -0,0 +1,18 @@
+#include <utils/IPCThreadState.h>
+#include <utils/ProcessState.h>
+#include <utils/IServiceManager.h>
+#include <utils/Log.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();
+}
diff --git a/include/GLES/egl.h b/include/GLES/egl.h
new file mode 100644
index 0000000..08834ab
--- /dev/null
+++ b/include/GLES/egl.h
@@ -0,0 +1,268 @@
+/*
+ * 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_EGL_H
+#define ANDROID_EGL_H
+
+#include <GLES/gl.h>
+#include <GLES/egltypes.h>
+#include <GLES/eglnatives.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EGL_VERSION_1_0         1
+#define EGL_VERSION_1_1         1
+#define EGL_VERSION_1_2         1
+
+#define EGL_FALSE               0
+#define EGL_TRUE                1
+
+/* Errors */
+#define EGL_SUCCESS                     0x3000
+#define EGL_NOT_INITIALIZED             0x3001
+#define EGL_BAD_ACCESS                  0x3002
+#define EGL_BAD_ALLOC                   0x3003
+#define EGL_BAD_ATTRIBUTE               0x3004
+#define EGL_BAD_CONFIG                  0x3005
+#define EGL_BAD_CONTEXT                 0x3006
+#define EGL_BAD_CURRENT_SURFACE         0x3007
+#define EGL_BAD_DISPLAY                 0x3008
+#define EGL_BAD_MATCH                   0x3009
+#define EGL_BAD_NATIVE_PIXMAP           0x300A
+#define EGL_BAD_NATIVE_WINDOW           0x300B
+#define EGL_BAD_PARAMETER               0x300C
+#define EGL_BAD_SURFACE                 0x300D
+#define EGL_CONTEXT_LOST                0x300E
+
+/* Config attributes */
+#define EGL_BUFFER_SIZE                 0x3020
+#define EGL_ALPHA_SIZE                  0x3021
+#define EGL_BLUE_SIZE                   0x3022
+#define EGL_GREEN_SIZE                  0x3023
+#define EGL_RED_SIZE                    0x3024
+#define EGL_DEPTH_SIZE                  0x3025
+#define EGL_STENCIL_SIZE                0x3026
+#define EGL_CONFIG_CAVEAT               0x3027
+#define EGL_CONFIG_ID                   0x3028
+#define EGL_LEVEL                       0x3029
+#define EGL_MAX_PBUFFER_HEIGHT          0x302A
+#define EGL_MAX_PBUFFER_PIXELS          0x302B
+#define EGL_MAX_PBUFFER_WIDTH           0x302C
+#define EGL_NATIVE_RENDERABLE           0x302D
+#define EGL_NATIVE_VISUAL_ID            0x302E
+#define EGL_NATIVE_VISUAL_TYPE          0x302F
+#define EGL_SAMPLES                     0x3031
+#define EGL_SAMPLE_BUFFERS              0x3032
+#define EGL_SURFACE_TYPE                0x3033
+#define EGL_TRANSPARENT_TYPE            0x3034
+#define EGL_TRANSPARENT_BLUE_VALUE      0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE     0x3036
+#define EGL_TRANSPARENT_RED_VALUE       0x3037
+#define EGL_NONE                        0x3038
+#define EGL_BIND_TO_TEXTURE_RGB         0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA        0x303A
+#define EGL_MIN_SWAP_INTERVAL           0x303B
+#define EGL_MAX_SWAP_INTERVAL           0x303C
+#define EGL_LUMINANCE_SIZE              0x303D
+#define EGL_ALPHA_MASK_SIZE             0x303E
+#define EGL_COLOR_BUFFER_TYPE           0x303F
+#define EGL_RENDERABLE_TYPE             0x3040
+
+/* Config values */
+#define EGL_DONT_CARE                   ((EGLint)-1)
+
+#define EGL_SLOW_CONFIG                 0x3050
+#define EGL_NON_CONFORMANT_CONFIG       0x3051
+#define EGL_TRANSPARENT_RGB             0x3052
+#define EGL_NO_TEXTURE                  0x305C
+#define EGL_TEXTURE_RGB                 0x305D
+#define EGL_TEXTURE_RGBA                0x305E
+#define EGL_TEXTURE_2D                  0x305F
+#define EGL_RGB_BUFFER                  0x308E
+#define EGL_LUMINANCE_BUFFER            0x308F
+
+/* Config attribute mask bits */
+#define EGL_PBUFFER_BIT                 0x01
+#define EGL_PIXMAP_BIT                  0x02
+#define EGL_WINDOW_BIT                  0x04
+#define EGL_OPENGL_ES_BIT               0x01
+#define EGL_OPENVG_BIT                  0x02
+
+/* String names */
+#define EGL_VENDOR                      0x3053
+#define EGL_VERSION                     0x3054
+#define EGL_EXTENSIONS                  0x3055
+#define EGL_CLIENT_APIS                 0x308D
+
+/* Surface attributes */
+#define EGL_HEIGHT                      0x3056
+#define EGL_WIDTH                       0x3057
+#define EGL_LARGEST_PBUFFER             0x3058
+#define EGL_TEXTURE_FORMAT              0x3080
+#define EGL_TEXTURE_TARGET              0x3081
+#define EGL_MIPMAP_TEXTURE              0x3082
+#define EGL_MIPMAP_LEVEL                0x3083
+#define EGL_RENDER_BUFFER               0x3086
+#define EGL_COLORSPACE                  0x3087
+#define EGL_ALPHA_FORMAT                0x3088
+#define EGL_HORIZONTAL_RESOLUTION       0x3090
+#define EGL_VERTICAL_RESOLUTION         0x3091
+#define EGL_PIXEL_ASPECT_RATIO          0x3092
+#define EGL_SWAP_BEHAVIOR               0x3093
+
+#define EGL_BACK_BUFFER                 0x3084
+#define EGL_SINGLE_BUFFER               0x3085
+
+#define EGL_DISPLAY_SCALING             10000
+
+#define EGL_UNKNOWN                     ((EGLint)-1)
+
+/* Back buffer swap behaviors */
+#define EGL_BUFFER_PRESERVED            0x3094
+#define EGL_BUFFER_DESTROYED            0x3095
+
+/* CreatePbufferFromClientBuffer buffer types */
+#define EGL_OPENVG_IMAGE                0x3096
+
+/* QueryContext targets */
+#define EGL_CONTEXT_CLIENT_TYPE         0x3097
+
+/* BindAPI/QueryAPI targets */
+#define EGL_OPENGL_ES_API               0x30A0
+#define EGL_OPENVG_API                  0x30A1
+
+/* WaitNative engines */
+#define EGL_CORE_NATIVE_ENGINE          0x305B
+
+/* Current surfaces */
+#define EGL_DRAW                        0x3059
+#define EGL_READ                        0x305A
+
+
+EGLDisplay eglGetDisplay(NativeDisplayType display);
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLBoolean eglTerminate(EGLDisplay dpy);
+
+EGLBoolean eglGetConfigs(   EGLDisplay dpy,
+                            EGLConfig *configs,
+                            EGLint config_size, EGLint *num_config);
+
+EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
+                            EGLConfig *configs, EGLint config_size,
+                            EGLint *num_config);
+
+EGLBoolean eglGetConfigAttrib(  EGLDisplay dpy, EGLConfig config,
+                                EGLint attribute, EGLint *value);
+
+EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
+                                    NativeWindowType window,
+                                    const EGLint *attrib_list);
+
+EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
+                                    NativePixmapType pixmap,
+                                    const EGLint *attrib_list);
+
+EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
+                                    const EGLint *attrib_list);
+                                    
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
+
+EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
+                            EGLint attribute, EGLint *value);
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
+                            EGLContext share_list, const EGLint *attrib_list);
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
+
+EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
+                            EGLSurface read, EGLContext ctx);
+
+EGLContext eglGetCurrentContext(void);
+EGLSurface eglGetCurrentSurface(EGLint readdraw);
+EGLDisplay eglGetCurrentDisplay(void);
+EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
+                            EGLint attribute, EGLint *value);
+
+EGLBoolean eglWaitGL(void);
+EGLBoolean eglWaitNative(EGLint engine);
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw);
+EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
+                            NativePixmapType target);
+
+EGLint eglGetError(void);
+const char* eglQueryString(EGLDisplay dpy, EGLint name);
+void (*eglGetProcAddress (const char *procname))();
+
+/* ----------------------------------------------------------------------------
+ * EGL 1.1
+ * ----------------------------------------------------------------------------
+ */
+
+EGLBoolean eglSurfaceAttrib(
+        EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+EGLBoolean eglBindTexImage(
+        EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLBoolean eglReleaseTexImage(
+        EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval);
+
+/* ----------------------------------------------------------------------------
+ * EGL 1.2
+ * ----------------------------------------------------------------------------
+ */
+
+EGLBoolean eglBindAPI(EGLenum api);
+EGLenum eglQueryAPI(void);
+EGLBoolean eglWaitClient(void);
+EGLBoolean eglReleaseThread(void);
+EGLSurface eglCreatePbufferFromClientBuffer(
+          EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
+          EGLConfig config, const EGLint *attrib_list);
+
+/* ----------------------------------------------------------------------------
+ * Android extentions
+ * ----------------------------------------------------------------------------
+ */
+
+EGLBoolean eglSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
+        EGLint l, EGLint t, EGLint w, EGLint h);
+
+EGLBoolean eglCopyFrontToBackANDROID(EGLDisplay dpy,
+        EGLSurface surface,
+        EGLint l, EGLint t, EGLint w, EGLint h);
+
+const char* eglQueryStringConfigANDROID(
+        EGLDisplay dpy, EGLConfig config, EGLint name);
+
+void* eglGetRenderBufferAddressANDROID(EGLDisplay dpy, EGLSurface surface);
+
+EGLBoolean eglCopyBitsANDROID(EGLDisplay dpy,
+        NativeWindowType draw, EGLint x, EGLint y,
+        NativeWindowType read,
+        EGLint crop_x, EGLint crop_y, EGLint crop_w, EGLint crop_h,
+        EGLint flags);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /*ANDROID_EGL_H*/
diff --git a/include/GLES/eglnatives.h b/include/GLES/eglnatives.h
new file mode 100644
index 0000000..f9e544c
--- /dev/null
+++ b/include/GLES/eglnatives.h
@@ -0,0 +1,276 @@
+/*
+ * 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_EGLNATIVES_H
+#define ANDROID_EGLNATIVES_H
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*****************************************************************************/
+
+struct egl_native_window_t;
+struct egl_native_pixmap_t;
+
+
+typedef struct egl_native_window_t*     NativeWindowType;
+typedef struct egl_native_pixmap_t*     NativePixmapType;
+typedef void*                           NativeDisplayType;
+
+/* 
+ * This a conveniance function to create a NativeWindowType surface
+ * that maps to the whole screen
+ * This function is actually implemented in libui.so
+ */
+
+NativeWindowType android_createDisplaySurface();
+
+/* flags returned from swapBuffer */
+#define EGL_NATIVES_FLAG_SIZE_CHANGED       0x00000001
+
+/* surface flags */
+#define EGL_NATIVES_FLAG_DESTROY_BACKBUFFER 0x00000001
+
+enum native_pixel_format_t
+{
+    NATIVE_PIXEL_FORMAT_RGBA_8888   = 1,
+    NATIVE_PIXEL_FORMAT_RGB_565     = 4,
+    NATIVE_PIXEL_FORMAT_RGBA_5551   = 6,
+    NATIVE_PIXEL_FORMAT_RGBA_4444   = 7,
+    NATIVE_PIXEL_FORMAT_YCbCr_422_SP= 0x10,
+    NATIVE_PIXEL_FORMAT_YCbCr_420_SP= 0x11,
+};
+
+enum native_memory_type_t
+{
+    NATIVE_MEMORY_TYPE_PMEM         = 0,
+    NATIVE_MEMORY_TYPE_GPU          = 1,
+    NATIVE_MEMORY_TYPE_FB           = 2,
+    NATIVE_MEMORY_TYPE_HEAP         = 128
+};
+
+
+struct egl_native_window_t
+{
+    /*
+     * magic must be set to 0x600913
+     */
+    uint32_t    magic;
+    
+    /*
+     * must be sizeof(egl_native_window_t)
+     */
+    uint32_t    version;
+
+    /*
+     * ident is reserved for the Android platform
+     */
+    uint32_t    ident;
+    
+    /*
+     * width, height and stride of the window in pixels
+     * Any of these value can be nul in which case GL commands are
+     * accepted and processed as usual, but not rendering occurs.
+     */
+    int         width;      // w=h=0 is legal
+    int         height;
+    int         stride;
+
+    /*
+     * format of the native window (see ui/PixelFormat.h)
+     */
+    int         format;
+    
+    /*
+     * Offset of the bits in the VRAM
+     */
+    intptr_t    offset;
+    
+    /*
+     * flags describing some attributes of this surface
+     * EGL_NATIVES_FLAG_DESTROY_BACKBUFFER: backbuffer not preserved after 
+     * eglSwapBuffers
+     */
+    uint32_t    flags;
+    
+    /*
+     * horizontal and vertical resolution in DPI
+     */
+    float       xdpi;
+    float       ydpi;
+    
+    /*
+     * refresh rate in frames per second (Hz)
+     */
+    float       fps;
+    
+    
+    /*
+     *  Base memory virtual address of the surface in the CPU side
+     */
+    intptr_t    base;
+    
+    /*
+     *  Heap the offset above is based from
+     */
+    int         fd;
+    
+    /*
+     *  Memory type the surface resides into
+     */
+    uint8_t     memory_type;
+    
+    /*
+     * Reserved for future use. MUST BE ZERO.
+     */
+    uint8_t     reserved_pad[3];
+    int         reserved[8];
+    
+    /*
+     * Vertical stride (only relevant with planar formats) 
+     */
+    
+    int         vstride;
+
+    /*
+     * Hook called by EGL to hold a reference on this structure
+     */
+    void        (*incRef)(NativeWindowType window);
+
+    /*
+     * Hook called by EGL to release a reference on this structure
+     */
+    void        (*decRef)(NativeWindowType window);
+
+    /*
+     * Hook called by EGL to perform a page flip. This function
+     * may update the size attributes above, in which case it returns
+     * the EGL_NATIVES_FLAG_SIZE_CHANGED bit set.
+     */
+    uint32_t    (*swapBuffers)(NativeWindowType window);
+    
+    /*
+     * Hook called by EGL to set the swap rectangle. this hook can be 
+     * null (operation not supported) 
+     */
+    void        (*setSwapRectangle)(NativeWindowType window, int l, int t, int w, int h);
+
+    /*
+     * Reserved for future use. MUST BE ZERO.
+     */
+    void        (*reserved_proc_0)(void);
+    
+    
+    /*
+     * Hook called by EGL to retrieve the next buffer to render into. 
+     * This call updates this structure.
+     */
+    uint32_t    (*nextBuffer)(NativeWindowType window);
+
+    /*
+     * Hook called by EGL when the native surface is associated to EGL
+     * (eglCreateWindowSurface). Can be NULL.
+     */
+    void        (*connect)(NativeWindowType window);
+
+    /*
+     * Hook called by EGL when eglDestroySurface is called.  Can be NULL.
+     */
+    void        (*disconnect)(NativeWindowType window);
+    
+    /*
+     * Reserved for future use. MUST BE ZERO.
+     */
+    void        (*reserved_proc[11])(void);
+    
+    /*
+     *  Some storage reserved for the oem driver.
+     */
+    intptr_t    oem[4];
+};
+
+
+struct egl_native_pixmap_t
+{
+    int32_t     version;    /* must be 32 */
+    int32_t     width;
+    int32_t     height;
+    int32_t     stride;
+    uint8_t*    data;
+    uint8_t     format;
+    uint8_t     rfu[3];
+    union {
+        uint32_t    compressedFormat;
+        int32_t     vstride;
+    };
+    int32_t     reserved;
+};
+
+/*****************************************************************************/
+
+/*
+ * OEM's egl's library (libhgl.so) must imlement these hooks to allocate
+ * the GPU memory they need  
+ */
+
+
+typedef struct
+{
+    // for internal use
+    void*   user;
+    // virtual address of this area
+    void*   base;
+    // size of this area in bytes
+    size_t  size;
+    // physical address of this area
+    void*   phys;
+    // offset in this area available to the GPU
+    size_t  offset;
+    // fd of this area
+    int     fd;
+} gpu_area_t;
+
+typedef struct
+{
+    // area where GPU registers are mapped
+    gpu_area_t regs;
+    // number of extra areas (currently limited to 2)
+    int32_t count;
+    // extra GPU areas (currently limited to 2)
+    gpu_area_t gpu[2];
+} request_gpu_t;
+
+
+typedef request_gpu_t* (*OEM_EGL_acquire_gpu_t)(void* user);
+typedef int (*OEM_EGL_release_gpu_t)(void* user, request_gpu_t* handle);
+typedef void (*register_gpu_t)
+        (void* user, OEM_EGL_acquire_gpu_t, OEM_EGL_release_gpu_t);
+
+void oem_register_gpu(
+        void* user,
+        OEM_EGL_acquire_gpu_t acquire,
+        OEM_EGL_release_gpu_t release);
+
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ANDROID_EGLNATIVES_H */
diff --git a/include/GLES/egltypes.h b/include/GLES/egltypes.h
new file mode 100644
index 0000000..698239b
--- /dev/null
+++ b/include/GLES/egltypes.h
@@ -0,0 +1,47 @@
+/*
+ * 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_EGL_TYPES_H
+#define ANDROID_EGL_TYPES_H
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned int EGLBoolean;
+typedef int32_t EGLint;
+typedef int EGLenum;
+typedef void *EGLDisplay;
+typedef void *EGLConfig;
+typedef void *EGLSurface;
+typedef void *EGLContext;
+typedef void *EGLClientBuffer;
+
+#define EGL_DEFAULT_DISPLAY ((NativeDisplayType)0)
+
+#define EGL_NO_CONTEXT      ((EGLContext)0)
+#define EGL_NO_DISPLAY      ((EGLDisplay)0)
+#define EGL_NO_SURFACE      ((EGLSurface)0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* ANDROID_EGL_TYPES_H */
diff --git a/include/GLES/gl.h b/include/GLES/gl.h
new file mode 100644
index 0000000..50b6ac4
--- /dev/null
+++ b/include/GLES/gl.h
@@ -0,0 +1,639 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __gl_h_
+#define __gl_h_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************/
+
+typedef int8_t              GLbyte;         // b
+typedef int16_t             GLshort;        // s
+typedef int32_t             GLint;          // i
+typedef ssize_t             GLsizei;        // i
+typedef int32_t             GLfixed;        // x
+typedef int32_t             GLclampx;       // x
+typedef float               GLfloat;        // f
+typedef float               GLclampf;       // f
+typedef uint8_t             GLubyte;        // ub
+typedef uint8_t             GLboolean;      // ub
+typedef uint16_t            GLushort;       // us
+typedef uint32_t            GLuint;         // ui
+typedef unsigned int        GLenum;         // ui
+typedef unsigned int        GLbitfield;     // ui
+typedef void                GLvoid;
+typedef intptr_t            GLintptr; 
+typedef int                 GLsizeiptr; 
+typedef GLintptr            GLintptrARB; 
+typedef GLsizeiptr          GLsizeiptrARB; 
+
+/*****************************************************************************/
+
+#define GL_VERSION_ES_CM_1_0                1
+#define GL_VERSION_ES_CL_1_0                1
+#define GL_VERSION_ES_CM_1_1                1
+#define GL_VERSION_ES_CL_1_1                1
+
+#define GL_OES_byte_coordinates             1
+#define GL_OES_fixed_point                  1
+#define GL_OES_single_precision             1
+#define GL_OES_read_format                  1
+#define GL_OES_compressed_paletted_texture  1
+#define GL_OES_draw_texture                 1
+#define GL_OES_matrix_get                   1
+#define GL_OES_query_matrix                 1
+#define GL_OES_vertex_buffer_object         1
+#define GL_OES_point_size_array             1
+#define GL_OES_point_sprite                 1
+#define GL_ARB_texture_non_power_of_two     1
+
+/*****************************************************************************/
+/* OpenGL ES 1.0 names */
+
+#define GL_FALSE                            0
+#define GL_TRUE                             1
+
+/* begin mode */
+#define GL_POINTS                           0x0000
+#define GL_LINES                            0x0001
+#define GL_LINE_LOOP                        0x0002
+#define GL_LINE_STRIP                       0x0003
+#define GL_TRIANGLES                        0x0004
+#define GL_TRIANGLE_STRIP                   0x0005
+#define GL_TRIANGLE_FAN                     0x0006
+
+/* clear mask  */
+#define GL_DEPTH_BUFFER_BIT                 0x00000100
+#define GL_STENCIL_BUFFER_BIT               0x00000400
+#define GL_COLOR_BUFFER_BIT                 0x00004000
+
+/* enable/disable */
+#define GL_FOG                              0x0B60
+#define GL_LIGHTING                         0x0B50
+#define GL_TEXTURE_2D                       0x0DE1
+#define GL_CULL_FACE                        0x0B44
+#define GL_ALPHA_TEST                       0x0BC0
+#define GL_BLEND                            0x0BE2
+#define GL_COLOR_LOGIC_OP                   0x0BF2
+#define GL_DITHER                           0x0BD0
+#define GL_STENCIL_TEST                     0x0B90
+#define GL_DEPTH_TEST                       0x0B71
+#define GL_POINT_SMOOTH                     0x0B10
+#define GL_LINE_SMOOTH                      0x0B20
+#define GL_SCISSOR_TEST                     0x0C11
+#define GL_COLOR_MATERIAL                   0x0B57
+#define GL_NORMALIZE                        0x0BA1
+#define GL_RESCALE_NORMAL                   0x803A
+#define GL_POLYGON_OFFSET_FILL              0x8037
+#define GL_VERTEX_ARRAY                     0x8074
+#define GL_NORMAL_ARRAY                     0x8075
+#define GL_COLOR_ARRAY                      0x8076
+#define GL_TEXTURE_COORD_ARRAY              0x8078
+#define GL_MULTISAMPLE                      0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE         0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE              0x809F
+#define GL_SAMPLE_COVERAGE                  0x80A0
+
+/* gets */
+#define GL_SMOOTH_POINT_SIZE_RANGE          0x0B12
+#define GL_SMOOTH_LINE_WIDTH_RANGE          0x0B22
+#define GL_ALIASED_POINT_SIZE_RANGE         0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE         0x846E
+#define GL_MAX_LIGHTS                       0x0D31
+#define GL_MAX_CLIP_PLANES                  0x0D32
+#define GL_MAX_TEXTURE_SIZE                 0x0D33
+#define GL_MAX_MODELVIEW_STACK_DEPTH        0x0D36
+#define GL_MAX_PROJECTION_STACK_DEPTH       0x0D38
+#define GL_MAX_TEXTURE_STACK_DEPTH          0x0D39
+#define GL_MAX_VIEWPORT_DIMS                0x0D3A
+#define GL_MAX_ELEMENTS_VERTICES            0x80E8
+#define GL_MAX_ELEMENTS_INDICES             0x80E9
+#define GL_MAX_TEXTURE_UNITS                0x84E2
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS   0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS       0x86A3
+#define GL_SUBPIXEL_BITS                    0x0D50
+#define GL_RED_BITS                         0x0D52
+#define GL_GREEN_BITS                       0x0D53
+#define GL_BLUE_BITS                        0x0D54
+#define GL_ALPHA_BITS                       0x0D55
+#define GL_DEPTH_BITS                       0x0D56
+#define GL_STENCIL_BITS                     0x0D57
+
+/* clip planes */
+#define GL_CLIP_PLANE0                      0x3000
+#define GL_CLIP_PLANE1                      0x3001
+#define GL_CLIP_PLANE2                      0x3002
+#define GL_CLIP_PLANE3                      0x3003
+#define GL_CLIP_PLANE4                      0x3004
+#define GL_CLIP_PLANE5                      0x3005
+
+/* errors */
+#define GL_NO_ERROR                         0
+#define GL_INVALID_ENUM                     0x0500
+#define GL_INVALID_VALUE                    0x0501
+#define GL_INVALID_OPERATION                0x0502
+#define GL_STACK_OVERFLOW                   0x0503
+#define GL_STACK_UNDERFLOW                  0x0504
+#define GL_OUT_OF_MEMORY                    0x0505
+
+/* fog */
+#define GL_EXP                              0x0800
+#define GL_EXP2                             0x0801
+#define GL_FOG_DENSITY                      0x0B62
+#define GL_FOG_START                        0x0B63
+#define GL_FOG_END                          0x0B64
+#define GL_FOG_MODE                         0x0B65
+#define GL_FOG_COLOR                        0x0B66
+
+/* culling */
+#define GL_CW                               0x0900
+#define GL_CCW                              0x0901
+
+#define GL_FRONT                            0x0404
+#define GL_BACK                             0x0405
+#define GL_FRONT_AND_BACK                   0x0408
+
+/* hints */
+#define GL_DONT_CARE                        0x1100
+#define GL_FASTEST                          0x1101
+#define GL_NICEST                           0x1102
+
+#define GL_PERSPECTIVE_CORRECTION_HINT      0x0C50
+#define GL_POINT_SMOOTH_HINT                0x0C51
+#define GL_LINE_SMOOTH_HINT                 0x0C52
+#define GL_POLYGON_SMOOTH_HINT              0x0C53
+#define GL_FOG_HINT                         0x0C54
+#define GL_GENERATE_MIPMAP_HINT             0x8192
+
+/* lights */
+#define GL_LIGHT_MODEL_AMBIENT              0x0B53
+#define GL_LIGHT_MODEL_TWO_SIDE             0x0B52
+
+#define GL_AMBIENT                          0x1200
+#define GL_DIFFUSE                          0x1201
+#define GL_SPECULAR                         0x1202
+#define GL_POSITION                         0x1203
+#define GL_SPOT_DIRECTION                   0x1204
+#define GL_SPOT_EXPONENT                    0x1205
+#define GL_SPOT_CUTOFF                      0x1206
+#define GL_CONSTANT_ATTENUATION             0x1207
+#define GL_LINEAR_ATTENUATION               0x1208
+#define GL_QUADRATIC_ATTENUATION            0x1209
+
+#define GL_LIGHT0                           0x4000
+#define GL_LIGHT1                           0x4001
+#define GL_LIGHT2                           0x4002
+#define GL_LIGHT3                           0x4003
+#define GL_LIGHT4                           0x4004
+#define GL_LIGHT5                           0x4005
+#define GL_LIGHT6                           0x4006
+#define GL_LIGHT7                           0x4007
+
+/* material */
+#define GL_EMISSION                         0x1600
+#define GL_SHININESS                        0x1601
+#define GL_AMBIENT_AND_DIFFUSE              0x1602
+
+/* matrix */
+#define GL_MODELVIEW                        0x1700
+#define GL_PROJECTION                       0x1701
+#define GL_TEXTURE                          0x1702
+
+/* types */
+#define GL_BYTE                             0x1400
+#define GL_UNSIGNED_BYTE                    0x1401
+#define GL_SHORT                            0x1402
+#define GL_UNSIGNED_SHORT                   0x1403
+#define GL_FLOAT                            0x1406
+#define GL_FIXED                            0x140C
+
+/* pixel formats */
+#define GL_ALPHA                            0x1906
+#define GL_RGB                              0x1907
+#define GL_RGBA                             0x1908
+#define GL_LUMINANCE                        0x1909
+#define GL_LUMINANCE_ALPHA                  0x190A
+
+/* pixel store */
+#define GL_UNPACK_ALIGNMENT                 0x0CF5
+#define GL_PACK_ALIGNMENT                   0x0D05
+
+/* pixel types */
+#define GL_UNSIGNED_SHORT_4_4_4_4           0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1           0x8034
+#define GL_UNSIGNED_SHORT_5_6_5             0x8363
+
+/* logic op */
+#define GL_CLEAR                            0x1500   // 0
+#define GL_AND                              0x1501   // s & d
+#define GL_AND_REVERSE                      0x1502   // s & ~d
+#define GL_COPY                             0x1503   // s
+#define GL_AND_INVERTED                     0x1504   // ~s & d
+#define GL_NOOP                             0x1505   // d
+#define GL_XOR                              0x1506   // s ^ d
+#define GL_OR                               0x1507   // s | d
+#define GL_NOR                              0x1508   // ~(s | d)
+#define GL_EQUIV                            0x1509   // ~(s ^ d)
+#define GL_INVERT                           0x150A   // ~d
+#define GL_OR_REVERSE                       0x150B   // s | ~d
+#define GL_COPY_INVERTED                    0x150C   // ~s 
+#define GL_OR_INVERTED                      0x150D   // ~s | d
+#define GL_NAND                             0x150E   // ~(s & d)
+#define GL_SET                              0x150F   // 1
+
+/* shade model */
+#define GL_FLAT                             0x1D00
+#define GL_SMOOTH                           0x1D01
+
+/* strings */
+#define GL_VENDOR                           0x1F00
+#define GL_RENDERER                         0x1F01
+#define GL_VERSION                          0x1F02
+#define GL_EXTENSIONS                       0x1F03
+
+/* stencil */
+#define GL_KEEP                             0x1E00
+#define GL_REPLACE                          0x1E01
+#define GL_INCR                             0x1E02
+#define GL_DECR                             0x1E03
+
+/* alpha & stencil */
+#define GL_NEVER                            0x0200
+#define GL_LESS                             0x0201
+#define GL_EQUAL                            0x0202
+#define GL_LEQUAL                           0x0203
+#define GL_GREATER                          0x0204
+#define GL_NOTEQUAL                         0x0205
+#define GL_GEQUAL                           0x0206
+#define GL_ALWAYS                           0x0207
+
+/* blending equation & function */
+#define GL_ZERO                             0           // SD
+#define GL_ONE                              1           // SD
+#define GL_SRC_COLOR                        0x0300      //  D
+#define GL_ONE_MINUS_SRC_COLOR              0x0301      //  D
+#define GL_SRC_ALPHA                        0x0302      // SD
+#define GL_ONE_MINUS_SRC_ALPHA              0x0303      // SD
+#define GL_DST_ALPHA                        0x0304      // SD
+#define GL_ONE_MINUS_DST_ALPHA              0x0305      // SD
+#define GL_DST_COLOR                        0x0306      // S
+#define GL_ONE_MINUS_DST_COLOR              0x0307      // S
+#define GL_SRC_ALPHA_SATURATE               0x0308      // S
+    
+/* Texture parameter name */
+#define GL_TEXTURE_MIN_FILTER               0x2801
+#define GL_TEXTURE_MAG_FILTER               0x2800
+#define GL_TEXTURE_WRAP_S                   0x2802
+#define GL_TEXTURE_WRAP_T                   0x2803
+#define GL_GENERATE_MIPMAP                  0x8191
+#define GL_TEXTURE_CROP_RECT_OES            0x8B9D
+
+/* Texture Filter */
+#define GL_NEAREST                          0x2600
+#define GL_LINEAR                           0x2601
+#define GL_NEAREST_MIPMAP_NEAREST           0x2700
+#define GL_LINEAR_MIPMAP_NEAREST            0x2701
+#define GL_NEAREST_MIPMAP_LINEAR            0x2702
+#define GL_LINEAR_MIPMAP_LINEAR             0x2703
+
+/* Texture Wrap Mode */
+#define GL_CLAMP                            0x2900
+#define GL_REPEAT                           0x2901
+#define GL_CLAMP_TO_EDGE                    0x812F
+
+/* Texture Env Mode */
+#define GL_REPLACE                          0x1E01
+#define GL_MODULATE                         0x2100
+#define GL_DECAL                            0x2101
+#define GL_ADD                              0x0104
+
+/* Texture Env Parameter */
+#define GL_TEXTURE_ENV_MODE                 0x2200
+#define GL_TEXTURE_ENV_COLOR                0x2201
+
+/* Texture Env Target */
+#define GL_TEXTURE_ENV                      0x2300
+
+/* TMUs */
+#define GL_TEXTURE0                         0x84C0
+#define GL_TEXTURE1                         0x84C1
+#define GL_TEXTURE2                         0x84C2
+#define GL_TEXTURE3                         0x84C3
+#define GL_TEXTURE4                         0x84C4
+#define GL_TEXTURE5                         0x84C5
+#define GL_TEXTURE6                         0x84C6
+#define GL_TEXTURE7                         0x84C7
+#define GL_TEXTURE8                         0x84C8
+#define GL_TEXTURE9                         0x84C9
+#define GL_TEXTURE10                        0x84CA
+#define GL_TEXTURE11                        0x84CB
+#define GL_TEXTURE12                        0x84CC
+#define GL_TEXTURE13                        0x84CD
+#define GL_TEXTURE14                        0x84CE
+#define GL_TEXTURE15                        0x84CF
+#define GL_TEXTURE16                        0x84D0
+#define GL_TEXTURE17                        0x84D1
+#define GL_TEXTURE18                        0x84D2
+#define GL_TEXTURE19                        0x84D3
+#define GL_TEXTURE20                        0x84D4
+#define GL_TEXTURE21                        0x84D5
+#define GL_TEXTURE22                        0x84D6
+#define GL_TEXTURE23                        0x84D7
+#define GL_TEXTURE24                        0x84D8
+#define GL_TEXTURE25                        0x84D9
+#define GL_TEXTURE26                        0x84DA
+#define GL_TEXTURE27                        0x84DB
+#define GL_TEXTURE28                        0x84DC
+#define GL_TEXTURE29                        0x84DD
+#define GL_TEXTURE30                        0x84DE
+#define GL_TEXTURE31                        0x84DF
+
+/*****************************************************************************/
+/* OpenGL ES 1.1 additions */
+
+#define GL_ARRAY_BUFFER                         0x8892
+#define GL_ELEMENT_ARRAY_BUFFER                 0x8893
+
+#define GL_STATIC_DRAW                          0x88E4
+#define GL_DYNAMIC_DRAW                         0x88E8
+
+#define GL_BUFFER_SIZE                          0x8764
+#define GL_BUFFER_USAGE                         0x8765
+
+#define GL_ARRAY_BUFFER_BINDING                 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING         0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING          0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING          0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING           0x8898
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING   0x889A
+
+/*****************************************************************************/
+/* Required extensions */
+
+#define GL_PALETTE4_RGB8_OES                        0x8B90
+#define GL_PALETTE4_RGBA8_OES                       0x8B91
+#define GL_PALETTE4_R5_G6_B5_OES                    0x8B92
+#define GL_PALETTE4_RGBA4_OES                       0x8B93
+#define GL_PALETTE4_RGB5_A1_OES                     0x8B94
+#define GL_PALETTE8_RGB8_OES                        0x8B95
+#define GL_PALETTE8_RGBA8_OES                       0x8B96
+#define GL_PALETTE8_R5_G6_B5_OES                    0x8B97
+#define GL_PALETTE8_RGBA4_OES                       0x8B98
+#define GL_PALETTE8_RGB5_A1_OES                     0x8B99
+
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES       0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES     0x8B9B
+
+#define GL_POINT_SPRITE_OES                         0x8861
+#define GL_COORD_REPLACE_OES                        0x8862
+
+#define GL_POINT_SIZE_ARRAY_OES                     0x8B9C
+#define GL_POINT_SIZE_ARRAY_TYPE_OES                0x898A
+#define GL_POINT_SIZE_ARRAY_STRIDE_OES              0x898B
+#define GL_POINT_SIZE_ARRAY_POINTER_OES             0x898C
+#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES      0x8B9F
+
+/*****************************************************************************/
+/* Extensions */
+
+#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES   0x898D
+#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES  0x898E
+#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES     0x898F
+
+#define GL_DIRECT_TEXTURE_2D_QUALCOMM               0x7E80
+
+
+
+
+/*****************************************************************************/
+/* OpenGL ES 1.0 functions */
+
+void glActiveTexture(GLenum texture);
+void glAlphaFunc(GLenum func, GLclampf ref);
+void glAlphaFuncx(GLenum func, GLclampx ref);
+void glBindTexture(GLenum target, GLuint texture);
+void glBlendFunc(GLenum sfactor, GLenum dfactor);
+void glClear(GLbitfield mask);
+void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+void glClearDepthf(GLclampf depth);
+void glClearDepthx(GLclampx depth);
+void glClearStencil(GLint s);
+void glClientActiveTexture(GLenum texture);
+void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+void glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+void glColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
+void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
+        GLsizei width, GLsizei height, GLint border,
+        GLsizei imageSize, const GLvoid *data);
+void glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset,
+        GLint yoffset, GLsizei width, GLsizei height,
+        GLenum format, GLsizei imageSize,
+        const GLvoid *data);
+void glCopyTexImage2D(  GLenum target, GLint level, GLenum internalformat,
+        GLint x, GLint y, GLsizei width, GLsizei height,
+        GLint border);
+void glCopyTexSubImage2D(   GLenum target, GLint level, GLint xoffset,
+        GLint yoffset, GLint x, GLint y, GLsizei width,
+        GLsizei height);
+void glCullFace(GLenum mode);
+void glDeleteTextures(GLsizei n, const GLuint *textures);
+void glDepthFunc(GLenum func);
+void glDepthMask(GLboolean flag);
+void glDepthRangef(GLclampf zNear, GLclampf zFar);
+void glDepthRangex(GLclampx zNear, GLclampx zFar);
+void glDisable(GLenum cap);
+void glDisableClientState(GLenum array);
+void glDrawArrays(GLenum mode, GLint first, GLsizei count);
+void glDrawElements(GLenum mode, GLsizei count,
+        GLenum type, const GLvoid *indices);
+void glEnable(GLenum cap);
+void glEnableClientState(GLenum array);
+void glFinish(void);
+void glFlush(void);
+void glFogf(GLenum pname, GLfloat param);
+void glFogfv(GLenum pname, const GLfloat *params);
+void glFogx(GLenum pname, GLfixed param);
+void glFogxv(GLenum pname, const GLfixed *params);
+void glFrontFace(GLenum mode);
+void glFrustumf(GLfloat left, GLfloat right,
+        GLfloat bottom, GLfloat top,
+        GLfloat zNear, GLfloat zFar);
+void glFrustumx(GLfixed left, GLfixed right,
+        GLfixed bottom, GLfixed top,
+        GLfixed zNear, GLfixed zFar);
+void glGenTextures(GLsizei n, GLuint *textures);
+GLenum glGetError(void);
+void glGetIntegerv(GLenum pname, GLint *params);
+const GLubyte * glGetString(GLenum name);
+void glHint(GLenum target, GLenum mode);
+void glLightModelf(GLenum pname, GLfloat param);
+void glLightModelfv(GLenum pname, const GLfloat *params);
+void glLightModelx(GLenum pname, GLfixed param);
+void glLightModelxv(GLenum pname, const GLfixed *params);
+void glLightf(GLenum light, GLenum pname, GLfloat param);
+void glLightfv(GLenum light, GLenum pname, const GLfloat *params);
+void glLightx(GLenum light, GLenum pname, GLfixed param);
+void glLightxv(GLenum light, GLenum pname, const GLfixed *params);
+void glLineWidth(GLfloat width);
+void glLineWidthx(GLfixed width);
+void glLoadIdentity(void);
+void glLoadMatrixf(const GLfloat *m);
+void glLoadMatrixx(const GLfixed *m);
+void glLogicOp(GLenum opcode);
+void glMaterialf(GLenum face, GLenum pname, GLfloat param);
+void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params);
+void glMaterialx(GLenum face, GLenum pname, GLfixed param);
+void glMaterialxv(GLenum face, GLenum pname, const GLfixed *params);
+void glMatrixMode(GLenum mode);
+void glMultMatrixf(const GLfloat *m);
+void glMultMatrixx(const GLfixed *m);
+void glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+void glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz);
+void glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz);
+void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
+void glOrthof(  GLfloat left, GLfloat right,
+        GLfloat bottom, GLfloat top,
+        GLfloat zNear, GLfloat zFar);
+void glOrthox(  GLfixed left, GLfixed right,
+        GLfixed bottom, GLfixed top,
+        GLfixed zNear, GLfixed zFar);
+void glPixelStorei(GLenum pname, GLint param);
+void glPointSize(GLfloat size);
+void glPointSizex(GLfixed size);
+void glPolygonOffset(GLfloat factor, GLfloat units);
+void glPolygonOffsetx(GLfixed factor, GLfixed units);
+void glPopMatrix(void);
+void glPushMatrix(void);
+void glReadPixels(  GLint x, GLint y, GLsizei width, GLsizei height,
+        GLenum format, GLenum type, GLvoid *pixels);
+void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+void glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+void glSampleCoverage(GLclampf value, GLboolean invert);
+void glSampleCoveragex(GLclampx value, GLboolean invert);
+void glScalef(GLfloat x, GLfloat y, GLfloat z);
+void glScalex(GLfixed x, GLfixed y, GLfixed z);
+void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
+void glShadeModel(GLenum mode);
+void glStencilFunc(GLenum func, GLint ref, GLuint mask);
+void glStencilMask(GLuint mask);
+void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+void glTexCoordPointer( GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer);
+void glTexEnvf(GLenum target, GLenum pname, GLfloat param);
+void glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params);
+void glTexEnvx(GLenum target, GLenum pname, GLfixed param);
+void glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params);
+void glTexImage2D(  GLenum target, GLint level, GLenum internalformat,
+        GLsizei width, GLsizei height, GLint border, GLenum format,
+        GLenum type, const GLvoid *pixels);
+void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
+void glTexParameterx(GLenum target, GLenum pname, GLfixed param);
+void glTexSubImage2D(   GLenum target, GLint level, GLint xoffset,
+        GLint yoffset, GLsizei width, GLsizei height,
+        GLenum format, GLenum type, const GLvoid *pixels);
+void glTranslatef(GLfloat x, GLfloat y, GLfloat z);
+void glTranslatex(GLfixed x, GLfixed y, GLfixed z);
+void glVertexPointer(   GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer);
+void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
+
+/*****************************************************************************/
+/* OpenGL ES 1.1 functions */
+
+void glClipPlanef(GLenum plane, const GLfloat* equation);
+void glClipPlanex(GLenum plane, const GLfixed* equation);
+
+void glBindBuffer(GLenum target, GLuint buffer);
+void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+void glDeleteBuffers(GLsizei n, const GLuint* buffers);
+void glGenBuffers(GLsizei n, GLuint* buffers);
+
+void glGetBooleanv(GLenum pname, GLboolean *params);
+void glGetFixedv(GLenum pname, GLfixed *params);
+void glGetFloatv(GLenum pname, GLfloat *params);
+void glGetPointerv(GLenum pname, void **params);
+void glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params);
+void glGetClipPlanef(GLenum pname, GLfloat eqn[4]);
+void glGetClipPlanex(GLenum pname, GLfixed eqn[4]);
+void glGetLightxv(GLenum light, GLenum pname, GLfixed *params);
+void glGetLightfv(GLenum light, GLenum pname, GLfloat *params);
+void glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params);
+void glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params);
+void glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params);
+void glGetTexEnviv(GLenum env, GLenum pname, GLint *params);
+void glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params);
+void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params);
+void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params);
+void glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params);
+GLboolean glIsBuffer(GLuint buffer);
+GLboolean glIsEnabled(GLenum cap);
+GLboolean glIsTexture(GLuint texture);
+void glPointParameterf(GLenum pname, GLfloat param);
+void glPointParameterfv(GLenum pname, const GLfloat *params);
+void glPointParameterx(GLenum pname, GLfixed param);
+void glPointParameterxv(GLenum pname, const GLfixed *params);
+void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+void glTexEnvi(GLenum target, GLenum pname, GLint param);
+void glTexEnviv(GLenum target, GLenum pname, const GLint *params);
+void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params);
+void glTexParameteriv(GLenum target, GLenum pname, const GLint *params);
+void glTexParameteri(GLenum target, GLenum pname, GLint param);
+void glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params);
+
+/*****************************************************************************/
+/* Required extensions functions */
+
+void glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer);
+
+
+/*****************************************************************************/
+/* Extensions functions */
+
+void glDrawTexsOES(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h);
+void glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h);
+void glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h);
+void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h);
+void glDrawTexsvOES(const GLshort* coords);
+void glDrawTexivOES(const GLint* coords);
+void glDrawTexfvOES(const GLfloat* coords);
+void glDrawTexxvOES(const GLfixed* coords);
+GLbitfield glQueryMatrixxOES(GLfixed* mantissa, GLint* exponent);
+
+/* called by dalvik */
+void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
+        const GLvoid *ptr, GLsizei count);
+void glNormalPointerBounds(GLenum type, GLsizei stride,
+        const GLvoid *pointer, GLsizei count);
+void glTexCoordPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+void glVertexPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gl_h_ */
diff --git a/include/pim/EventRecurrence.h b/include/pim/EventRecurrence.h
new file mode 100644
index 0000000..1ceda41
--- /dev/null
+++ b/include/pim/EventRecurrence.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _PIM_EVENT_RECURRENCE_H
+#define _PIM_EVENT_RECURRENCE_H
+
+#include <utils/String16.h>
+
+namespace android {
+
+struct EventRecurrence
+{
+public:
+                EventRecurrence();
+                ~EventRecurrence();
+    
+    status_t    parse(const String16&);
+
+
+    enum freq_t {
+        SECONDLY = 1,
+        MINUTELY = 2,
+        HOURLY = 3,
+        DAILY = 4,
+        WEEKLY = 5,
+        MONTHLY = 6,
+        YEARLY = 7
+    };
+
+    enum {
+        SU = 0x00010000,
+        MO = 0x00020000,
+        TU = 0x00040000,
+        WE = 0x00080000,
+        TH = 0x00100000,
+        FR = 0x00200000,
+        SA = 0x00400000
+    };
+    
+    freq_t    freq;
+    String16  until;
+    int       count;
+    int       interval;
+    int*      bysecond;
+    int       bysecondCount;
+    int*      byminute;
+    int       byminuteCount;
+    int*      byhour;
+    int       byhourCount;
+    int*      byday;
+    int*      bydayNum;
+    int       bydayCount;   
+    int*      bymonthday;
+    int       bymonthdayCount;
+    int*      byyearday;
+    int       byyeardayCount;
+    int*      byweekno;
+    int       byweeknoCount;
+    int*      bymonth;
+    int       bymonthCount;
+    int*      bysetpos;
+    int       bysetposCount;
+    int       wkst;
+};
+
+}; // namespace android
+
+#endif // _PIM_EVENT_RECURRENCE_H
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
new file mode 100644
index 0000000..67d50fd
--- /dev/null
+++ b/include/private/opengles/gl_context.h
@@ -0,0 +1,624 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CONTEXT_H
+#define ANDROID_OPENGLES_CONTEXT_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <pthread.h>
+#ifdef HAVE_ANDROID_OS
+#include <sys/tls.h>
+#endif
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+namespace android {
+
+const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10;
+
+class EGLTextureObject;
+class EGLSurfaceManager;
+class EGLBufferObjectManager;
+
+namespace gl {
+ 
+struct ogles_context_t;
+struct matrixx_t;
+struct transform_t;
+struct buffer_t;
+
+ogles_context_t* getGlContext();
+
+template<typename T>
+static inline void swap(T& a, T& b) {
+    T t(a); a = b; b = t;
+}
+template<typename T>
+inline T max(T a, T b) {
+    return a<b ? b : a;
+}
+template<typename T>
+inline T max(T a, T b, T c) {
+    return max(a, max(b, c));
+}
+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(min(a,b), min(c,d));
+}
+
+// ----------------------------------------------------------------------------
+// vertices
+// ----------------------------------------------------------------------------
+
+struct vec3_t {
+    union {
+        struct { GLfixed x, y, z; };
+        struct { GLfixed r, g, b; };
+        struct { GLfixed S, T, R; };
+        GLfixed v[3];
+    };
+};
+
+struct vec4_t {
+    union {
+        struct { GLfixed x, y, z, w; };
+        struct { GLfixed r, g, b, a; };
+        struct { GLfixed S, T, R, Q; };
+        GLfixed v[4];
+    };
+};
+
+struct vertex_t {
+    enum {
+        // these constant matter for our clipping 
+        CLIP_L          = 0x0001,   // clipping flags
+        CLIP_R          = 0x0002,
+        CLIP_B          = 0x0004,
+        CLIP_T          = 0x0008,
+        CLIP_N          = 0x0010,
+        CLIP_F          = 0x0020,
+
+        EYE             = 0x0040,
+        RESERVED        = 0x0080,
+        
+        USER_CLIP_0     = 0x0100,   // user clipping flags
+        USER_CLIP_1     = 0x0200,
+        USER_CLIP_2     = 0x0400,
+        USER_CLIP_3     = 0x0800,
+        USER_CLIP_4     = 0x1000,
+        USER_CLIP_5     = 0x2000,
+
+        LIT             = 0x4000,   // lighting has been applied
+        TT              = 0x8000,   // texture coords transformed
+
+        FRUSTUM_CLIP_ALL= 0x003F,
+        USER_CLIP_ALL   = 0x3F00,
+        CLIP_ALL        = 0x3F3F,
+    };
+    
+    // the fields below are arranged to minimize d-cache usage
+    // we group together, by cache-line, the fields most likely to be used
+
+    union {
+    vec4_t          obj;
+    vec4_t          eye;
+    };
+    vec4_t          clip;
+    
+    uint32_t        flags;
+    size_t          index;  // cache tag, and vertex index
+    GLfixed         fog;
+    uint8_t         locked;
+    uint8_t         mru;
+    uint8_t         reserved[2];
+    vec4_t          window;
+
+    vec4_t          color;
+    vec4_t          texture[GGL_TEXTURE_UNIT_COUNT];
+    uint32_t        reserved1[4];
+    
+    inline void clear() {
+        flags = index = locked = mru = 0;
+    }
+};
+
+struct point_size_t {
+    GGLcoord    size;
+    GLboolean   smooth;
+};
+
+struct line_width_t {
+    GGLcoord    width;
+    GLboolean   smooth;
+};
+
+struct polygon_offset_t {
+    GLfixed     factor;
+    GLfixed     units;
+    GLboolean   enable;
+};
+
+// ----------------------------------------------------------------------------
+// arrays
+// ----------------------------------------------------------------------------
+
+struct array_t {
+    typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*);
+    fetcher_t       fetch;
+    GLvoid const*   physical_pointer;
+    GLint           size;
+    GLsizei         stride;
+    GLvoid const*   pointer;
+    buffer_t const* bo;
+    uint16_t        type;
+    GLboolean       enable;
+    GLboolean       pad;
+    GLsizei         bounds;
+    void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei);
+    inline void resolve();
+    inline const GLubyte* element(GLint i) const {
+        return (const GLubyte*)physical_pointer + i * stride;
+    }
+};
+
+struct array_machine_t {
+    array_t         vertex;
+    array_t         normal;
+    array_t         color;
+    array_t         texture[GGL_TEXTURE_UNIT_COUNT];
+    uint8_t         activeTexture;
+    uint8_t         tmu;
+    uint16_t        cull;
+    uint32_t        flags;
+    GLenum          indicesType;
+    buffer_t const* array_buffer;
+    buffer_t const* element_array_buffer;
+    
+    void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
+    void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
+
+    void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*);
+    void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*);
+    void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*);
+    void (*perspective)(ogles_context_t*c, vertex_t* v);
+    void (*clipVertex)(ogles_context_t* c, vertex_t* nv,
+            GGLfixed t, const vertex_t* s, const vertex_t* p);
+    void (*clipEye)(ogles_context_t* c, vertex_t* nv,
+            GGLfixed t, const vertex_t* s, const vertex_t* p);
+};
+
+struct vertex_cache_t {
+    enum {
+        // must be at least 4
+        // 3 vertice for triangles
+        // or 2 + 2 for indexed triangles w/ cache contention
+        VERTEX_BUFFER_SIZE  = 8,
+        // must be a power of two and at least 3
+        VERTEX_CACHE_SIZE   = 64,   // 8 KB
+
+        INDEX_BITS      = 16,
+        INDEX_MASK      = ((1LU<<INDEX_BITS)-1),
+        INDEX_SEQ       = 1LU<<INDEX_BITS,
+    };
+    vertex_t*       vBuffer;
+    vertex_t*       vCache;
+    uint32_t        sequence;
+    void*           base;
+    uint32_t        total;
+    uint32_t        misses;
+    int64_t         startTime;
+    void init();
+    void uninit();
+    void clear();
+    void dump_stats(GLenum mode);
+};
+
+// ----------------------------------------------------------------------------
+// fog
+// ----------------------------------------------------------------------------
+
+struct fog_t {
+    GLfixed     density;
+    GLfixed     start;
+    GLfixed     end;
+    GLfixed     invEndMinusStart;
+    GLenum      mode;
+    GLfixed     (*fog)(ogles_context_t* c, GLfixed z);
+};
+
+// ----------------------------------------------------------------------------
+// user clip planes
+// ----------------------------------------------------------------------------
+
+const unsigned int OGLES_MAX_CLIP_PLANES = 6;
+
+struct clip_plane_t {
+    vec4_t      equation;
+};
+
+struct user_clip_planes_t {
+    clip_plane_t    plane[OGLES_MAX_CLIP_PLANES];
+    uint32_t        enable;
+};
+
+// ----------------------------------------------------------------------------
+// lighting
+// ----------------------------------------------------------------------------
+
+const unsigned int OGLES_MAX_LIGHTS = 8;
+
+struct light_t {
+    vec4_t      ambient;
+    vec4_t      diffuse;
+    vec4_t      specular;
+    vec4_t      implicitAmbient;
+    vec4_t      implicitDiffuse;
+    vec4_t      implicitSpecular;
+    vec4_t      position;       // position in eye space
+    vec4_t      objPosition;
+    vec4_t      normalizedObjPosition;
+    vec4_t      spotDir;
+    vec4_t      normalizedSpotDir;
+    GLfixed     spotExp;
+    GLfixed     spotCutoff;
+    GLfixed     spotCutoffCosine;
+    GLfixed     attenuation[3];
+    GLfixed     rConstAttenuation;
+    GLboolean   enable;
+};
+
+struct material_t {
+    vec4_t      ambient;
+    vec4_t      diffuse;
+    vec4_t      specular;
+    vec4_t      emission;
+    GLfixed     shininess;
+};
+
+struct light_model_t {
+    vec4_t      ambient;
+    GLboolean   twoSide;
+};
+
+struct color_material_t {
+    GLenum      face;
+    GLenum      mode;
+    GLboolean   enable;
+};
+
+struct lighting_t {
+    light_t             lights[OGLES_MAX_LIGHTS];
+    material_t          front;
+    light_model_t       lightModel;
+    color_material_t    colorMaterial;
+    uint32_t            enabledLights;
+    GLboolean           enable;
+    vec4_t              implicitSceneEmissionAndAmbient;
+    GLenum              shadeModel;
+    typedef void (*light_fct_t)(ogles_context_t*, vertex_t*);
+    void (*lightVertex)(ogles_context_t* c, vertex_t* v);
+    void (*lightTriangle)(ogles_context_t* c,
+            vertex_t* v0, vertex_t* v1, vertex_t* v2);
+};
+
+struct culling_t {
+    GLenum      cullFace;
+    GLenum      frontFace;
+    GLboolean   enable;
+};
+
+// ----------------------------------------------------------------------------
+// textures
+// ----------------------------------------------------------------------------
+
+struct texture_unit_t {
+    GLuint              name;
+    EGLTextureObject*   texture;
+    uint8_t             dirty;
+};
+
+struct texture_state_t
+{
+    texture_unit_t      tmu[GGL_TEXTURE_UNIT_COUNT];
+    int                 active;     // active tmu
+    EGLTextureObject*   defaultTexture;
+    GGLContext*         ggl;
+    uint8_t             packAlignment;
+    uint8_t             unpackAlignment;
+};
+
+// ----------------------------------------------------------------------------
+// transformation and matrices
+// ----------------------------------------------------------------------------
+
+struct matrixf_t;
+
+struct matrixx_t {
+    GLfixed m[16];
+    void load(const matrixf_t& rhs);
+};
+
+struct matrix_stack_t;
+
+
+struct matrixf_t {
+    void loadIdentity();
+    void load(const matrixf_t& rhs);
+
+    inline GLfloat* editElements() { return m; }
+    inline GLfloat const* elements() const { return m; }
+
+    void set(const GLfixed* rhs);
+    void set(const GLfloat* rhs);
+
+    static void multiply(matrixf_t& r,
+            const matrixf_t& lhs, const matrixf_t& rhs);
+
+    void dump(const char* what);
+
+private:
+    friend struct matrix_stack_t;
+    GLfloat     m[16];
+    void load(const GLfixed* rhs);
+    void load(const GLfloat* rhs);
+    void multiply(const matrixf_t& rhs);
+    void translate(GLfloat x, GLfloat y, GLfloat z);
+    void scale(GLfloat x, GLfloat y, GLfloat z);
+    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
+};
+
+enum {
+    OP_IDENTITY         = 0x00,
+    OP_TRANSLATE        = 0x01,
+    OP_UNIFORM_SCALE    = 0x02,
+    OP_SCALE            = 0x05,
+    OP_ROTATE           = 0x08,
+    OP_SKEW             = 0x10,
+    OP_ALL              = 0x1F
+};
+
+struct transform_t {
+    enum {
+        FLAGS_2D_PROJECTION = 0x1
+    };
+    matrixx_t       matrix;
+    uint32_t        flags;
+    uint32_t        ops;
+    
+    union {
+        struct {
+            void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
+            void (*point3)(transform_t const* t, vec4_t*, vec4_t const*);
+            void (*point4)(transform_t const* t, vec4_t*, vec4_t const*);
+        };
+        void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*);
+    };
+
+    void loadIdentity();
+    void picker();
+    void dump(const char* what);
+};
+
+struct mvui_transform_t : public transform_t
+{
+    void picker();
+};
+
+struct matrix_stack_t {
+    enum {
+        DO_PICKER           = 0x1,
+        DO_FLOAT_TO_FIXED   = 0x2
+    };
+    transform_t     transform;
+    uint8_t         maxDepth;
+    uint8_t         depth;
+    uint8_t         dirty;
+    uint8_t         reserved;
+    matrixf_t       *stack;
+    uint8_t         *ops;
+    void init(int depth);
+    void uninit();
+    void loadIdentity();
+    void load(const GLfixed* rhs);
+    void load(const GLfloat* rhs);
+    void multiply(const matrixf_t& rhs);
+    void translate(GLfloat x, GLfloat y, GLfloat z);
+    void scale(GLfloat x, GLfloat y, GLfloat z);
+    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
+    GLint push();
+    GLint pop();
+    void validate();
+    matrixf_t& top() { return stack[depth]; }
+    const matrixf_t& top() const { return stack[depth]; }
+    const uint32_t top_ops() const { return ops[depth]; }
+    inline bool isRigidBody() const {
+        return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
+    }
+};
+
+struct vp_transform_t {
+    transform_t     transform;
+    matrixf_t       matrix;
+    GLfloat         zNear;
+    GLfloat         zFar;
+    void loadIdentity();
+};
+
+struct transform_state_t {
+    enum {
+        MODELVIEW           = 0x01,
+        PROJECTION          = 0x02,
+        VIEWPORT            = 0x04,
+        TEXTURE             = 0x08,
+        MVUI                = 0x10,
+        MVIT                = 0x20,
+        MVP                 = 0x40,
+    };
+    matrix_stack_t      *current;
+    matrix_stack_t      modelview;
+    matrix_stack_t      projection;
+    matrix_stack_t      texture[GGL_TEXTURE_UNIT_COUNT];
+
+    // modelview * projection
+    transform_t         mvp     __attribute__((aligned(32)));
+    // viewport transformation
+    vp_transform_t      vpt     __attribute__((aligned(32)));
+    // same for 4-D vertices
+    transform_t         mvp4;
+    // full modelview inverse transpose
+    transform_t         mvit4;
+    // upper 3x3 of mv-inverse-transpose (for normals)
+    mvui_transform_t    mvui;
+
+    GLenum              matrixMode;
+    GLenum              rescaleNormals;
+    uint32_t            dirty;
+    void invalidate();
+    void update_mvp();
+    void update_mvit();
+    void update_mvui();
+};
+
+struct viewport_t {
+    GLint       x;
+    GLint       y;
+    GLsizei     w;
+    GLsizei     h; 
+    struct {
+        GLint       x;
+        GLint       y;
+    } surfaceport;  
+    struct {
+        GLint       x;
+        GLint       y;
+        GLsizei     w;
+        GLsizei     h; 
+    } scissor;  
+};
+
+// ----------------------------------------------------------------------------
+// Lerping
+// ----------------------------------------------------------------------------
+
+struct compute_iterators_t
+{
+    void initTriangle(
+            vertex_t const* v0,
+            vertex_t const* v1,
+            vertex_t const* v2);
+
+    inline void initLerp(vertex_t const* v0, uint32_t enables);
+
+    int iteratorsScale(int32_t it[3],
+            int32_t c0, int32_t c1, int32_t c2) const;
+
+    void iterators1616(GGLfixed it[3],
+            GGLfixed c0, GGLfixed c1, GGLfixed c2) const;
+
+    void iterators0032(int32_t it[3],
+            int32_t c0, int32_t c1, int32_t c2) const;
+
+    GGLcoord area() const { return m_area; }
+
+private:
+    // don't change order of members here -- used by iterators.S
+    GGLcoord m_dx01, m_dy10, m_dx20, m_dy02;
+    GGLcoord m_x0, m_y0;
+    GGLcoord m_area;
+    uint8_t m_scale;
+    uint8_t m_area_scale;
+    uint8_t m_reserved[2];
+
+};
+
+// ----------------------------------------------------------------------------
+// state
+// ----------------------------------------------------------------------------
+
+#ifdef HAVE_ANDROID_OS
+    // We have a dedicated TLS slot in bionic
+    inline void setGlThreadSpecific(ogles_context_t *value) {
+        ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
+    }
+    inline ogles_context_t* getGlThreadSpecific() {
+        return (ogles_context_t *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
+    }
+#else
+    extern pthread_key_t gGLKey;
+    inline void setGlThreadSpecific(ogles_context_t *value) {
+        pthread_setspecific(gGLKey, value);
+    }
+    inline ogles_context_t* getGlThreadSpecific() {
+        return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
+    }
+#endif
+
+
+struct prims_t {
+    typedef ogles_context_t* GL;
+    void (*renderPoint)(GL, vertex_t*);
+    void (*renderLine)(GL, vertex_t*, vertex_t*);
+    void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
+};
+
+struct ogles_context_t {
+    context_t               rasterizer;
+    array_machine_t         arrays         __attribute__((aligned(32)));
+    texture_state_t         textures;
+    transform_state_t       transforms;
+    vertex_cache_t          vc;
+    prims_t                 prims;
+    culling_t               cull;
+    lighting_t              lighting;
+    user_clip_planes_t      clipPlanes;
+    compute_iterators_t     lerp;           __attribute__((aligned(32)));
+    vertex_t                current;
+    vec4_t                  currentColorClamped;
+    vec3_t                  currentNormal;
+    viewport_t              viewport;
+    point_size_t            point;
+    line_width_t            line;
+    polygon_offset_t        polygonOffset;
+    fog_t                   fog;
+    uint32_t                perspective : 1;
+    uint32_t                transformTextures : 1;
+    EGLSurfaceManager*      surfaceManager;
+    EGLBufferObjectManager* bufferObjectManager;
+    GLenum                  error;
+
+    static inline ogles_context_t* get() {
+        return getGlThreadSpecific();
+    }
+
+};
+
+}; // namespace gl
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_CONTEXT_H
+
diff --git a/include/private/ui/LayerState.h b/include/private/ui/LayerState.h
new file mode 100644
index 0000000..b6fcd80
--- /dev/null
+++ b/include/private/ui/LayerState.h
@@ -0,0 +1,75 @@
+/*
+ * 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_COMPOSER_LAYER_STATE_H
+#define ANDROID_COMPOSER_LAYER_STATE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+
+#include <ui/ISurfaceFlingerClient.h>
+#include <ui/Region.h>
+
+#include <private/ui/SharedState.h>
+
+namespace android {
+
+class Parcel;
+
+struct layer_state_t {
+
+    layer_state_t()
+        :   surface(0), what(0),
+            x(0), y(0), z(0), w(0), h(0),
+            alpha(0), tint(0), flags(0), mask(0),
+            reserved(0)
+    {
+        matrix.dsdx = matrix.dtdy = 1.0f;
+        matrix.dsdy = matrix.dtdx = 0.0f;
+    }
+
+    status_t    write(Parcel& output) const;
+    status_t    read(const Parcel& input);
+
+            struct matrix22_t {
+                float   dsdx;
+                float   dtdx;
+                float   dsdy;
+                float   dtdy;
+            };
+            SurfaceID       surface;
+            uint32_t        what;
+            int32_t         x;
+            int32_t         y;
+            uint32_t        z;
+            uint32_t        w;
+            uint32_t        h;
+            float           alpha;
+            uint32_t        tint;
+            uint8_t         flags;
+            uint8_t         mask;
+            uint8_t         reserved;
+            matrix22_t      matrix;
+            // non POD must be last. see write/read
+            Region          transparentRegion;
+};
+
+}; // namespace android
+
+#endif // ANDROID_COMPOSER_LAYER_STATE_H
+
diff --git a/include/private/ui/SharedState.h b/include/private/ui/SharedState.h
new file mode 100644
index 0000000..546d0ad
--- /dev/null
+++ b/include/private/ui/SharedState.h
@@ -0,0 +1,168 @@
+/*
+ * 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_UI_SHARED_STATE_H
+#define ANDROID_UI_SHARED_STATE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+namespace android {
+
+/*
+ * These structures are shared between the composer process and its clients
+ */
+
+// ---------------------------------------------------------------------------
+
+struct surface_info_t { // 4 longs, 16 bytes
+    enum {
+        eBufferDirty    = 0x01
+    };
+    uint16_t    w;
+    uint16_t    h;
+    uint16_t    stride;
+    uint16_t    bpr;
+    uint16_t    reserved;
+    uint8_t     format;
+    uint8_t     flags;
+    ssize_t     bits_offset;
+};
+
+// ---------------------------------------------------------------------------
+
+const uint32_t NUM_LAYERS_MAX = 31;
+
+enum { // layer_cblk_t swapState
+    eIndex              = 0x00000001,
+    eFlipRequested      = 0x00000002,
+    
+    eResizeBuffer0      = 0x00000004,
+    eResizeBuffer1      = 0x00000008,    
+    eResizeRequested    = eResizeBuffer0 | eResizeBuffer1,
+    
+    eBusy               = 0x00000010,
+    eLocked             = 0x00000020,
+    eNextFlipPending    = 0x00000040,    
+    eInvalidSurface     = 0x00000080
+};
+
+enum { // layer_cblk_t flags
+    eLayerNotPosted     = 0x00000001,
+    eNoCopyBack         = 0x00000002,
+    eReserved           = 0x0000007C,
+    eBufferIndexShift   = 7,
+    eBufferIndex        = 1<<eBufferIndexShift,
+};
+
+struct flat_region_t    // 40 bytes
+{
+    int32_t     count;
+    int16_t     l;
+    int16_t     t;
+    int16_t     r;
+    int16_t     b;
+    uint16_t    runs[14];
+};
+
+struct layer_cblk_t     // (128 bytes)
+{
+    volatile    int32_t             swapState;      //  4
+    volatile    int32_t             flags;          //  4
+    volatile    int32_t             identity;       //  4
+                int32_t             reserved;       //  4
+                surface_info_t      surface[2];     // 32
+                flat_region_t       region[2];      // 80
+
+    static inline int backBuffer(uint32_t state) {
+        return ((state & eIndex) ^ ((state & eFlipRequested)>>1));
+    }
+    static inline int frontBuffer(uint32_t state) {
+        return 1 - backBuffer(state);
+    }
+};
+
+// ---------------------------------------------------------------------------
+
+struct per_client_cblk_t   // 4KB max
+{
+                Mutex           lock;
+                Condition       cv;
+                layer_cblk_t    layers[NUM_LAYERS_MAX] __attribute__((aligned(32)));
+
+    enum {
+        BLOCKING = 0x00000001,
+        INSPECT  = 0x00000002
+    };
+
+    per_client_cblk_t();
+
+    // these functions are used by the clients
+    status_t validate(size_t i) const;
+    int32_t lock_layer(size_t i, uint32_t flags);
+    uint32_t unlock_layer_and_post(size_t i);
+    void unlock_layer(size_t i);
+};
+// ---------------------------------------------------------------------------
+
+const uint32_t NUM_DISPLAY_MAX = 4;
+
+struct display_cblk_t
+{
+    uint16_t    w;
+    uint16_t    h;
+    uint8_t     format;
+    uint8_t     orientation;
+    uint8_t     reserved[2];
+    float       fps;
+    float       density;
+    float       xdpi;
+    float       ydpi;
+    uint32_t    pad[2];
+};
+
+struct surface_flinger_cblk_t   // 4KB max
+{
+    surface_flinger_cblk_t();
+    
+    uint8_t         connected;
+    uint8_t         reserved[3];
+    uint32_t        pad[7];
+ 
+    display_cblk_t  displays[NUM_DISPLAY_MAX];
+};
+
+// ---------------------------------------------------------------------------
+
+template<bool> struct CTA;
+template<> struct CTA<true> { };
+
+// compile-time assertions. just to avoid catastrophes.
+inline void compile_time_asserts() {
+    CTA<sizeof(layer_cblk_t) == 128> sizeof__layer_cblk_t__eq_128;
+    (void)sizeof__layer_cblk_t__eq_128; // we don't want a warning
+    CTA<sizeof(per_client_cblk_t) <= 4096> sizeof__per_client_cblk_t__le_4096;
+    (void)sizeof__per_client_cblk_t__le_4096;  // we don't want a warning
+    CTA<sizeof(surface_flinger_cblk_t) <= 4096> sizeof__surface_flinger_cblk_t__le_4096;
+    (void)sizeof__surface_flinger_cblk_t__le_4096;  // we don't want a warning
+}
+
+}; // namespace android
+
+#endif // ANDROID_UI_SHARED_STATE_H
+
diff --git a/include/private/ui/SurfaceFlingerSynchro.h b/include/private/ui/SurfaceFlingerSynchro.h
new file mode 100644
index 0000000..ff91b61
--- /dev/null
+++ b/include/private/ui/SurfaceFlingerSynchro.h
@@ -0,0 +1,76 @@
+/*
+ * 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_SURFACE_FLINGER_SYNCHRO_H
+#define ANDROID_SURFACE_FLINGER_SYNCHRO_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <ui/ISurfaceComposer.h>
+
+namespace android {
+
+class SurfaceFlinger;
+
+class SurfaceFlingerSynchro
+{
+public:
+
+                // client constructor
+                SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger);
+                ~SurfaceFlingerSynchro();
+    
+                // signal surfaceflinger for some work
+    status_t    signal();
+    
+private:
+    class Barrier {
+    public:
+        Barrier();
+        ~Barrier();
+        void open();
+        void close();
+        void waitAndClose();
+        status_t waitAndClose(nsecs_t timeout);
+    private:
+        enum { OPENED, CLOSED };
+        mutable     Mutex       lock;
+        mutable     Condition   cv;
+        volatile    int         state;
+    };
+
+    friend class SurfaceFlinger;
+
+                // server constructor
+                SurfaceFlingerSynchro();
+                
+    void        open();
+    
+                // wait until there is some work to do
+    status_t    wait();
+    status_t    wait(nsecs_t timeout);
+    
+    sp<ISurfaceComposer> mSurfaceComposer;
+    Barrier              mBarrier;
+};
+
+}; // namespace android
+
+#endif // ANDROID_SURFACE_FLINGER_SYNCHRO_H
+
diff --git a/include/private/utils/Static.h b/include/private/utils/Static.h
new file mode 100644
index 0000000..f1439b7
--- /dev/null
+++ b/include/private/utils/Static.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+// All static variables go here, to control initialization and
+// destruction order in the library.
+
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
+
+#ifndef LIBUTILS_NATIVE
+#include <utils/IBinder.h>
+#include <utils/IMemory.h>
+#include <utils/ProcessState.h>
+#include <utils/IPermissionController.h>
+#include <utils/IServiceManager.h>
+#endif
+
+namespace android {
+// For TextStream.cpp
+extern Vector<int32_t> gTextBuffers;
+
+// For String8.cpp
+extern void initialize_string8();
+extern void terminate_string8();
+
+// For String16.cpp
+extern void initialize_string16();
+extern void terminate_string16();
+
+
+
+#ifndef LIBUTILS_NATIVE
+
+// For ProcessState.cpp
+extern Mutex gProcessMutex;
+extern sp<ProcessState> gProcess;
+
+// For ServiceManager.cpp
+extern Mutex gDefaultServiceManagerLock;
+extern sp<IServiceManager> gDefaultServiceManager;
+extern sp<IPermissionController> gPermissionController;
+
+#endif
+
+}   // namespace android
diff --git a/include/private/utils/binder_module.h b/include/private/utils/binder_module.h
new file mode 100644
index 0000000..fdf327e
--- /dev/null
+++ b/include/private/utils/binder_module.h
@@ -0,0 +1,148 @@
+/*
+ * 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 _BINDER_MODULE_H_
+#define _BINDER_MODULE_H_
+
+#ifdef __cplusplus
+namespace android {
+#endif
+
+#if defined(HAVE_ANDROID_OS)
+
+/* obtain structures and constants from the kernel header */
+
+#include <sys/ioctl.h>
+#include <linux/binder.h>
+
+#else
+
+/* Some parts of the simulator need fake versions of this 
+ * stuff in order to compile.  Really this should go away
+ * entirely...
+ */
+
+#define BINDER_CURRENT_PROTOCOL_VERSION 7
+
+#define BINDER_TYPE_BINDER 1
+#define BINDER_TYPE_WEAK_BINDER 2
+#define BINDER_TYPE_HANDLE 3
+#define BINDER_TYPE_WEAK_HANDLE 4
+#define BINDER_TYPE_FD 5
+
+struct flat_binder_object {
+    unsigned long type;
+    unsigned long flags;
+    union {
+        void *binder;
+        signed long handle;
+    };
+    void *cookie;
+};
+
+struct binder_write_read {
+    signed long write_size;
+    signed long write_consumed;
+    unsigned long write_buffer;
+    signed long read_size;
+    signed long read_consumed;
+    unsigned long read_buffer;
+};
+
+struct binder_transaction_data {
+    union {
+        size_t handle;
+        void *ptr;
+    } target;
+    void *cookie;
+    unsigned int code;
+    
+    unsigned int flags;
+    pid_t sender_pid;
+    uid_t sender_euid;
+    size_t data_size;
+    size_t offsets_size;
+    
+    union {
+        struct {
+            const void *buffer;
+            const void *offsets;
+        } ptr;
+        uint8_t buf[8];
+    } data;
+};
+
+enum transaction_flags {
+    TF_ONE_WAY = 0x01,
+    TF_ROOT_OBJECT = 0x04,
+    TF_STATUS_CODE = 0x08,
+    TF_ACCEPT_FDS = 0x10,
+};
+
+
+enum {
+    FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
+    FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
+};
+
+enum BinderDriverReturnProtocol {
+    BR_ERROR,
+    BR_OK,
+    BR_TRANSACTION,
+    BR_REPLY,
+    BR_ACQUIRE_RESULT,
+    BR_DEAD_REPLY,
+    BR_TRANSACTION_COMPLETE,
+    BR_INCREFS,
+    BR_ACQUIRE,
+    BR_RELEASE,
+    BR_DECREFS,
+    BR_ATTEMPT_ACQUIRE,
+    BR_NOOP,
+    BR_SPAWN_LOOPER,
+    BR_FINISHED,
+    BR_DEAD_BINDER,
+    BR_CLEAR_DEATH_NOTIFICATION_DONE,
+    BR_FAILED_REPLY,
+};
+
+enum BinderDriverCommandProtocol {
+    BC_TRANSACTION,
+    BC_REPLY,
+    BC_ACQUIRE_RESULT,
+    BC_FREE_BUFFER,
+    BC_INCREFS,
+    BC_ACQUIRE,
+    BC_RELEASE,
+    BC_DECREFS,
+    BC_INCREFS_DONE,
+    BC_ACQUIRE_DONE,
+    BC_ATTEMPT_ACQUIRE,
+    BC_REGISTER_LOOPER,
+    BC_ENTER_LOOPER,
+    BC_EXIT_LOOPER,
+    BC_REQUEST_DEATH_NOTIFICATION,
+    BC_CLEAR_DEATH_NOTIFICATION,
+    BC_DEAD_BINDER_DONE,
+};
+
+#endif
+
+#ifdef __cplusplus
+}   // namespace android
+#endif
+
+#endif // _BINDER_MODULE_H_
diff --git a/include/private/utils/futex_synchro.h b/include/private/utils/futex_synchro.h
new file mode 100644
index 0000000..ac2ab19
--- /dev/null
+++ b/include/private/utils/futex_synchro.h
@@ -0,0 +1,60 @@
+/*
+ * 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 _FUTEX_SYNCHRO_H
+#define _FUTEX_SYNCHRO_H
+
+#ifndef HAVE_FUTEX
+#error "HAVE_FUTEX not defined"
+#endif
+
+#define FUTEX_WAIT_INFINITE (0)
+
+typedef struct futex_mutex_t futex_mutex_t;
+
+struct futex_mutex_t 
+{
+    volatile int value;
+};
+
+typedef struct futex_cond_t futex_cond_t;
+
+struct futex_cond_t 
+{
+    volatile int value;
+};
+
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void futex_mutex_init(futex_mutex_t *m);
+int futex_mutex_lock(futex_mutex_t *m, unsigned msec);
+void futex_mutex_unlock(futex_mutex_t *m);
+int futex_mutex_trylock(futex_mutex_t *m);
+
+void futex_cond_init(futex_cond_t *c);
+int futex_cond_wait(futex_cond_t *c, futex_mutex_t *m, unsigned msec);
+void futex_cond_signal(futex_cond_t *c);
+void futex_cond_broadcast(futex_cond_t *c);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FUTEX_SYNCHRO_H
+
diff --git a/include/ui/BlitHardware.h b/include/ui/BlitHardware.h
new file mode 100644
index 0000000..4de1c12
--- /dev/null
+++ b/include/ui/BlitHardware.h
@@ -0,0 +1,143 @@
+/*
+ * 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_BLIT_HARDWARE_H
+#define ANDROID_BLIT_HARDWARE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************/
+
+/* supported pixel-formats. these must be compatible with
+ * graphics/PixelFormat.java, ui/PixelFormat.h, pixelflinger/format.h
+ */
+
+enum
+{
+    COPYBIT_RGBA_8888    = 1,
+    COPYBIT_RGB_565      = 4,
+    COPYBIT_RGBA_5551    = 6,
+    COPYBIT_RGBA_4444    = 7,
+    COPYBIT_YCbCr_422_SP = 0x10,
+    COPYBIT_YCbCr_420_SP = 0x11
+};
+
+/* name for copybit_set_parameter */
+enum 
+{
+    /* rotation of the source image in degrees (0 to 359) */
+    COPYBIT_ROTATION_DEG    = 1,
+    /* plane alpha value */
+    COPYBIT_PLANE_ALPHA     = 2,
+    /* enable or disable dithering */
+    COPYBIT_DITHER          = 3,
+    /* transformation applied (this is a superset of COPYBIT_ROTATION_DEG) */
+    COPYBIT_TRANSFORM       = 4,
+};
+
+/* values for copybit_set_parameter(COPYBIT_TRANSFORM) */
+enum {
+    /* flip source image horizontally */
+    COPYBIT_TRANSFORM_FLIP_H    = 0x01,
+    /* flip source image vertically */
+    COPYBIT_TRANSFORM_FLIP_V    = 0x02,
+    /* rotate source image 90 degres */
+    COPYBIT_TRANSFORM_ROT_90    = 0x04,
+    /* rotate source image 180 degres */
+    COPYBIT_TRANSFORM_ROT_180   = 0x03,
+    /* rotate source image 270 degres */
+    COPYBIT_TRANSFORM_ROT_270   = 0x07,
+};
+
+/* enable/disable value copybit_set_parameter */
+enum {
+    COPYBIT_DISABLE = 0,
+    COPYBIT_ENABLE  = 1
+};
+
+/* use get() to query static informations about the hardware */
+enum {
+    /* Maximum amount of minification supported by the hardware*/
+    COPYBIT_MINIFICATION_LIMIT  = 1,
+    /* Maximum amount of magnification supported by the hardware */
+    COPYBIT_MAGNIFICATION_LIMIT = 2,
+    /* Number of fractional bits support by the scaling engine */
+    COPYBIT_SCALING_FRAC_BITS   = 3,
+    /* Supported rotation step in degres. */
+    COPYBIT_ROTATION_STEP_DEG   = 4,
+};
+
+struct copybit_image_t {
+    uint32_t    w;
+    uint32_t    h;
+    int32_t     format;
+    uint32_t    offset;
+    void*       base;
+    int         fd;
+};
+
+
+struct copybit_rect_t {
+    int l;
+    int t;
+    int r;
+    int b;
+};
+
+struct copybit_region_t {
+    int (*next)(copybit_region_t const*, copybit_rect_t* rect); 
+};
+
+struct copybit_t
+{
+    int (*set_parameter)(struct copybit_t* handle, int name, int value);
+
+    int (*get)(struct copybit_t* handle, int name);
+    
+    int (*blit)(
+            struct copybit_t* handle, 
+            struct copybit_image_t const* dst, 
+            struct copybit_image_t const* src,
+            struct copybit_region_t const* region);
+
+    int (*stretch)(
+            struct copybit_t* handle, 
+            struct copybit_image_t const* dst, 
+            struct copybit_image_t const* src, 
+            struct copybit_rect_t const* dst_rect,
+            struct copybit_rect_t const* src_rect,
+            struct copybit_region_t const* region);
+};
+
+/******************************************************************************/
+
+struct copybit_t* copybit_init();
+
+int copybit_term(struct copybit_t* handle);
+
+
+/******************************************************************************/
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_BLIT_HARDWARE_H
diff --git a/include/ui/Camera.h b/include/ui/Camera.h
new file mode 100644
index 0000000..562a0a2
--- /dev/null
+++ b/include/ui/Camera.h
@@ -0,0 +1,125 @@
+/*
+ * 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_HARDWARE_CAMERA_H
+#define ANDROID_HARDWARE_CAMERA_H
+
+#include <ui/ICameraClient.h>
+
+namespace android {
+
+class ICameraService;
+class ICamera;
+class Surface;
+class Mutex;
+class String8;
+
+typedef void (*shutter_callback)(void *cookie);
+typedef void (*frame_callback)(const sp<IMemory>& mem, void *cookie);
+typedef void (*autofocus_callback)(bool focused, void *cookie);
+typedef void (*error_callback)(status_t err, void *cookie);
+
+class Camera : public BnCameraClient, public IBinder::DeathRecipient
+{
+public:
+    static  sp<Camera>  connect();
+                        ~Camera();
+
+            void        disconnect();
+
+            status_t    getStatus() { return mStatus; }
+
+            // pass the buffered ISurface to the camera service
+            status_t    setPreviewDisplay(const sp<Surface>& surface);
+
+            // start preview mode, must call setPreviewDisplay first
+            status_t    startPreview();
+
+            // stop preview mode
+            void        stopPreview();
+
+            // autoFocus - status returned from callback
+            status_t    autoFocus();
+
+            // take a picture - picture returned from callback
+            status_t    takePicture();
+
+            // set preview/capture parameters - key/value pairs
+            status_t    setParameters(const String8& params);
+
+            // get preview/capture parameters - key/value pairs
+            String8     getParameters() const;
+
+            void        setShutterCallback(shutter_callback cb, void *cookie);
+            void        setRawCallback(frame_callback cb, void *cookie);
+            void        setJpegCallback(frame_callback cb, void *cookie);
+            void        setFrameCallback(frame_callback cb, void *cookie);
+            void        setErrorCallback(error_callback cb, void *cookie);
+            void        setAutoFocusCallback(autofocus_callback cb, void *cookie);
+    // ICameraClient interface
+    virtual void        shutterCallback();
+    virtual void        rawCallback(const sp<IMemory>& picture);
+    virtual void        jpegCallback(const sp<IMemory>& picture);
+    virtual void        frameCallback(const sp<IMemory>& frame);
+    virtual void        errorCallback(status_t error);
+    virtual void        autoFocusCallback(bool focused);
+
+    
+private:
+                        Camera();
+                        virtual void binderDied(const wp<IBinder>& who);
+
+            class DeathNotifier: public IBinder::DeathRecipient
+            {
+            public:
+                DeathNotifier() {      
+                }
+                
+                virtual void binderDied(const wp<IBinder>& who);
+            };
+        
+            static sp<DeathNotifier> mDeathNotifier;
+        
+            // helper function to obtain camera service handle
+            static const sp<ICameraService>& getCameraService();
+
+            sp<ICamera>         mCamera;
+            status_t            mStatus;
+
+            shutter_callback    mShutterCallback;
+            void                *mShutterCallbackCookie;
+            frame_callback      mRawCallback;
+            void                *mRawCallbackCookie;
+            frame_callback      mJpegCallback;
+            void                *mJpegCallbackCookie;
+            frame_callback      mFrameCallback;
+            void                *mFrameCallbackCookie;
+            error_callback      mErrorCallback;
+            void                *mErrorCallbackCookie;
+            autofocus_callback  mAutoFocusCallback;
+            void                *mAutoFocusCallbackCookie;
+            
+            friend class DeathNotifier;
+
+            static  Mutex               mLock;
+            static  sp<ICameraService>  mCameraService;
+            
+};
+
+}; // namespace android
+
+#endif
+
diff --git a/include/ui/CameraHardwareInterface.h b/include/ui/CameraHardwareInterface.h
new file mode 100644
index 0000000..5fa933f
--- /dev/null
+++ b/include/ui/CameraHardwareInterface.h
@@ -0,0 +1,156 @@
+/*
+ * 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_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
+#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
+
+#include <utils/IMemory.h>
+#include <utils/RefBase.h>
+#include <ui/CameraParameters.h>
+
+namespace android {
+
+/** Callback for startPreview() */
+typedef void (*preview_callback)(const sp<IMemory>& mem, void* user);
+
+/** Callback for takePicture() */
+typedef void (*shutter_callback)(void* user);
+
+/** Callback for takePicture() */
+typedef void (*raw_callback)(const sp<IMemory>& mem, void* user);
+
+/** Callback for takePicture() */
+typedef void (*jpeg_callback)(const sp<IMemory>& mem, void* user);
+
+/** Callback for autoFocus() */
+typedef void (*autofocus_callback)(bool focused, void* user);
+
+/**
+ * This defines the interface to the camera hardware abstraction
+ * layer. It supports setting and getting parameters, live
+ * previewing and taking pictures. It is a referenced counted
+ * interface with RefBase as its base class.
+ *
+ * The openCameraHardware function is used to
+ * retrieve a strong pointer to the instance of this interface
+ * and may be called multiple times.
+ *
+ * After calling openCameraHardware the getParameters and
+ * setParameters are used to initialize the camera instance.
+ *
+ * Then getPreviewHeap is called to get access to the preview
+ * heap so it can be registered with the SurfaceFlinger for efficient
+ * display updating while in the preview mode.
+ *
+ * Next startPreview is called which is passed a preview_callback
+ * function and a user parameter. The camera instance then
+ * periodically calls preview_callback each time a new
+ * preview frame is available. The call back routine has
+ * two parameters, the first is a pointer to the the IMemory containing
+ * the frame and the other is the user parameter. If the preview_callback
+ * code needs to use this memory after returning it must copy
+ * the data.
+ *
+ * Prior to taking a picture the autoFocus method is usually called with a
+ * autofocus_callback and a user parameter. When auto focusing
+ * has completed the camera instance calls autofocus_callback which
+ * informs the application if focusing was successful or not.
+ * The camera instance only calls the autofocus_callback once and it
+ * is up to the application to call autoFocus again if refocusing is desired.
+ *
+ * The method takePicture is called to request that the camera instance take a
+ * picture. This method has three callbacks: shutter_callback, raw_callback,
+ * and jpeg_callback. As soon as the shutter snaps and it is safe to move the
+ * camera, shutter_callback is called.  Typically, you would want to play the
+ * shutter sound at this moment. Later, when the raw image is available the
+ * raw_callback is called with a pointer to the IMemory containing the raw
+ * image.  Finally, when the encoded jpeg image is available the jpeg_callback
+ * will be called with a pointer to the IMemory containing the jpeg image.  As
+ * with the preview_callback the memory must be copied if it's needed after
+ * returning.
+ */
+class CameraHardwareInterface : public virtual RefBase {
+public:
+    virtual ~CameraHardwareInterface() { }
+
+    /** Return the IMemoryHeap for the preview image heap */
+    virtual sp<IMemoryHeap>         getPreviewHeap() const = 0;
+
+    /**
+     * Start preview mode. When a preview image is available
+     * preview_callback is called with the user parameter. The
+     * call back parameter may be null.
+     */
+    virtual status_t    startPreview(preview_callback cb, void* user) = 0;
+
+    /**
+     * Stop a previously started preview.
+     */
+    virtual void        stopPreview() = 0;
+
+    /**
+     * Start auto focus, the callback routine is called
+     * once when focusing is complete. autoFocus() will
+     * be called agained if another auto focus is needed.
+     */
+    virtual status_t    autoFocus(autofocus_callback,
+                                  void* user) = 0;
+
+    /**
+     * Take a picture. The raw_callback is called when
+     * the uncompressed image is available. The jpeg_callback
+     * is called when the compressed image is available. These
+     * call backs may be null. The user parameter is passed
+     * to each of the call back routines.
+     */
+    virtual status_t    takePicture(shutter_callback,
+                                    raw_callback,
+                                    jpeg_callback,
+                                    void* user) = 0;
+
+    /**
+     * Cancel a picture that was started with takePicture.  You may cancel any
+     * of the shutter, raw, or jpeg callbacks.  Calling this method when no
+     * picture is being taken is a no-op.
+     */
+    virtual status_t    cancelPicture(bool cancel_shutter,
+                                      bool cancel_raw,
+                                      bool cancel_jpeg) = 0;
+
+    /** Set the camera parameters. */
+    virtual status_t    setParameters(const CameraParameters& params) = 0;
+
+    /** Return the camera parameters. */
+    virtual CameraParameters  getParameters() const = 0;
+
+    /**
+     * Release the hardware resources owned by this object.  Note that this is
+     * *not* done in the destructor.
+     */
+    virtual void release() = 0;
+    
+    /**
+     * Dump state of the camera hardware
+     */
+    virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
+};
+
+/** factory function to instantiate a camera hardware object */
+extern "C" sp<CameraHardwareInterface> openCameraHardware();
+
+};  // namespace android
+
+#endif
diff --git a/include/ui/CameraParameters.h b/include/ui/CameraParameters.h
new file mode 100644
index 0000000..e35a054
--- /dev/null
+++ b/include/ui/CameraParameters.h
@@ -0,0 +1,70 @@
+/*
+ * 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_HARDWARE_CAMERA_PARAMETERS_H
+#define ANDROID_HARDWARE_CAMERA_PARAMETERS_H
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class CameraParameters
+{
+public:
+    CameraParameters();
+    CameraParameters(const String8 &params) { unflatten(params); }
+    ~CameraParameters();
+
+    String8 flatten() const;
+    void unflatten(const String8 &params);
+
+    void set(const char *key, const char *value);
+    void set(const char *key, int value);
+    const char *get(const char *key) const;
+    int getInt(const char *key) const;
+
+    /* preview-size=176x144 */
+    void setPreviewSize(int width, int height);
+    void getPreviewSize(int *width, int *height) const;
+
+    /* preview-fps=15 */
+    void setPreviewFrameRate(int fps);
+    int getPreviewFrameRate() const;
+
+    /* preview-format=rgb565|yuv422 */
+    void setPreviewFormat(const char *format);
+    const char *getPreviewFormat() const;
+
+    /* picture-size=1024x768 */
+    void setPictureSize(int width, int height);
+    void getPictureSize(int *width, int *height) const;
+
+    /* picture-format=yuv422|jpeg */
+    void setPictureFormat(const char *format);
+    const char *getPictureFormat() const;
+
+    void dump() const;
+    status_t dump(int fd, const Vector<String16>& args) const;
+
+private:
+    DefaultKeyedVector<String8,String8>    mMap;
+};
+
+
+}; // namespace android
+
+#endif
diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h
new file mode 100644
index 0000000..c419efe
--- /dev/null
+++ b/include/ui/DisplayInfo.h
@@ -0,0 +1,43 @@
+/*
+ * 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_UI_DISPLAY_INFO_H
+#define ANDROID_UI_DISPLAY_INFO_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/PixelFormat.h>
+
+namespace android {
+
+struct DisplayInfo {
+    uint32_t            w;
+    uint32_t            h;
+    PixelFormatInfo     pixelFormatInfo;
+    uint8_t             orientation;
+    uint8_t             reserved[3];
+    float               fps;
+    float               density;
+    float               xdpi;
+    float               ydpi;
+};
+
+}; // namespace android
+
+#endif // ANDROID_COMPOSER_DISPLAY_INFO_H
+
diff --git a/include/ui/EGLDisplaySurface.h b/include/ui/EGLDisplaySurface.h
new file mode 100644
index 0000000..a9cfd5a
--- /dev/null
+++ b/include/ui/EGLDisplaySurface.h
@@ -0,0 +1,82 @@
+/*
+ * 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_EGL_DISPLAY_SURFACE_H
+#define ANDROID_EGL_DISPLAY_SURFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Timers.h>
+
+#include <ui/EGLNativeSurface.h>
+#include <ui/BlitHardware.h>
+
+#include <pixelflinger/pixelflinger.h>
+#include <linux/fb.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Region;
+class Rect;
+
+class EGLDisplaySurface : public EGLNativeSurface<EGLDisplaySurface>
+{
+public:
+    EGLDisplaySurface();
+    ~EGLDisplaySurface();
+    
+    int32_t getPageFlipCount() const;
+    void    copyFrontToBack(const Region& copyback);
+    
+private:
+    static void         hook_incRef(NativeWindowType window);
+    static void         hook_decRef(NativeWindowType window);
+    static uint32_t     hook_swapBuffers(NativeWindowType window);
+    static void         hook_setSwapRectangle(NativeWindowType window, int l, int t, int w, int h);
+    static uint32_t     hook_nextBuffer(NativeWindowType window);
+     
+            uint32_t    swapBuffers();
+            uint32_t    nextBuffer();
+            void        setSwapRectangle(int l, int t, int w, int h);
+
+            status_t    mapFrameBuffer();
+
+            enum {
+                PAGE_FLIP = 0x00000001
+            };
+    GGLSurface          mFb[2];
+    int                 mIndex;
+    uint32_t            mFlags;
+    size_t              mSize;
+    fb_var_screeninfo   mInfo;
+    fb_fix_screeninfo   mFinfo;
+    int32_t             mPageFlipCount;
+    nsecs_t             mTime;
+    int32_t             mSwapCount;
+    nsecs_t             mSleep;
+    uint32_t            mFeatureFlags;
+    copybit_t*          mBlitEngine;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_EGL_DISPLAY_SURFACE_H
+
diff --git a/include/ui/EGLNativeSurface.h b/include/ui/EGLNativeSurface.h
new file mode 100644
index 0000000..7c9ce99
--- /dev/null
+++ b/include/ui/EGLNativeSurface.h
@@ -0,0 +1,64 @@
+/*
+ * 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_EGL_NATIVE_SURFACE_H
+#define ANDROID_EGL_NATIVE_SURFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/atomic.h>
+#include <utils/RefBase.h>
+
+#include <GLES/eglnatives.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+template <class TYPE>
+class EGLNativeSurface : public egl_native_window_t
+{
+public:
+    EGLNativeSurface() : mCount(0) { 
+        memset(egl_native_window_t::reserved, 0, 
+                sizeof(egl_native_window_t::reserved));
+        memset(egl_native_window_t::reserved_proc, 0, 
+                sizeof(egl_native_window_t::reserved_proc));
+        memset(egl_native_window_t::oem, 0, 
+                sizeof(egl_native_window_t::oem));
+    }
+    inline void incStrong(void*) const {
+        android_atomic_inc(&mCount);
+    }
+    inline void decStrong(void*) const {
+        if (android_atomic_dec(&mCount) == 1) {
+             delete static_cast<const TYPE*>(this);
+         }
+    }
+protected:
+    EGLNativeSurface& operator = (const EGLNativeSurface& rhs);
+    EGLNativeSurface(const EGLNativeSurface& rhs);
+    inline ~EGLNativeSurface() { };
+    mutable volatile int32_t mCount;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_EGL_SURFACE_H
+
diff --git a/include/ui/EGLNativeWindowSurface.h b/include/ui/EGLNativeWindowSurface.h
new file mode 100644
index 0000000..058479a
--- /dev/null
+++ b/include/ui/EGLNativeWindowSurface.h
@@ -0,0 +1,60 @@
+/*
+ * 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_EGL_NATIVE_WINDOW_SURFACE_H
+#define ANDROID_EGL_NATIVE_WINDOW_SURFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <ui/EGLNativeSurface.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Surface;
+
+class EGLNativeWindowSurface : public EGLNativeSurface<EGLNativeWindowSurface>
+{
+public:
+    EGLNativeWindowSurface(const sp<Surface>& surface);
+    ~EGLNativeWindowSurface();
+
+private:
+    static void         hook_incRef(NativeWindowType window);
+    static void         hook_decRef(NativeWindowType window);
+    static uint32_t     hook_swapBuffers(NativeWindowType window);
+    static uint32_t     hook_nextBuffer(NativeWindowType window);
+    static void         hook_setSwapRectangle(NativeWindowType window, int l, int t, int w, int h);
+    static void         hook_connect(NativeWindowType window);
+    static void         hook_disconnect(NativeWindowType window);
+
+            uint32_t    swapBuffers();
+            uint32_t    nextBuffer();
+            void        setSwapRectangle(int l, int t, int w, int h);
+            void        connect();
+            void        disconnect();
+            
+            sp<Surface> mSurface;
+            bool        mConnected;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_EGL_NATIVE_WINDOW_SURFACE_H
+
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
new file mode 100644
index 0000000..101a920
--- /dev/null
+++ b/include/ui/EventHub.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _RUNTIME_EVENT_HUB_H
+#define _RUNTIME_EVENT_HUB_H
+
+#include <utils/String8.h>
+#include <utils/threads.h>
+#include <utils.h>
+
+#include <linux/input.h>
+
+struct pollfd;
+
+namespace android {
+
+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().
+ */
+class EventHub : public RefBase
+{
+public:
+    EventHub();
+    
+    status_t errorCheck() const;
+    
+    // bit fields for classes of devices.
+    enum {
+        CLASS_KEYBOARD      = 0x00000001,
+        CLASS_TOUCHSCREEN   = 0x00000002,
+        CLASS_TRACKBALL     = 0x00000004
+    };
+    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;
+    
+    // special type codes when devices are added/removed.
+    enum {
+        DEVICE_ADDED = 0x10000000,
+        DEVICE_REMOVED = 0x20000000
+    };
+    
+    virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
+            int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
+            int32_t* outValue, nsecs_t* outWhen);
+    
+protected:
+    virtual ~EventHub();
+    virtual void onFirstRef();
+    
+private:
+    bool openPlatformInput(void);
+    int32_t convertDeviceKey_TI_P2(int code);
+
+    int open_device(const char *device);
+    int close_device(const char *device);
+    int scan_dir(const char *dirname);
+    int read_notify(int nfd);
+
+    status_t mError;
+
+    struct device_t {
+        const int32_t   id;
+        const String8   path;
+        String8         name;
+        uint32_t        classes;
+        KeyLayoutMap*   layoutMap;
+        String8         keylayoutFilename;
+        device_t*       next;
+        
+        device_t(int32_t _id, const char* _path);
+        ~device_t();
+    };
+
+    device_t* getDevice(int32_t deviceId) const;
+    
+    // Protect all internal state.
+    mutable Mutex   mLock;
+    
+    bool            mHaveFirstKeyboard;
+    int32_t         mFirstKeyboardId; // the API is that the build in keyboard is id 0, so map it
+    
+    struct device_ent {
+        device_t* device;
+        uint32_t seq;
+    };
+    device_ent      *mDevicesById;
+    int             mNumDevicesById;
+    
+    device_t        *mOpeningDevices;
+    device_t        *mClosingDevices;
+    
+    device_t        **mDevices;
+    struct pollfd   *mFDs;
+    int             mFDCount;
+    
+    // device ids that report particular switches.
+#ifdef EV_SW
+    int32_t         mSwitches[SW_MAX+1];
+#endif
+
+    KeyLayoutMap * mLayoutMap;
+};
+
+}; // namespace android
+
+#endif // _RUNTIME_EVENT_HUB_H
diff --git a/include/ui/ICamera.h b/include/ui/ICamera.h
new file mode 100644
index 0000000..6aa3940
--- /dev/null
+++ b/include/ui/ICamera.h
@@ -0,0 +1,75 @@
+/*
+ * 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_HARDWARE_ICAMERA_H
+#define ANDROID_HARDWARE_ICAMERA_H
+
+#include <utils/RefBase.h>
+#include <utils/IInterface.h>
+#include <utils/Parcel.h>
+
+#include <ui/ISurface.h>
+#include <utils/IMemory.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class ICamera: public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(Camera);
+
+    virtual void            disconnect() = 0;
+
+    // pass the buffered ISurface to the camera service
+    virtual status_t        setPreviewDisplay(const sp<ISurface>& surface) = 0;
+    
+    // tell the service whether to callback with each preview frame
+    virtual void            setHasFrameCallback(bool installed) = 0;
+
+    // start preview mode, must call setPreviewDisplay first
+    virtual status_t        startPreview() = 0;
+
+    // stop preview mode
+    virtual void            stopPreview() = 0;
+
+    // auto focus
+    virtual status_t        autoFocus() = 0;
+
+    // take a picture
+    virtual status_t        takePicture() = 0;
+
+    // set preview/capture parameters - key/value pairs
+    virtual status_t        setParameters(const String8& params) = 0;
+
+    // get preview/capture parameters - key/value pairs
+    virtual String8         getParameters() const = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnCamera: public BnInterface<ICamera>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/ui/ICameraClient.h b/include/ui/ICameraClient.h
new file mode 100644
index 0000000..a286b8e
--- /dev/null
+++ b/include/ui/ICameraClient.h
@@ -0,0 +1,54 @@
+/*
+ * 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_HARDWARE_ICAMERA_APP_H
+#define ANDROID_HARDWARE_ICAMERA_APP_H
+
+#include <utils/RefBase.h>
+#include <utils/IInterface.h>
+#include <utils/Parcel.h>
+#include <utils/IMemory.h>
+
+namespace android {
+
+class ICameraClient: public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(CameraClient);
+
+    virtual void            shutterCallback() = 0;
+    virtual void            rawCallback(const sp<IMemory>& picture) = 0;
+    virtual void            jpegCallback(const sp<IMemory>& picture) = 0;
+    virtual void            frameCallback(const sp<IMemory>& frame) = 0;
+    virtual void            errorCallback(status_t error) = 0;
+    virtual void            autoFocusCallback(bool focused) = 0;
+
+};
+
+// ----------------------------------------------------------------------------
+
+class BnCameraClient: public BnInterface<ICameraClient>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/ui/ICameraService.h b/include/ui/ICameraService.h
new file mode 100644
index 0000000..dfd8923
--- /dev/null
+++ b/include/ui/ICameraService.h
@@ -0,0 +1,55 @@
+/*
+ * 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_HARDWARE_ICAMERASERVICE_H
+#define ANDROID_HARDWARE_ICAMERASERVICE_H
+
+#include <utils/RefBase.h>
+#include <utils/IInterface.h>
+#include <utils/Parcel.h>
+
+#include <ui/ICameraClient.h>
+#include <ui/ICamera.h>
+
+namespace android {
+
+class ICameraService : public IInterface
+{
+protected:
+    enum {
+        CONNECT = IBinder::FIRST_CALL_TRANSACTION,
+    };
+
+public:
+    DECLARE_META_INTERFACE(CameraService);
+
+    virtual sp<ICamera>     connect(const sp<ICameraClient>& cameraClient) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnCameraService: public BnInterface<ICameraService>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h
new file mode 100644
index 0000000..ca691f5
--- /dev/null
+++ b/include/ui/ISurface.h
@@ -0,0 +1,62 @@
+/*
+ * 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_ISURFACE_H
+#define ANDROID_ISURFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/IInterface.h>
+#include <utils/RefBase.h>
+#include <ui/PixelFormat.h>
+
+namespace android {
+
+typedef int32_t    SurfaceID;
+
+class IMemoryHeap;
+
+class ISurface : public IInterface
+{
+public: 
+    DECLARE_META_INTERFACE(Surface);
+
+    virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
+            PixelFormat format, const sp<IMemoryHeap>& heap) = 0;
+
+    virtual void postBuffer(ssize_t offset) = 0; // one-way
+
+    virtual void unregisterBuffers() = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSurface : public BnInterface<ISurface>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_ISURFACE_H
diff --git a/include/ui/ISurfaceComposer.h b/include/ui/ISurfaceComposer.h
new file mode 100644
index 0000000..f9eeb30
--- /dev/null
+++ b/include/ui/ISurfaceComposer.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_ISURFACE_COMPOSER_H
+#define ANDROID_ISURFACE_COMPOSER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <utils/IInterface.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/ISurfaceFlingerClient.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class DisplayInfo;
+class IGPUCallback;
+
+class ISurfaceComposer : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(SurfaceComposer);
+
+    enum { // (keep in sync with Surface.java)
+        eHidden             = 0x00000004,
+        eGPU                = 0x00000008,
+        eHardware           = 0x00000010,
+        eDestroyBackbuffer  = 0x00000020,
+        eSecure             = 0x00000080,
+        eNonPremultiplied   = 0x00000100,
+        ePushBuffers        = 0x00000200,
+
+        eFXSurfaceNormal    = 0x00000000,
+        eFXSurfaceBlur      = 0x00010000,
+        eFXSurfaceDim       = 0x00020000,
+        eFXSurfaceMask      = 0x000F0000,
+    };
+
+    enum {
+        ePositionChanged            = 0x00000001,
+        eLayerChanged               = 0x00000002,
+        eSizeChanged                = 0x00000004,
+        eAlphaChanged               = 0x00000008,
+        eMatrixChanged              = 0x00000010,
+        eTransparentRegionChanged   = 0x00000020,
+        eVisibilityChanged          = 0x00000040,
+        eFreezeTintChanged          = 0x00000080,
+        eDestroyed                  = 0x00000100
+    };
+
+    enum {
+        eLayerHidden        = 0x01,
+        eLayerFrozen        = 0x02,
+        eLayerDither        = 0x04,
+        eLayerFilter        = 0x08,
+        eLayerBlurFreeze    = 0x10
+    };
+
+    enum {
+        eOrientationDefault     = 0,
+        eOrientation90          = 1,
+        eOrientation180         = 2,
+        eOrientation270         = 3,
+        eOrientationSwapMask    = 0x01
+    };
+
+    /* create connection with surface flinger, requires
+     * ACCESS_SURFACE_FLINGER permission
+     */
+
+    virtual sp<ISurfaceFlingerClient> createConnection() = 0;
+
+    /* retrieve the control block */
+    virtual sp<IMemory> getCblk() const = 0;
+
+    /* open/close transactions. recquires ACCESS_SURFACE_FLINGER permission */
+    virtual void openGlobalTransaction() = 0;
+    virtual void closeGlobalTransaction() = 0;
+
+    /* [un]freeze display. recquires ACCESS_SURFACE_FLINGER permission */
+    virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags) = 0;
+    virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags) = 0;
+
+    /* Set display orientation. recquires ACCESS_SURFACE_FLINGER permission */
+    virtual int setOrientation(DisplayID dpy, int orientation) = 0;
+
+    /* signal that we're done booting.
+     * recquires ACCESS_SURFACE_FLINGER permission
+     */
+    virtual void bootFinished() = 0;
+
+    /* get access to the GPU. Access is relinquished when releasing regs */
+    struct gpu_info_t {
+        struct gpu_region_t {
+            sp<IMemory> region;
+            size_t reserved;
+        };
+        sp<IMemory>             regs;
+        size_t                  count;
+        gpu_region_t            regions[2];
+    };
+    virtual status_t requestGPU(
+            const sp<IGPUCallback>& callback,
+            gpu_info_t* gpu) = 0;
+
+    /* take the gpu back from any apps using it. They'll get a
+     * EGL_CONTEXT_LOST error */
+    virtual status_t revokeGPU() = 0;
+
+    /* Signal surfaceflinger that there might be some work to do
+     * This is an ASYNCHRONOUS call.
+     */
+    virtual void signal() const = 0;
+};
+
+class IGPUCallback : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(GPUCallback);
+    virtual void gpuLost() = 0; //one-way
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSurfaceComposer : public BnInterface<ISurfaceComposer>
+{
+public:
+    enum {
+        // Note: BOOT_FINISHED must remain this value, it is called from
+        // Java by ActivityManagerService.
+        BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
+        CREATE_CONNECTION,
+        GET_CBLK,
+        OPEN_GLOBAL_TRANSACTION,
+        CLOSE_GLOBAL_TRANSACTION,
+        SET_ORIENTATION,
+        FREEZE_DISPLAY,
+        UNFREEZE_DISPLAY,
+        REQUEST_GPU,
+        REVOKE_GPU,
+        SIGNAL
+    };
+
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+class BnGPUCallback : public BnInterface<IGPUCallback>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_ISURFACE_COMPOSER_H
diff --git a/include/ui/ISurfaceFlingerClient.h b/include/ui/ISurfaceFlingerClient.h
new file mode 100644
index 0000000..bb2d39f
--- /dev/null
+++ b/include/ui/ISurfaceFlingerClient.h
@@ -0,0 +1,91 @@
+/*
+ * 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_ISURFACE_FLINGER_CLIENT_H
+#define ANDROID_ISURFACE_FLINGER_CLIENT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/IInterface.h>
+#include <utils/RefBase.h>
+
+#include <ui/ISurface.h>
+
+#include <ui/PixelFormat.h>
+  
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class Rect;
+class Point;
+class IMemory;
+class ISurface;
+
+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;
+        int32_t             type;
+        sp<IMemoryHeap>     heap[2];
+        status_t readFromParcel(const Parcel& parcel);
+        status_t writeToParcel(Parcel* parcel) const;
+    };
+    
+    virtual void getControlBlocks(sp<IMemory>* ctl) const = 0;
+
+    virtual sp<ISurface> createSurface( surface_data_t* data,
+                                        int pid, 
+                                        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_ISURFACE_FLINGER_CLIENT_H
diff --git a/include/ui/KeyCharacterMap.h b/include/ui/KeyCharacterMap.h
new file mode 100644
index 0000000..bad2cf8
--- /dev/null
+++ b/include/ui/KeyCharacterMap.h
@@ -0,0 +1,72 @@
+/*
+ * 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 _UI_KEY_CHARACTER_MAP_H
+#define _UI_KEY_CHARACTER_MAP_H
+
+#include <stdint.h>
+#include <utils/Vector.h>
+
+using namespace android;
+
+class KeyCharacterMap
+{
+public:
+    ~KeyCharacterMap();
+
+    // see the javadoc for android.text.method.KeyCharacterMap for what
+    // these do
+    unsigned short get(int keycode, int meta);
+    unsigned short getNumber(int keycode);
+    unsigned short getMatch(int keycode, const unsigned short* chars,
+                            int charsize, uint32_t modifiers);
+    unsigned short getDisplayLabel(int keycode);
+    bool getKeyData(int keycode, unsigned short *displayLabel,
+                    unsigned short *number, unsigned short* results);
+    inline unsigned int getKeyboardType() { return m_type; }
+    bool getEvents(uint16_t* chars, size_t len,
+                   Vector<int32_t>* keys, Vector<uint32_t>* modifiers);
+
+    static KeyCharacterMap* load(int id);
+
+    enum {
+        NUMERIC = 1,
+        Q14 = 2,
+        QWERTY = 3 // or AZERTY or whatever
+    };
+
+#define META_MASK 3
+
+private:
+    struct Key
+    {
+        int32_t keycode;
+        uint16_t display_label;
+        uint16_t number;
+        uint16_t data[META_MASK + 1];
+    };
+
+    KeyCharacterMap();
+    static KeyCharacterMap* try_file(const char* filename);
+    Key* find_key(int keycode);
+    bool find_char(uint16_t c, uint32_t* key, uint32_t* mods);
+
+    unsigned int m_type;
+    unsigned int m_keyCount;
+    Key* m_keys;
+};
+
+#endif // _UI_KEY_CHARACTER_MAP_H
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
new file mode 100644
index 0000000..747925d
--- /dev/null
+++ b/include/ui/KeycodeLabels.h
@@ -0,0 +1,222 @@
+/*
+ * 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 _UI_KEYCODE_LABELS_H
+#define _UI_KEYCODE_LABELS_H
+
+struct KeycodeLabel {
+    const char *literal;
+    int value;
+};
+
+static const KeycodeLabel KEYCODES[] = {
+    { "SOFT_LEFT", 1 },
+    { "SOFT_RIGHT", 2 },
+    { "HOME", 3 },
+    { "BACK", 4 },
+    { "CALL", 5 },
+    { "ENDCALL", 6 },
+    { "0", 7 },
+    { "1", 8 },
+    { "2", 9 },
+    { "3", 10 },
+    { "4", 11 },
+    { "5", 12 },
+    { "6", 13 },
+    { "7", 14 },
+    { "8", 15 },
+    { "9", 16 },
+    { "STAR", 17 },
+    { "POUND", 18 },
+    { "DPAD_UP", 19 },
+    { "DPAD_DOWN", 20 },
+    { "DPAD_LEFT", 21 },
+    { "DPAD_RIGHT", 22 },
+    { "DPAD_CENTER", 23 },
+    { "VOLUME_UP", 24 },
+    { "VOLUME_DOWN", 25 },
+    { "POWER", 26 },
+    { "CAMERA", 27 },
+    { "CLEAR", 28 },
+    { "A", 29 },
+    { "B", 30 },
+    { "C", 31 },
+    { "D", 32 },
+    { "E", 33 },
+    { "F", 34 },
+    { "G", 35 },
+    { "H", 36 },
+    { "I", 37 },
+    { "J", 38 },
+    { "K", 39 },
+    { "L", 40 },
+    { "M", 41 },
+    { "N", 42 },
+    { "O", 43 },
+    { "P", 44 },
+    { "Q", 45 },
+    { "R", 46 },
+    { "S", 47 },
+    { "T", 48 },
+    { "U", 49 },
+    { "V", 50 },
+    { "W", 51 },
+    { "X", 52 },
+    { "Y", 53 },
+    { "Z", 54 },
+    { "COMMA", 55 },
+    { "PERIOD", 56 },
+    { "ALT_LEFT", 57 },
+    { "ALT_RIGHT", 58 },
+    { "SHIFT_LEFT", 59 },
+    { "SHIFT_RIGHT", 60 },
+    { "TAB", 61 },
+    { "SPACE", 62 },
+    { "SYM", 63 },
+    { "EXPLORER", 64 },
+    { "ENVELOPE", 65 },
+    { "ENTER", 66 },
+    { "DEL", 67 },
+    { "GRAVE", 68 },
+    { "MINUS", 69 },
+    { "EQUALS", 70 },
+    { "LEFT_BRACKET", 71 },
+    { "RIGHT_BRACKET", 72 },
+    { "BACKSLASH", 73 },
+    { "SEMICOLON", 74 },
+    { "APOSTROPHE", 75 },
+    { "SLASH", 76 },
+    { "AT", 77 },
+    { "NUM", 78 },
+    { "HEADSETHOOK", 79 },
+    { "FOCUS", 80 },
+    { "PLUS", 81 },
+    { "MENU", 82 },
+    { "NOTIFICATION", 83 },
+    { "SEARCH", 84 },
+
+    // NOTE: If you add a new keycode here you must also add it to:
+    //   (enum KeyCode, in this file)
+    //   java/android/android/view/KeyEvent.java
+    //   tools/puppet_master/PuppetMaster.nav_keys.py
+    //   apps/common/res/values/attrs.xml
+
+    { 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
+} KeyCode;
+
+static const KeycodeLabel FLAGS[] = {
+    { "WAKE", 0x00000001 },
+    { "WAKE_DROPPED", 0x00000002 },
+    { "SHIFT", 0x00000004 },
+    { "CAPS_LOCK", 0x00000008 },
+    { "ALT", 0x00000010 },
+    { "ALT_GR", 0x00000020 },
+    { "MENU", 0x00000040 },
+    { "LAUNCHER", 0x00000080 },
+    { NULL, 0 }
+};
+
+#endif // _UI_KEYCODE_LABELS_H
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
new file mode 100644
index 0000000..d56a4a7
--- /dev/null
+++ b/include/ui/PixelFormat.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+
+// Pixel formats used across the system.
+// These formats might not all be supported by all renderers, for instance
+// skia or SurfaceFlinger are not required to support all of these formats
+// (either as source or destination)
+
+// XXX: we should consolidate these formats and skia's
+
+#ifndef UI_PIXELFORMAT_H
+#define UI_PIXELFORMAT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <pixelflinger/format.h>
+
+namespace android {
+
+enum {
+    //
+    // these constants need to match those
+    // in graphics/PixelFormat.java & pixelflinger/format.h
+    //
+    PIXEL_FORMAT_UNKNOWN    =   0,
+    PIXEL_FORMAT_NONE       =   0,
+
+    // logical pixel formats used by the SurfaceFlinger -----------------------
+    PIXEL_FORMAT_CUSTOM         = -4,
+        // Custom pixel-format described by a PixelFormatInfo sructure
+
+    PIXEL_FORMAT_TRANSLUCENT    = -3,
+        // System chooses a format that supports translucency (many alpha bits)
+
+    PIXEL_FORMAT_TRANSPARENT    = -2,
+        // System chooses a format that supports transparency
+        // (at least 1 alpha bit)
+
+    PIXEL_FORMAT_OPAQUE         = -1,
+        // System chooses an opaque format (no alpha bits required)
+    
+    // real pixel formats supported for rendering -----------------------------
+
+    PIXEL_FORMAT_RGBA_8888   = GGL_PIXEL_FORMAT_RGBA_8888,  // 4x8-bit RGBA
+    PIXEL_FORMAT_RGBX_8888   = GGL_PIXEL_FORMAT_RGBX_8888,  // 4x8-bit RGB0
+    PIXEL_FORMAT_RGB_888     = GGL_PIXEL_FORMAT_RGB_888,    // 3x8-bit RGB
+    PIXEL_FORMAT_RGB_565     = GGL_PIXEL_FORMAT_RGB_565,    // 16-bit RGB
+    PIXEL_FORMAT_RGBA_5551   = GGL_PIXEL_FORMAT_RGBA_5551,  // 16-bit ARGB
+    PIXEL_FORMAT_RGBA_4444   = GGL_PIXEL_FORMAT_RGBA_4444,  // 16-bit ARGB
+    PIXEL_FORMAT_A_8         = GGL_PIXEL_FORMAT_A_8,        // 8-bit A
+    PIXEL_FORMAT_L_8         = GGL_PIXEL_FORMAT_L_8,        // 8-bit L (R=G=B=L)
+    PIXEL_FORMAT_LA_88       = GGL_PIXEL_FORMAT_LA_88,      // 16-bit LA
+    PIXEL_FORMAT_RGB_332     = GGL_PIXEL_FORMAT_RGB_332,    // 8-bit RGB
+
+    PIXEL_FORMAT_YCbCr_422_SP= GGL_PIXEL_FORMAT_YCbCr_422_SP,
+    PIXEL_FORMAT_YCbCr_420_SP= GGL_PIXEL_FORMAT_YCbCr_420_SP,
+
+    // New formats can be added if they're also defined in
+    // pixelflinger/format.h
+};
+
+typedef int32_t PixelFormat;
+
+struct PixelFormatInfo
+{
+    inline PixelFormatInfo() : version(sizeof(PixelFormatInfo)) { }
+    size_t      version;
+    PixelFormat format;
+    size_t      bytesPerPixel;
+    size_t      bitsPerPixel;
+    uint8_t     h_alpha;
+    uint8_t     l_alpha;
+    uint8_t     h_red;
+    uint8_t     l_red;
+    uint8_t     h_green;
+    uint8_t     l_green;
+    uint8_t     h_blue;
+    uint8_t     l_blue;
+    uint32_t    reserved[2];
+};
+
+// considere caching the results of these functions are they're not
+// guaranteed to be fast.
+ssize_t     bytesPerPixel(PixelFormat format);
+ssize_t     bitsPerPixel(PixelFormat format);
+status_t    getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info);
+
+}; // namespace android
+
+#endif // UI_PIXELFORMAT_H
diff --git a/include/ui/Point.h b/include/ui/Point.h
new file mode 100644
index 0000000..dbbad1e
--- /dev/null
+++ b/include/ui/Point.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_UI_POINT
+#define ANDROID_UI_POINT
+
+#include <utils/TypeHelpers.h>
+
+namespace android {
+
+class Point
+{
+public:
+    int x;
+    int y;
+
+    // we don't provide copy-ctor and operator= on purpose
+    // because we want the compiler generated versions
+
+    // Default constructor doesn't initialize the Point
+    inline Point()
+    {
+    }
+
+    inline Point(int _x, int _y) : x(_x), y(_y)
+    {
+    }
+
+    inline bool operator == (const Point& rhs) const {
+        return (x == rhs.x) && (y == rhs.y);
+    }
+    inline bool operator != (const Point& rhs) const {
+        return !operator == (rhs);
+    }
+
+    inline bool isOrigin() const {
+        return !(x|y);
+    }
+
+    // operator < defines an order which allows to use points in sorted
+    // vectors.
+    bool operator < (const Point& rhs) const {
+        return y<rhs.y || (y==rhs.y && x<rhs.x);
+    }
+
+    inline Point& operator - () {
+        x=-x;
+        y=-y;
+        return *this;
+    }
+    
+    inline Point& operator += (const Point& rhs) {
+        x += rhs.x;
+        y += rhs.y;
+        return *this;
+    }
+    inline Point& operator -= (const Point& rhs) {
+        x -= rhs.x;
+        y -= rhs.y;
+        return *this;
+    }
+    
+    Point operator + (const Point& rhs) const {
+        return Point(x+rhs.x, y+rhs.y);
+    }
+    Point operator - (const Point& rhs) const {
+        return Point(x-rhs.x, y-rhs.y);
+    }    
+};
+
+ANDROID_BASIC_TYPES_TRAITS(Point)
+
+}; // namespace android
+
+#endif // ANDROID_UI_POINT
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
new file mode 100644
index 0000000..d232847
--- /dev/null
+++ b/include/ui/Rect.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_UI_RECT
+#define ANDROID_UI_RECT
+
+#include <utils/TypeHelpers.h>
+#include <ui/Point.h>
+
+namespace android {
+
+class Rect
+{
+public:
+    int left;
+    int top;
+    int right;
+    int bottom;
+
+    // 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(int l, int t, int r, int 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)
+    {
+    }
+
+    void makeInvalid();
+    
+    // a valid rectangle has a non negative width and height
+    inline bool isValid() const {
+        return (width()>=0) && (height()>=0);
+    }
+
+    // an empty rect has a zero width or height, or is invalid
+    inline bool isEmpty() const {
+        return (width()<=0) || (height()<=0);
+    }
+
+    inline void set(const Rect& rhs) {
+        operator = (rhs);
+    }
+
+    // rectangle's width
+    inline int width() const {
+        return right-left;
+    }
+    
+    // rectangle's height
+    inline int height() const {
+        return bottom-top;
+    }
+
+    // returns left-top Point non-const reference, can be assigned
+    inline Point& leftTop() {
+        return reinterpret_cast<Point&>(left);
+    }
+    // returns right bottom non-const reference, can be assigned
+    inline Point& rightBottom() {
+        return reinterpret_cast<Point&>(right);
+    }
+    
+    // the following 4 functions return the 4 corners of the rect as Point
+    inline const Point& leftTop() const {
+        return reinterpret_cast<const Point&>(left);
+    }
+    inline const Point& rightBottom() const {
+        return reinterpret_cast<const Point&>(right);
+    }
+    Point rightTop() const {
+        return Point(right, top);
+    }
+    Point leftBottom() const {
+        return Point(left, bottom);
+    }
+
+    // comparisons
+    inline bool operator == (const Rect& rhs) const {
+        return (left == rhs.left) && (top == rhs.top) &&
+               (right == rhs.right) && (bottom == rhs.bottom);
+    }
+
+    inline bool operator != (const Rect& rhs) const {
+        return !operator == (rhs);
+    }
+
+    // operator < defines an order which allows to use rectangles in sorted
+    // vectors.
+    bool operator < (const Rect& rhs) const;
+
+    Rect& offsetToOrigin() {
+        right -= left;
+        bottom -= top;
+        left = top = 0;
+        return *this;
+    }
+    Rect& offsetTo(const Point& p) {
+        return offsetTo(p.x, p.y);
+    }
+    Rect& offsetBy(const Point& dp) {
+        return offsetBy(dp.x, dp.y);
+    }
+    Rect& operator += (const Point& rhs) {
+        return offsetBy(rhs.x, rhs.y);
+    }
+    Rect& operator -= (const Point& rhs) {
+        return offsetBy(-rhs.x, -rhs.y);
+    }
+    Rect operator + (const Point& rhs) const;
+    Rect operator - (const Point& rhs) const;
+
+    void translate(int dx, int dy) { // legacy, don't use.
+        offsetBy(dx, dy);
+    }
+ 
+    Rect&   offsetTo(int x, int y);
+    Rect&   offsetBy(int x, int y);
+    bool    intersect(const Rect& with, Rect* result) const;
+};
+
+ANDROID_BASIC_TYPES_TRAITS(Rect)
+
+}; // namespace android
+
+#endif // ANDROID_UI_RECT
diff --git a/include/ui/Region.h b/include/ui/Region.h
new file mode 100644
index 0000000..a86e630
--- /dev/null
+++ b/include/ui/Region.h
@@ -0,0 +1,174 @@
+/*
+ * 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_UI_REGION_H
+#define ANDROID_UI_REGION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Vector.h>
+#include <utils/Parcel.h>
+
+#include <ui/Rect.h>
+#include <ui/BlitHardware.h>
+
+#include <corecg/SkRegion.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class String8;
+
+// ---------------------------------------------------------------------------
+class Region
+{
+public:
+                        Region();
+                        Region(const Region& rhs);
+    explicit            Region(const SkRegion& rhs);
+    explicit            Region(const Rect& rhs);
+    explicit            Region(const Parcel& parcel);
+    explicit            Region(const void* buffer);
+                        ~Region();
+                        
+        Region& operator = (const Region& rhs);
+
+    inline  bool        isEmpty() const     { return mRegion.isEmpty(); }
+    inline  bool        isRect() const      { return mRegion.isRect(); }
+
+            Rect        bounds() const;
+
+            const SkRegion& toSkRegion() const;
+
+            void        clear();
+            void        set(const Rect& r);
+        
+            Region&     orSelf(const Rect& rhs);
+            Region&     andSelf(const Rect& rhs);
+
+            // boolean operators, applied on this
+            Region&     orSelf(const Region& rhs);
+            Region&     andSelf(const Region& rhs);
+            Region&     subtractSelf(const Region& rhs);
+
+            // these translate rhs first
+            Region&     translateSelf(int dx, int dy);
+            Region&     orSelf(const Region& rhs, int dx, int dy);
+            Region&     andSelf(const Region& rhs, int dx, int dy);
+            Region&     subtractSelf(const Region& rhs, int dx, int dy);
+
+            // boolean operators
+            Region      merge(const Region& rhs) const;
+            Region      intersect(const Region& rhs) const;
+            Region      subtract(const Region& rhs) const;
+
+            // these translate rhs first
+            Region      translate(int dx, int dy) const;
+            Region      merge(const Region& rhs, int dx, int dy) const;
+            Region      intersect(const Region& rhs, int dx, int dy) const;
+            Region      subtract(const Region& rhs, int dx, int dy) const;
+
+    // convenience operators overloads
+    inline  Region      operator | (const Region& rhs) const;
+    inline  Region      operator & (const Region& rhs) const;
+    inline  Region      operator - (const Region& rhs) const;
+    inline  Region      operator + (const Point& pt) const;
+
+    inline  Region&     operator |= (const Region& rhs);
+    inline  Region&     operator &= (const Region& rhs);
+    inline  Region&     operator -= (const Region& rhs);
+    inline  Region&     operator += (const Point& pt);
+
+    class iterator {
+        SkRegion::Iterator  mIt;
+    public:
+        iterator(const Region& r);
+        inline operator bool () const { return !done(); }
+        int iterate(Rect* rect);
+    private:
+        inline bool done() const {
+            return const_cast<SkRegion::Iterator&>(mIt).done();
+        }
+    };
+
+            size_t      rects(Vector<Rect>& rectList) const;
+
+            // flatten/unflatten a region to/from a Parcel
+            status_t    write(Parcel& parcel) const;
+            status_t    read(const Parcel& parcel);
+
+            // flatten/unflatten a region to/from a raw buffer
+            ssize_t     write(void* buffer, size_t size) const;
+    static  ssize_t     writeEmpty(void* buffer, size_t size);
+
+            ssize_t     read(const void* buffer);
+    static  bool        isEmpty(void* buffer);
+
+    void        dump(String8& out, const char* what, uint32_t flags=0) const;
+    void        dump(const char* what, uint32_t flags=0) const;
+
+private:
+    SkRegion    mRegion;
+};
+
+
+Region Region::operator | (const Region& rhs) const {
+    return merge(rhs);
+}
+Region Region::operator & (const Region& rhs) const {
+    return intersect(rhs);
+}
+Region Region::operator - (const Region& rhs) const {
+    return subtract(rhs);
+}
+Region Region::operator + (const Point& pt) const {
+    return translate(pt.x, pt.y);
+}
+
+
+Region& Region::operator |= (const Region& rhs) {
+    return orSelf(rhs);
+}
+Region& Region::operator &= (const Region& rhs) {
+    return andSelf(rhs);
+}
+Region& Region::operator -= (const Region& rhs) {
+    return subtractSelf(rhs);
+}
+Region& Region::operator += (const Point& pt) {
+    return translateSelf(pt.x, pt.y);
+}
+
+// ---------------------------------------------------------------------------
+
+struct region_iterator : public copybit_region_t {
+    region_iterator(const Region& region) : i(region) {
+        this->next = iterate;
+    }
+private:
+    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
+        return static_cast<const region_iterator*>(self)
+        ->i.iterate(reinterpret_cast<Rect*>(rect));
+    }
+    mutable Region::iterator i;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_UI_REGION_H
+
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
new file mode 100644
index 0000000..0a75bf3
--- /dev/null
+++ b/include/ui/Surface.h
@@ -0,0 +1,137 @@
+/*
+ * 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_UI_SURFACE_H
+#define ANDROID_UI_SURFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
+#include <ui/ISurface.h>
+#include <ui/PixelFormat.h>
+#include <ui/Region.h>
+#include <ui/ISurfaceFlingerClient.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class Rect;
+class SurfaceComposerClient;
+
+class Surface : public RefBase
+{
+
+public:
+    struct SurfaceInfo {
+        uint32_t    w;
+        uint32_t    h;
+        uint32_t    bpr;
+        PixelFormat format;
+        void*       bits;
+        void*       base;
+        uint32_t    reserved[2];
+    };
+    
+    bool        isValid() const { return this && mToken>=0 && mClient!=0; }
+    SurfaceID   ID() const      { return mToken; }
+
+    status_t    lock(SurfaceInfo* info, bool blocking = true);
+    status_t    lock(SurfaceInfo* info, Region* dirty, bool blocking = true);
+    status_t    unlockAndPost();
+    status_t    unlock();
+
+    void*       heapBase(int i) const;
+    uint32_t    getFlags() const { return mFlags; }
+    int         getMemoryType() const { return mMemoryType; }
+    
+    // setSwapRectangle() is mainly used by EGL
+    void        setSwapRectangle(const Rect& r);
+    const Rect& swapRectangle() const;
+    status_t    nextBuffer(SurfaceInfo* info);
+    
+    sp<Surface>         dup() const;
+    static sp<Surface>  readFromParcel(Parcel* parcel);
+    static status_t     writeToParcel(const sp<Surface>& surface, Parcel* parcel);
+    static bool         isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs);
+    
+    status_t    setLayer(int32_t layer);
+    status_t    setPosition(int32_t x, int32_t y);
+    status_t    setSize(uint32_t w, uint32_t h);
+    status_t    hide();
+    status_t    show(int32_t layer = -1);
+    status_t    freeze();
+    status_t    unfreeze();
+    status_t    setFlags(uint32_t flags, uint32_t mask);
+    status_t    setTransparentRegionHint(const Region& transparent);
+    status_t    setAlpha(float alpha=1.0f);
+    status_t    setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
+    status_t    setFreezeTint(uint32_t tint);
+    
+    uint32_t    getIdentity() const { return mIdentity; }
+private:
+    friend class SurfaceComposerClient;
+
+    // camera needs access to the ISurface binder interface for preview
+    friend class Camera;
+    // mediaplayer needs access to ISurface for display
+    friend class MediaPlayer;
+    const sp<ISurface>& getISurface() const { return mSurface; }
+
+    // can't be copied
+    Surface& operator = (Surface& rhs);
+    Surface(const Surface& rhs);
+
+    Surface(const sp<SurfaceComposerClient>& client, 
+            const sp<ISurface>& surface,
+            const ISurfaceFlingerClient::surface_data_t& data,
+            uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
+            bool owner = true);
+    
+    Surface(Surface const* rhs);
+
+    ~Surface();
+
+    Region dirtyRegion() const;
+    void setDirtyRegion(const Region& region) const;
+    
+    // this locks protects calls to lockSurface() / unlockSurface()
+    // and is called by SurfaceComposerClient.
+    Mutex& getLock() const { return mSurfaceLock; }
+
+    sp<SurfaceComposerClient>   mClient;
+    sp<ISurface>                mSurface;
+    sp<IMemoryHeap>             mHeap[2];
+    int                         mMemoryType;
+    SurfaceID                   mToken;
+    uint32_t                    mIdentity;
+    PixelFormat                 mFormat;
+    uint32_t                    mFlags;
+    const bool                  mOwner;
+    mutable void*               mSurfaceHeapBase[2];
+    mutable Region              mDirtyRegion;
+    mutable Rect                mSwapRectangle;
+    mutable uint8_t             mBackbufferIndex;
+    mutable Mutex               mSurfaceLock;
+};
+
+}; // namespace android
+
+#endif // ANDROID_UI_SURFACE_H
+
diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h
new file mode 100644
index 0000000..3b875be
--- /dev/null
+++ b/include/ui/SurfaceComposerClient.h
@@ -0,0 +1,179 @@
+/*
+ * 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_COMPOSER_CLIENT_H
+#define ANDROID_SURFACE_COMPOSER_CLIENT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/SortedVector.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/Region.h>
+#include <ui/Surface.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class Region;
+class SurfaceFlingerSynchro;
+struct per_client_cblk_t;
+struct layer_cblk_t;
+
+class SurfaceComposerClient : virtual public RefBase
+{
+public:    
+                SurfaceComposerClient();
+    virtual     ~SurfaceComposerClient();
+
+    // Always make sure we could initialize
+    status_t    initCheck() const;
+
+    // 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();
+
+    // ------------------------------------------------------------------------
+    // surface creation / destruction
+
+    //! Create a surface
+    sp<Surface>   createSurface(
+            int pid,            //!< pid of the process the surfacec is for
+            DisplayID display,  //!< Display to create this surface on
+            uint32_t w,         //!< width in pixel
+            uint32_t h,         //!< height in pixel
+            PixelFormat format, //!< pixel-format desired
+            uint32_t flags = 0  //!< usage flags
+    );
+
+    // ------------------------------------------------------------------------
+    // Composer paramters
+    // All composer parameters must be changed within a transaction
+    // several surfaces can be updated in one transaction, all changes are
+    // committed at once when the transaction is closed.
+    // CloseTransaction() usually requires an IPC with the server.
+    
+    //! Open a composer transaction
+    status_t    openTransaction();
+
+    //! commit the transaction
+    status_t    closeTransaction();
+
+    //! Open a composer transaction on all active SurfaceComposerClients.
+    static void openGlobalTransaction();
+        
+    //! Close a composer transaction on all active SurfaceComposerClients.
+    static void closeGlobalTransaction();
+    
+    //! Freeze the specified display but not transactions.
+    static status_t freezeDisplay(DisplayID dpy, uint32_t flags = 0);
+        
+    //! Resume updates on the specified display.
+    static status_t unfreezeDisplay(DisplayID dpy, uint32_t flags = 0);
+
+    //! Set the orientation of the given display
+    static int setOrientation(DisplayID dpy, int orientation);
+
+    // Query the number of displays
+    static ssize_t getNumberOfDisplays();
+
+    // Get information about a display
+    static status_t getDisplayInfo(DisplayID dpy, DisplayInfo* info);
+    static ssize_t getDisplayWidth(DisplayID dpy);
+    static ssize_t getDisplayHeight(DisplayID dpy);
+    static ssize_t getDisplayOrientation(DisplayID dpy);
+
+
+private:
+    friend class Surface;
+    
+    SurfaceComposerClient(const sp<ISurfaceComposer>& sm, 
+            const sp<IBinder>& conn);
+
+    status_t    hide(Surface* surface);
+    status_t    show(Surface* surface, int32_t layer = -1);
+    status_t    freeze(Surface* surface);
+    status_t    unfreeze(Surface* surface);
+    status_t    setFlags(Surface* surface, uint32_t flags, uint32_t mask);
+    status_t    setTransparentRegionHint(Surface* surface, const Region& transparent);
+    status_t    setLayer(Surface* surface, int32_t layer);
+    status_t    setAlpha(Surface* surface, float alpha=1.0f);
+    status_t    setFreezeTint(Surface* surface, uint32_t tint);
+    status_t    setMatrix(Surface* surface, float dsdx, float dtdx, float dsdy, float dtdy);
+    status_t    setPosition(Surface* surface, int32_t x, int32_t y);
+    status_t    setSize(Surface* surface, uint32_t w, uint32_t h);
+    
+    //! Unlock the surface, and specify the dirty region if any
+    status_t    unlockAndPostSurface(Surface* surface);
+    status_t    unlockSurface(Surface* surface);
+
+    status_t    lockSurface(Surface* surface,
+                            Surface::SurfaceInfo* info,
+                            Region* dirty,
+                            bool blocking = true);
+
+    status_t    nextBuffer(Surface* surface,
+                            Surface::SurfaceInfo* info);
+
+    status_t    destroySurface(SurfaceID sid);
+
+    void        _init(const sp<ISurfaceComposer>& sm,
+                    const sp<ISurfaceFlingerClient>& conn);
+    void        _signal_server();
+    static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty);
+
+    inline layer_state_t*   _get_state_l(const sp<Surface>& surface);
+    layer_state_t*          _lockLayerState(const sp<Surface>& surface);
+    inline void             _unlockLayerState();
+
+    status_t validateSurface(
+            per_client_cblk_t const* cblk, Surface const * surface);
+
+    void pinHeap(const sp<IMemoryHeap>& heap);
+
+    mutable     Mutex                               mLock;
+                layer_state_t*                      mPrebuiltLayerState;
+                SortedVector<layer_state_t>         mStates;
+                int32_t                             mTransactionOpen;
+
+                // these don't need to be protected because they never change
+                // after assignment
+                status_t                    mStatus;
+                per_client_cblk_t*          mControl;
+                sp<IMemory>                 mControlMemory;
+                sp<ISurfaceFlingerClient>   mClient;
+                sp<IMemoryHeap>             mSurfaceHeap;
+                uint8_t*                    mSurfaceHeapBase;
+                void*                       mGL;
+                SurfaceFlingerSynchro*      mSignalServer;
+};
+
+}; // namespace android
+
+#endif // ANDROID_SURFACE_COMPOSER_CLIENT_H
+
diff --git a/include/utils.h b/include/utils.h
new file mode 100644
index 0000000..30648b1
--- /dev/null
+++ b/include/utils.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Handy utility functions and portability code.  This file includes all
+// of the generally-useful headers in the "utils" directory.
+//
+#ifndef _LIBS_UTILS_H
+#define _LIBS_UTILS_H
+
+#include <utils/ported.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/List.h>
+#include <utils/string_array.h>
+#include <utils/misc.h>
+#include <utils/Errors.h>
+
+#endif // _LIBS_UTILS_H
diff --git a/include/utils/AndroidUnicode.h b/include/utils/AndroidUnicode.h
new file mode 100644
index 0000000..563fcd0
--- /dev/null
+++ b/include/utils/AndroidUnicode.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_UNICODE_H
+#define ANDROID_UNICODE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define REPLACEMENT_CHAR (0xFFFD)
+
+// this part of code is copied from umachine.h under ICU
+/**
+ * Define UChar32 as a type for single Unicode code points.
+ * UChar32 is a signed 32-bit integer (same as int32_t).
+ *
+ * The Unicode code point range is 0..0x10ffff.
+ * All other values (negative or >=0x110000) are illegal as Unicode code points.
+ * They may be used as sentinel values to indicate "done", "error"
+ * or similar non-code point conditions.
+ *
+ * @stable ICU 2.4
+ */
+typedef int32_t UChar32;
+
+namespace android {
+
+    class Encoding;
+    /**
+     * \class Unicode
+     *
+     * Helper class for getting properties of Unicode characters. Characters
+     * can have one of the types listed in CharType and each character can have the
+     * directionality of Direction.
+     */
+    class Unicode
+    {
+    public:
+        /**
+         * Directions specified in the Unicode standard. These directions map directly
+         * to java.lang.Character.
+         */
+        enum Direction {
+            DIRECTIONALITY_UNDEFINED = -1,
+            DIRECTIONALITY_LEFT_TO_RIGHT,
+            DIRECTIONALITY_RIGHT_TO_LEFT,
+            DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC,
+            DIRECTIONALITY_EUROPEAN_NUMBER,
+            DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR,
+            DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR,
+            DIRECTIONALITY_ARABIC_NUMBER,
+            DIRECTIONALITY_COMMON_NUMBER_SEPARATOR,
+            DIRECTIONALITY_NONSPACING_MARK,
+            DIRECTIONALITY_BOUNDARY_NEUTRAL,
+            DIRECTIONALITY_PARAGRAPH_SEPARATOR,
+            DIRECTIONALITY_SEGMENT_SEPARATOR,
+            DIRECTIONALITY_WHITESPACE,
+            DIRECTIONALITY_OTHER_NEUTRALS,
+            DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING,
+            DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE,
+            DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING,
+            DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE,
+            DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+        };
+
+        /**
+         * Character types as specified in the Unicode standard. These map directly to
+         * java.lang.Character.
+         */
+        enum CharType {
+            CHARTYPE_UNASSIGNED = 0,
+            CHARTYPE_UPPERCASE_LETTER,
+            CHARTYPE_LOWERCASE_LETTER,
+            CHARTYPE_TITLECASE_LETTER,
+            CHARTYPE_MODIFIER_LETTER,
+            CHARTYPE_OTHER_LETTER,
+            CHARTYPE_NON_SPACING_MARK,
+            CHARTYPE_ENCLOSING_MARK,
+            CHARTYPE_COMBINING_SPACING_MARK,
+            CHARTYPE_DECIMAL_DIGIT_NUMBER,
+            CHARTYPE_LETTER_NUMBER,
+            CHARTYPE_OTHER_NUMBER,
+            CHARTYPE_SPACE_SEPARATOR,
+            CHARTYPE_LINE_SEPARATOR,
+            CHARTYPE_PARAGRAPH_SEPARATOR,
+            CHARTYPE_CONTROL,
+            CHARTYPE_FORMAT,
+            CHARTYPE_MISSING_VALUE_FOR_JAVA,    /* This is the mysterious missing 17 value from the java constants */
+            CHARTYPE_PRIVATE_USE,
+            CHARTYPE_SURROGATE,
+            CHARTYPE_DASH_PUNCTUATION,
+            CHARTYPE_START_PUNCTUATION,
+            CHARTYPE_END_PUNCTUATION,
+            CHARTYPE_CONNECTOR_PUNCTUATION,
+            CHARTYPE_OTHER_PUNCTUATION,
+            CHARTYPE_MATH_SYMBOL,
+            CHARTYPE_CURRENCY_SYMBOL,
+            CHARTYPE_MODIFIER_SYMBOL,
+            CHARTYPE_OTHER_SYMBOL,
+            CHARTYPE_INITIAL_QUOTE_PUNCTUATION,
+            CHARTYPE_FINAL_QUOTE_PUNCTUATION
+        };
+
+        /**
+         * Decomposition types as described by the unicode standard. These values map to
+         * the same values in uchar.h in ICU.
+         */
+        enum DecompositionType {
+            DECOMPOSITION_NONE = 0,
+            DECOMPOSITION_CANONICAL,
+            DECOMPOSITION_COMPAT,
+            DECOMPOSITION_CIRCLE,
+            DECOMPOSITION_FINAL,
+            DECOMPOSITION_FONT,
+            DECOMPOSITION_FRACTION,
+            DECOMPOSITION_INITIAL,
+            DECOMPOSITION_ISOLATED,
+            DECOMPOSITION_MEDIAL,
+            DECOMPOSITION_NARROW,
+            DECOMPOSITION_NOBREAK,
+            DECOMPOSITION_SMALL,
+            DECOMPOSITION_SQUARE,
+            DECOMPOSITION_SUB,
+            DECOMPOSITION_SUPER,
+            DECOMPOSITION_VERTICAL,
+            DECOMPOSITION_WIDE
+        };
+
+        /**
+         * Returns the packed data for java calls
+         * @param c The unicode character.
+         * @return The packed data for the character.
+         *
+         * Copied from java.lang.Character implementation:
+         * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+         * F E D C B A 9 8 7 6 5 4 3 2 1 0 F E D C B A 9 8 7 6 5 4 3 2 1 0
+         * 
+         *                              31 types                 ---------
+         *                   18 directionalities       ---------
+         *                   2 mirroreds             -
+         *                               -----------      56  toupper diffs
+         *                   -----------                  48  tolower diffs
+         *               ---                              4 totitlecase diffs
+         * -------------                                 84 numeric values
+         *     ---------                                 24 mirror char diffs
+         */
+        static uint32_t getPackedData(UChar32 c);
+        
+        /**
+         * Get the Character type.
+         * @param c The unicode character.
+         * @return The character's type or CHARTYPE_UNASSIGNED if the character is invalid
+         *         or has an unassigned class.
+         */
+        static CharType getType(UChar32 c);    
+
+        /**
+         * Get the Character's decomposition type.
+         * @param c The unicode character.
+         * @return The character's decomposition type or DECOMPOSITION_NONE is there 
+         *         is no decomposition.
+         */
+        static DecompositionType getDecompositionType(UChar32 c);
+        
+        /**
+         * Returns the digit value of a character or -1 if the character
+         * is not within the specified radix.
+         *
+         * The digit value is computed for integer characters and letters
+         * within the given radix. This function does not handle Roman Numerals,
+         * fractions, or any other characters that may represent numbers.
+         * 
+         * @param c The unicode character
+         * @param radix The intended radix.
+         * @return The digit value or -1 if there is no digit value or if the value is outside the radix.
+         */
+        static int getDigitValue(UChar32 c, int radix = 10);
+
+        /**
+         * Return the numeric value of a character
+         *
+         * @param c The unicode character.
+         * @return The numeric value of the character. -1 if the character has no numeric value, 
+         *         -2 if the character has a numeric value that is not representable by an integer.
+         */
+        static int getNumericValue(UChar32 c);
+
+        /**
+         * Convert the character to lowercase
+         * @param c The unicode character.
+         * @return The lowercase character equivalent of c. If c does not have a lowercase equivalent,
+         *         the original character is returned.
+         */
+        static UChar32 toLower(UChar32 c);
+            
+        /**
+         * Convert the character to uppercase
+         * @param c The unicode character.
+         * @return The uppercase character equivalent of c. If c does not have an uppercase equivalent,
+         *         the original character is returned.
+         */
+        static UChar32 toUpper(UChar32 c);
+    
+        /**
+         * Get the directionality of the character.
+         * @param c The unicode character.
+         * @return The direction of the character or DIRECTIONALITY_UNDEFINED.
+         */
+        static Direction getDirectionality(UChar32 c);
+            
+        /**
+         * Check if the character is a mirrored character. This means that the character
+         * has an equivalent character that is the mirror image of itself.
+         * @param c The unicode character.
+         * @return True iff c has a mirror equivalent.
+         */
+        static bool isMirrored(UChar32 c);
+         
+        /**
+         * Return the mirror of the given character.
+         * @param c The unicode character.
+         * @return The mirror equivalent of c. If c does not have a mirror equivalent,
+         *         the original character is returned.
+         * @see isMirrored
+         */
+        static UChar32 toMirror(UChar32 c);
+        
+        /**
+         * Convert the character to title case.
+         * @param c The unicode character.
+         * @return The titlecase equivalent of c. If c does not have a titlecase equivalent,
+         *         the original character is returned.
+         */
+        static UChar32 toTitle(UChar32 c);
+
+   };
+
+}
+
+#endif
diff --git a/include/utils/Asset.h b/include/utils/Asset.h
new file mode 100644
index 0000000..d8351f5
--- /dev/null
+++ b/include/utils/Asset.h
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Class providing access to a read-only asset.  Asset objects are NOT
+// thread-safe, and should not be shared across threads.
+//
+#ifndef __LIBS_ASSET_H
+#define __LIBS_ASSET_H
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "FileMap.h"
+#include "String8.h"
+#include "Errors.h"
+
+namespace android {
+
+/*
+ * Instances of this class provide read-only operations on a byte stream.
+ *
+ * Access may be optimized for streaming, random, or whole buffer modes.  All
+ * operations are supported regardless of how the file was opened, but some
+ * things will be less efficient.  [pass that in??]
+ *
+ * "Asset" is the base class for all types of assets.  The classes below
+ * provide most of the implementation.  The AssetManager uses one of the
+ * static "create" functions defined here to create a new instance.
+ */
+class Asset {
+public:
+    virtual ~Asset(void);
+
+    static int32_t getGlobalCount();
+    
+    /* used when opening an asset */
+    typedef enum AccessMode {
+        ACCESS_UNKNOWN = 0,
+
+        /* read chunks, and seek forward and backward */
+        ACCESS_RANDOM,
+
+        /* read sequentially, with an occasional forward seek */
+        ACCESS_STREAMING,
+
+        /* caller plans to ask for a read-only buffer with all data */
+        ACCESS_BUFFER,
+    } AccessMode;
+
+    enum {
+        /* data larger than this does not get uncompressed into a buffer */
+        UNCOMPRESS_DATA_MAX = 1 * 1024 * 1024
+    };
+
+    /*
+     * Read data from the current offset.  Returns the actual number of
+     * bytes read, 0 on EOF, or -1 on error.
+     */
+    virtual ssize_t read(void* buf, size_t count) = 0;
+
+    /*
+     * Seek to the specified offset.  "whence" uses the same values as
+     * lseek/fseek.  Returns the new position on success, or (off_t) -1
+     * on failure.
+     */
+    virtual off_t seek(off_t offset, int whence) = 0;
+
+    /*
+     * Close the asset, freeing all associated resources.
+     */
+    virtual void close(void) = 0;
+
+    /*
+     * Get a pointer to a buffer with the entire contents of the file.
+     */
+    virtual const void* getBuffer(bool wordAligned) = 0;
+
+    /*
+     * Get the total amount of data that can be read.
+     */
+    virtual off_t getLength(void) const = 0;
+
+    /*
+     * Get the total amount of data that can be read from the current position.
+     */
+    virtual off_t getRemainingLength(void) const = 0;
+
+    /*
+     * Open a new file descriptor that can be used to read this asset.
+     * Returns -1 if you can not use the file descriptor (for example if the
+     * asset is compressed).
+     */
+    virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const = 0;
+    
+    /*
+     * Get a string identifying the asset's source.  This might be a full
+     * path, it might be a colon-separated list of identifiers.
+     *
+     * This is NOT intended to be used for anything except debug output.
+     * DO NOT try to parse this or use it to open a file.
+     */
+    const char* getAssetSource(void) const { return mAssetSource.string(); }
+
+protected:
+    Asset(void);        // constructor; only invoked indirectly
+
+    /* handle common seek() housekeeping */
+    off_t handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn);
+
+    /* set the asset source string */
+    void setAssetSource(const String8& path) { mAssetSource = path; }
+
+    AccessMode getAccessMode(void) const { return mAccessMode; }
+
+private:
+    /* these operations are not implemented */
+    Asset(const Asset& src);
+    Asset& operator=(const Asset& src);
+
+    /* AssetManager needs access to our "create" functions */
+    friend class AssetManager;
+
+    /*
+     * Create the asset from a named file on disk.
+     */
+    static Asset* createFromFile(const char* fileName, AccessMode mode);
+
+    /*
+     * Create the asset from a named, compressed file on disk (e.g. ".gz").
+     */
+    static Asset* createFromCompressedFile(const char* fileName,
+        AccessMode mode);
+
+#if 0
+    /*
+     * Create the asset from a segment of an open file.  This will fail
+     * if "offset" and "length" don't fit within the bounds of the file.
+     *
+     * The asset takes ownership of the file descriptor.
+     */
+    static Asset* createFromFileSegment(int fd, off_t offset, size_t length,
+        AccessMode mode);
+
+    /*
+     * Create from compressed data.  "fd" should be seeked to the start of
+     * the compressed data.  This could be inside a gzip file or part of a
+     * Zip archive.
+     *
+     * The asset takes ownership of the file descriptor.
+     *
+     * This may not verify the validity of the compressed data until first
+     * use.
+     */
+    static Asset* createFromCompressedData(int fd, off_t offset,
+        int compressionMethod, size_t compressedLength,
+        size_t uncompressedLength, AccessMode mode);
+#endif
+
+    /*
+     * Create the asset from a memory-mapped file segment.
+     *
+     * The asset takes ownership of the FileMap.
+     */
+    static Asset* createFromUncompressedMap(FileMap* dataMap, AccessMode mode);
+
+    /*
+     * Create the asset from a memory-mapped file segment with compressed
+     * data.  "method" is a Zip archive compression method constant.
+     *
+     * The asset takes ownership of the FileMap.
+     */
+    static Asset* createFromCompressedMap(FileMap* dataMap, int method,
+        size_t uncompressedLen, AccessMode mode);
+
+
+    /*
+     * Create from a reference-counted chunk of shared memory.
+     */
+    // TODO
+
+    AccessMode  mAccessMode;        // how the asset was opened
+    String8    mAssetSource;       // debug string
+};
+
+
+/*
+ * ===========================================================================
+ *
+ * Innards follow.  Do not use these classes directly.
+ */
+
+/*
+ * An asset based on an uncompressed file on disk.  It may encompass the
+ * entire file or just a piece of it.  Access is through fread/fseek.
+ */
+class _FileAsset : public Asset {
+public:
+    _FileAsset(void);
+    virtual ~_FileAsset(void);
+
+    /*
+     * Use a piece of an already-open file.
+     *
+     * On success, the object takes ownership of "fd".
+     */
+    status_t openChunk(const char* fileName, int fd, off_t offset, size_t length);
+
+    /*
+     * Use a memory-mapped region.
+     *
+     * On success, the object takes ownership of "dataMap".
+     */
+    status_t openChunk(FileMap* dataMap);
+
+    /*
+     * Standard Asset interfaces.
+     */
+    virtual ssize_t read(void* buf, size_t count);
+    virtual off_t seek(off_t offset, int whence);
+    virtual void close(void);
+    virtual const void* getBuffer(bool wordAligned);
+    virtual off_t getLength(void) const { return mLength; }
+    virtual off_t getRemainingLength(void) const { return mLength-mOffset; }
+    virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const;
+
+private:
+    off_t       mStart;         // absolute file offset of start of chunk
+    off_t       mLength;        // length of the chunk
+    off_t       mOffset;        // current local offset, 0 == mStart
+    FILE*       mFp;            // for read/seek
+    char*       mFileName;      // for opening
+
+    /*
+     * To support getBuffer() we either need to read the entire thing into
+     * a buffer or memory-map it.  For small files it's probably best to
+     * just read them in.
+     */
+    enum { kReadVsMapThreshold = 4096 };
+
+    FileMap*    mMap;           // for memory map
+    unsigned char* mBuf;        // for read
+    
+    const void* ensureAlignment(FileMap* map);
+};
+
+
+/*
+ * An asset based on compressed data in a file.
+ */
+class _CompressedAsset : public Asset {
+public:
+    _CompressedAsset(void);
+    virtual ~_CompressedAsset(void);
+
+    /*
+     * Use a piece of an already-open file.
+     *
+     * On success, the object takes ownership of "fd".
+     */
+    status_t openChunk(int fd, off_t offset, int compressionMethod,
+        size_t uncompressedLen, size_t compressedLen);
+
+    /*
+     * Use a memory-mapped region.
+     *
+     * On success, the object takes ownership of "fd".
+     */
+    status_t openChunk(FileMap* dataMap, int compressionMethod,
+        size_t uncompressedLen);
+
+    /*
+     * Standard Asset interfaces.
+     */
+    virtual ssize_t read(void* buf, size_t count);
+    virtual off_t seek(off_t offset, int whence);
+    virtual void close(void);
+    virtual const void* getBuffer(bool wordAligned);
+    virtual off_t getLength(void) const { return mUncompressedLen; }
+    virtual off_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
+    virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const { return -1; }
+
+private:
+    off_t       mStart;         // offset to start of compressed data
+    off_t       mCompressedLen; // length of the compressed data
+    off_t       mUncompressedLen; // length of the uncompressed data
+    off_t       mOffset;        // current offset, 0 == start of uncomp data
+
+    FileMap*    mMap;           // for memory-mapped input
+    int         mFd;            // for file input
+
+    unsigned char*  mBuf;       // for getBuffer()
+};
+
+// need: shared mmap version?
+
+}; // namespace android
+
+#endif // __LIBS_ASSET_H
diff --git a/include/utils/AssetDir.h b/include/utils/AssetDir.h
new file mode 100644
index 0000000..abf8a35
--- /dev/null
+++ b/include/utils/AssetDir.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Access a chunk of the asset hierarchy as if it were a single directory.
+//
+#ifndef __LIBS_ASSETDIR_H
+#define __LIBS_ASSETDIR_H
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/SortedVector.h>
+#include <utils/misc.h>
+#include <sys/types.h>
+
+namespace android {
+
+/*
+ * This provides vector-style access to a directory.  We do this rather
+ * than modeling opendir/readdir access because it's simpler and the
+ * nature of the operation requires us to have all data on hand anyway.
+ *
+ * The list of files will be sorted in ascending order by ASCII value.
+ *
+ * The contents are populated by our friend, the AssetManager.
+ */
+class AssetDir {
+public:
+    AssetDir(void)
+        : mFileInfo(NULL)
+        {}
+    virtual ~AssetDir(void) {
+        delete mFileInfo;
+    }
+
+    /*
+     * Vector-style access.
+     */
+    size_t getFileCount(void) { return mFileInfo->size(); }
+    const String8& getFileName(int idx) {
+        return mFileInfo->itemAt(idx).getFileName();
+    }
+    const String8& getSourceName(int idx) {
+        return mFileInfo->itemAt(idx).getSourceName();
+    }
+
+    /*
+     * Get the type of a file (usually regular or directory).
+     */
+    FileType getFileType(int idx) {
+        return mFileInfo->itemAt(idx).getFileType();
+    }
+
+private:
+    /* these operations are not implemented */
+    AssetDir(const AssetDir& src);
+    const AssetDir& operator=(const AssetDir& src);
+
+    friend class AssetManager;
+
+    /*
+     * This holds information about files in the asset hierarchy.
+     */
+    class FileInfo {
+    public:
+        FileInfo(void) {}
+        FileInfo(const String8& path)      // useful for e.g. svect.indexOf
+            : mFileName(path), mFileType(kFileTypeUnknown)
+            {}
+        ~FileInfo(void) {}
+        FileInfo(const FileInfo& src) {
+            copyMembers(src);
+        }
+        const FileInfo& operator= (const FileInfo& src) {
+            if (this != &src)
+                copyMembers(src);
+            return *this;
+        }
+
+        void copyMembers(const FileInfo& src) {
+            mFileName = src.mFileName;
+            mFileType = src.mFileType;
+            mSourceName = src.mSourceName;
+        }
+
+        /* need this for SortedVector; must compare only on file name */
+        bool operator< (const FileInfo& rhs) const {
+            return mFileName < rhs.mFileName;
+        }
+
+        /* used by AssetManager */
+        bool operator== (const FileInfo& rhs) const {
+            return mFileName == rhs.mFileName;
+        }
+
+        void set(const String8& path, FileType type) {
+            mFileName = path;
+            mFileType = type;
+        }
+
+        const String8& getFileName(void) const { return mFileName; }
+        void setFileName(const String8& path) { mFileName = path; }
+
+        FileType getFileType(void) const { return mFileType; }
+        void setFileType(FileType type) { mFileType = type; }
+
+        const String8& getSourceName(void) const { return mSourceName; }
+        void setSourceName(const String8& path) { mSourceName = path; }
+
+        /*
+         * Handy utility for finding an entry in a sorted vector of FileInfo.
+         * Returns the index of the matching entry, or -1 if none found.
+         */
+        static int findEntry(const SortedVector<FileInfo>* pVector,
+            const String8& fileName);
+
+    private:
+        String8    mFileName;      // filename only
+        FileType    mFileType;      // regular, directory, etc
+
+        String8    mSourceName;    // currently debug-only
+    };
+
+    /* AssetManager uses this to initialize us */
+    void setFileList(SortedVector<FileInfo>* list) { mFileInfo = list; }
+
+    SortedVector<FileInfo>* mFileInfo;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ASSETDIR_H
diff --git a/include/utils/AssetManager.h b/include/utils/AssetManager.h
new file mode 100644
index 0000000..e94c0e8
--- /dev/null
+++ b/include/utils/AssetManager.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Asset management class.  AssetManager objects are thread-safe.
+//
+#ifndef __LIBS_ASSETMANAGER_H
+#define __LIBS_ASSETMANAGER_H
+
+#include <utils/Asset.h>
+#include <utils/AssetDir.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/String16.h>
+#include <utils/ZipFileRO.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class Asset;        // fwd decl for things that include Asset.h first
+class ResTable;
+struct ResTable_config;
+
+/*
+ * Every application that uses assets needs one instance of this.  A
+ * single instance may be shared across multiple threads, and a single
+ * thread may have more than one instance (the latter is discouraged).
+ *
+ * The purpose of the AssetManager is to create Asset objects.  To do
+ * this efficiently it may cache information about the locations of
+ * files it has seen.  This can be controlled with the "cacheMode"
+ * argument.
+ *
+ * The asset hierarchy may be examined like a filesystem, using
+ * AssetDir objects to peruse a single directory.
+ */
+class AssetManager {
+public:
+    typedef enum CacheMode {
+        CACHE_UNKNOWN = 0,
+        CACHE_OFF,          // don't try to cache file locations
+        CACHE_DEFER,        // construct cache as pieces are needed
+        //CACHE_SCAN,         // scan full(!) asset hierarchy at init() time
+    } CacheMode;
+
+    AssetManager(CacheMode cacheMode = CACHE_OFF);
+    virtual ~AssetManager(void);
+
+    static int32_t getGlobalCount();
+    
+    /*                                                                       
+     * Add a new source for assets.  This can be called multiple times to
+     * look in multiple places for assets.  It can be either a directory (for
+     * finding assets as raw files on the disk) or a ZIP file.  This newly
+     * added asset path will be examined first when searching for assets,
+     * before any that were previously added.
+     *
+     * Returns "true" on success, "false" on failure.  If 'cookie' is non-NULL,
+     * then on success, *cookie is set to the value corresponding to the
+     * newly-added asset source.
+     */
+    bool addAssetPath(const String8& path, void** cookie);
+
+    /*                                                                       
+     * Convenience for adding the standard system assets.  Uses the
+     * ANDROID_ROOT environment variable to find them.
+     */
+    bool addDefaultAssets();
+
+    /*                                                                       
+     * Iterate over the asset paths in this manager.  (Previously
+     * added via addAssetPath() and addDefaultAssets().)  On first call,
+     * 'cookie' must be NULL, resulting in the first cookie being returned.
+     * Each next cookie will be returned there-after, until NULL indicating
+     * the end has been reached.
+     */
+    void* nextAssetPath(void* cookie) const;
+
+    /*                                                                       
+     * Return an asset path in the manager.  'which' must be between 0 and
+     * countAssetPaths().
+     */
+    String8 getAssetPath(void* cookie) const;
+
+    /*
+     * Set the current locale and vendor.  The locale can change during
+     * the lifetime of an AssetManager if the user updates the device's
+     * language setting.  The vendor is less likely to change.
+     *
+     * Pass in NULL to indicate no preference.
+     */
+    void setLocale(const char* locale);
+    void setVendor(const char* vendor);
+
+    /*
+     * Choose screen orientation for resources values returned.
+     */
+    void setConfiguration(const ResTable_config& config, const char* locale = NULL);
+
+    typedef Asset::AccessMode AccessMode;       // typing shortcut
+
+    /*
+     * Open an asset.
+     *
+     * This will search through locale-specific and vendor-specific
+     * directories and packages to find the file.
+     *
+     * The object returned does not depend on the AssetManager.  It should
+     * be freed by calling Asset::close().
+     */
+    Asset* open(const char* fileName, AccessMode mode);
+
+    /*
+     * Open a non-asset file as an asset.
+     *
+     * This is for opening files that are included in an asset package
+     * but aren't assets.  These sit outside the usual "locale/vendor"
+     * path hierarchy, and will not be seen by "AssetDir" or included
+     * in our filename cache.
+     */
+    Asset* openNonAsset(const char* fileName, AccessMode mode);
+
+    /*
+     * Explicit non-asset file.  The file explicitly named by the cookie (the
+     * resource set to look in) and fileName will be opened and returned.
+     */
+    Asset* openNonAsset(void* cookie, const char* fileName, AccessMode mode);
+
+    /*
+     * Open a directory within the asset hierarchy.
+     *
+     * The contents of the directory are an amalgam of vendor-specific,
+     * locale-specific, and generic assets stored loosely or in asset
+     * packages.  Depending on the cache setting and previous accesses,
+     * this call may incur significant disk overhead.
+     *
+     * To open the top-level directory, pass in "".
+     */
+    AssetDir* openDir(const char* dirName);
+
+    /*
+     * Get the type of a file in the asset hierarchy.  They will either
+     * be "regular" or "directory".  [Currently only works for "regular".]
+     *
+     * Can also be used as a quick test for existence of a file.
+     */
+    FileType getFileType(const char* fileName);
+
+    /*                                                                       
+     * Return the complete resource table to find things in the package.
+     */
+    const ResTable& getResources(bool required = true) const;
+
+    /*
+     * Discard cached filename information.  This only needs to be called
+     * if somebody has updated the set of "loose" files, and we want to
+     * discard our cached notion of what's where.
+     */
+    void purge(void) { purgeFileNameCacheLocked(); }
+
+    /*
+     * Return true if the files this AssetManager references are all
+     * up-to-date (have not been changed since it was created).  If false
+     * is returned, you will need to create a new AssetManager to get
+     * the current data.
+     */
+    bool isUpToDate();
+    
+    /**
+     * Get the known locales for this asset manager object.
+     */
+    void getLocales(Vector<String8>* locales) const;
+
+private:
+    struct asset_path
+    {
+        String8 path;
+        FileType type;
+    };
+
+    Asset* openInPathLocked(const char* fileName, AccessMode mode,
+        const asset_path& path);
+    Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,
+        const asset_path& path);
+    Asset* openInLocaleVendorLocked(const char* fileName, AccessMode mode,
+        const asset_path& path, const char* locale, const char* vendor);
+    String8 createPathNameLocked(const asset_path& path, const char* locale,
+        const char* vendor);
+    String8 createPathNameLocked(const asset_path& path, const char* rootDir);
+    String8 createZipSourceNameLocked(const String8& zipFileName,
+        const String8& dirName, const String8& fileName);
+
+    ZipFileRO* getZipFileLocked(const asset_path& path);
+    Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode);
+    Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile,
+        const ZipEntryRO entry, AccessMode mode, const String8& entryName);
+
+    bool scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const asset_path& path, const char* rootDir, const char* dirName);
+    SortedVector<AssetDir::FileInfo>* scanDirLocked(const String8& path);
+    bool scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const asset_path& path, const char* rootDir, const char* dirName);
+    void mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const SortedVector<AssetDir::FileInfo>* pContents);
+
+    void loadFileNameCacheLocked(void);
+    void fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const char* dirName);
+    bool fncScanAndMergeDirLocked(
+        SortedVector<AssetDir::FileInfo>* pMergedInfo,
+        const asset_path& path, const char* locale, const char* vendor,
+        const char* dirName);
+    void purgeFileNameCacheLocked(void);
+
+    const ResTable* getResTable(bool required = true) const;
+    void setLocaleLocked(const char* locale);
+    void updateResourceParamsLocked() const;
+
+    class SharedZip : public RefBase {
+    public:
+        static sp<SharedZip> get(const String8& path);
+
+        ZipFileRO* getZip();
+
+        Asset* getResourceTableAsset();
+        Asset* setResourceTableAsset(Asset* asset);
+
+        bool isUpToDate();
+        
+    protected:
+        ~SharedZip();
+
+    private:
+        SharedZip(const String8& path, time_t modWhen);
+        SharedZip(); // <-- not implemented
+
+        String8 mPath;
+        ZipFileRO* mZipFile;
+        time_t mModWhen;
+
+        Asset* mResourceTableAsset;
+
+        static Mutex gLock;
+        static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
+    };
+
+    /*
+     * Manage a set of Zip files.  For each file we need a pointer to the
+     * ZipFile and a time_t with the file's modification date.
+     *
+     * We currently only have two zip files (current app, "common" app).
+     * (This was originally written for 8, based on app/locale/vendor.)
+     */
+    class ZipSet {
+    public:
+        ZipSet(void);
+        ~ZipSet(void);
+
+        /*
+         * Return a ZipFileRO structure for a ZipFileRO with the specified
+         * parameters.
+         */
+        ZipFileRO* getZip(const String8& path);
+
+        Asset* getZipResourceTable(const String8& path);
+        Asset* setZipResourceTable(const String8& path, Asset* asset);
+
+        // generate path, e.g. "common/en-US-noogle.zip"
+        static String8 getPathName(const char* path);
+
+        bool isUpToDate();
+        
+    private:
+        void closeZip(int idx);
+
+        int getIndex(const String8& zip) const;
+        mutable Vector<String8> mZipPath;
+        mutable Vector<sp<SharedZip> > mZipFile;
+    };
+
+    // Protect all internal state.
+    mutable Mutex   mLock;
+
+    ZipSet          mZipSet;
+
+    Vector<asset_path> mAssetPaths;
+    char*           mLocale;
+    char*           mVendor;
+
+    mutable ResTable* mResources;
+    ResTable_config* mConfig;
+
+    /*
+     * Cached data for "loose" files.  This lets us avoid poking at the
+     * filesystem when searching for loose assets.  Each entry is the
+     * "extended partial" path, e.g. "default/default/foo/bar.txt".  The
+     * full set of files is present, including ".EXCLUDE" entries.
+     *
+     * We do not cache directory names.  We don't retain the ".gz",
+     * because to our clients "foo" and "foo.gz" both look like "foo".
+     */
+    CacheMode       mCacheMode;         // is the cache enabled?
+    bool            mCacheValid;        // clear when locale or vendor changes
+    SortedVector<AssetDir::FileInfo> mCache;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ASSETMANAGER_H
diff --git a/include/utils/Atomic.h b/include/utils/Atomic.h
new file mode 100644
index 0000000..7eb476c
--- /dev/null
+++ b/include/utils/Atomic.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_UTILS_ATOMIC_H
+#define ANDROID_UTILS_ATOMIC_H
+
+#include <cutils/atomic.h>
+
+#endif // ANDROID_UTILS_ATOMIC_H
diff --git a/include/utils/Binder.h b/include/utils/Binder.h
new file mode 100644
index 0000000..b5b8d98
--- /dev/null
+++ b/include/utils/Binder.h
@@ -0,0 +1,103 @@
+/*
+ * 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_BINDER_H
+#define ANDROID_BINDER_H
+
+#include <utils/IBinder.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class BBinder : public IBinder
+{
+public:
+                        BBinder();
+
+    virtual String16    getInterfaceDescriptor() const;
+    virtual bool        isBinderAlive() const;
+    virtual status_t    pingBinder();
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+    virtual status_t    transact(   uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+
+    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
+                                    void* cookie = NULL,
+                                    uint32_t flags = 0);
+
+    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
+                                        void* cookie = NULL,
+                                        uint32_t flags = 0,
+                                        wp<DeathRecipient>* outRecipient = NULL);
+
+    virtual void        attachObject(   const void* objectID,
+                                        void* object,
+                                        void* cleanupCookie,
+                                        object_cleanup_func func);
+    virtual void*       findObject(const void* objectID) const;
+    virtual void        detachObject(const void* objectID);
+
+    virtual BBinder*    localBinder();
+
+protected:
+    virtual             ~BBinder();
+
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+
+private:
+                        BBinder(const BBinder& o);
+            BBinder&    operator=(const BBinder& o);
+
+    class Extras;
+
+            Extras*     mExtras;
+            void*       mReserved0;
+};
+
+// ---------------------------------------------------------------------------
+
+class BpRefBase : public virtual RefBase
+{
+protected:
+                            BpRefBase(const sp<IBinder>& o);
+    virtual                 ~BpRefBase();
+    virtual void            onFirstRef();
+    virtual void            onLastStrongRef(const void* id);
+    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
+
+    inline  IBinder*        remote()                { return mRemote; }
+    inline  IBinder*        remote() const          { return mRemote; }
+
+private:
+                            BpRefBase(const BpRefBase& o);
+    BpRefBase&              operator=(const BpRefBase& o);
+
+    IBinder* const          mRemote;
+    RefBase::weakref_type*  mRefs;
+    volatile int32_t        mState;
+};
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_BINDER_H
diff --git a/include/utils/BpBinder.h b/include/utils/BpBinder.h
new file mode 100644
index 0000000..7b96e29
--- /dev/null
+++ b/include/utils/BpBinder.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_BPBINDER_H
+#define ANDROID_BPBINDER_H
+
+#include <utils/IBinder.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class BpBinder : public IBinder
+{
+public:
+                        BpBinder(int32_t handle);
+
+    inline  int32_t     handle() const { return mHandle; }
+
+    virtual String16    getInterfaceDescriptor() const;
+    virtual bool        isBinderAlive() const;
+    virtual status_t    pingBinder();
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+    virtual status_t    transact(   uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+
+    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
+                                    void* cookie = NULL,
+                                    uint32_t flags = 0);
+    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
+                                        void* cookie = NULL,
+                                        uint32_t flags = 0,
+                                        wp<DeathRecipient>* outRecipient = NULL);
+
+    virtual void        attachObject(   const void* objectID,
+                                        void* object,
+                                        void* cleanupCookie,
+                                        object_cleanup_func func);
+    virtual void*       findObject(const void* objectID) const;
+    virtual void        detachObject(const void* objectID);
+
+    virtual BpBinder*   remoteBinder();
+
+            status_t    setConstantData(const void* data, size_t size);
+            void        sendObituary();
+
+    class ObjectManager
+    {
+    public:
+                    ObjectManager();
+                    ~ObjectManager();
+
+        void        attach( const void* objectID,
+                            void* object,
+                            void* cleanupCookie,
+                            IBinder::object_cleanup_func func);
+        void*       find(const void* objectID) const;
+        void        detach(const void* objectID);
+
+        void        kill();
+
+    private:
+                    ObjectManager(const ObjectManager&);
+        ObjectManager& operator=(const ObjectManager&);
+
+        struct entry_t
+        {
+            void* object;
+            void* cleanupCookie;
+            IBinder::object_cleanup_func func;
+        };
+
+        KeyedVector<const void*, entry_t> mObjects;
+    };
+
+protected:
+    virtual             ~BpBinder();
+    virtual void        onFirstRef();
+    virtual void        onLastStrongRef(const void* id);
+    virtual bool        onIncStrongAttempted(uint32_t flags, const void* id);
+
+private:
+    const   int32_t             mHandle;
+
+    struct Obituary {
+        wp<DeathRecipient> recipient;
+        void* cookie;
+        uint32_t flags;
+    };
+
+            void                reportOneDeath(const Obituary& obit);
+
+    mutable Mutex               mLock;
+            volatile int32_t    mAlive;
+            volatile int32_t    mObitsSent;
+            Vector<Obituary>*   mObituaries;
+            ObjectManager       mObjects;
+            Parcel*             mConstantData;
+};
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_BPBINDER_H
diff --git a/include/utils/Buffer.h b/include/utils/Buffer.h
new file mode 100644
index 0000000..8e22b0f
--- /dev/null
+++ b/include/utils/Buffer.h
@@ -0,0 +1,107 @@
+/*
+ * 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/BufferedTextOutput.h b/include/utils/BufferedTextOutput.h
new file mode 100644
index 0000000..69c6240
--- /dev/null
+++ b/include/utils/BufferedTextOutput.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_BUFFEREDTEXTOUTPUT_H
+#define ANDROID_BUFFEREDTEXTOUTPUT_H
+
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+#include <cutils/uio.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class BufferedTextOutput : public TextOutput
+{
+public:
+    //** Flags for constructor */
+    enum {
+        MULTITHREADED = 0x0001
+    };
+    
+                        BufferedTextOutput(uint32_t flags = 0);
+    virtual             ~BufferedTextOutput();
+    
+    virtual status_t    print(const char* txt, size_t len);
+    virtual void        moveIndent(int delta);
+    
+    virtual void        pushBundle();
+    virtual void        popBundle();
+    
+protected:
+    virtual status_t    writeLines(const struct iovec& vec, size_t N) = 0;
+
+private:
+    struct BufferState;
+    struct ThreadState;
+    
+    static  ThreadState*getThreadState();
+    static  void        threadDestructor(void *st);
+    
+            BufferState*getBuffer() const;
+            
+    uint32_t            mFlags;
+    const int32_t       mSeq;
+    const int32_t       mIndex;
+    
+    Mutex               mLock;
+    BufferState*        mGlobalState;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_BUFFEREDTEXTOUTPUT_H
diff --git a/include/utils/ByteOrder.h b/include/utils/ByteOrder.h
new file mode 100644
index 0000000..4c06067
--- /dev/null
+++ b/include/utils/ByteOrder.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_UTILS_BYTE_ORDER_H
+#define _LIBS_UTILS_BYTE_ORDER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#ifdef HAVE_WINSOCK
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+
+/*
+ * These macros are like the hton/ntoh byte swapping macros,
+ * except they allow you to swap to and from the "device" byte
+ * order.  The device byte order is the endianness of the target
+ * device -- for the ARM CPUs we use today, this is little endian.
+ *
+ * Note that the byte swapping functions have not been optimized
+ * much; performance is currently not an issue for them since the
+ * intent is to allow us to avoid byte swapping on the device.
+ */
+
+#define DEVICE_BYTE_ORDER LITTLE_ENDIAN
+
+#if BYTE_ORDER == DEVICE_BYTE_ORDER
+
+#define	dtohl(x)	(x)
+#define	dtohs(x)	(x)
+#define	htodl(x)	(x)
+#define	htods(x)	(x)
+
+#else
+
+static inline uint32_t android_swap_long(uint32_t v)
+{
+    return (v<<24) | ((v<<8)&0x00FF0000) | ((v>>8)&0x0000FF00) | (v>>24);
+}
+
+static inline uint16_t android_swap_short(uint16_t v)
+{
+    return (v<<8) | (v>>8);
+}
+
+#define	dtohl(x)	(android_swap_long(x))
+#define	dtohs(x)	(android_swap_short(x))
+#define	htodl(x)	(android_swap_long(x))
+#define	htods(x)	(android_swap_short(x))
+
+#endif
+
+#endif // _LIBS_UTILS_BYTE_ORDER_H
diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h
new file mode 100644
index 0000000..c2c8ce5
--- /dev/null
+++ b/include/utils/CallStack.h
@@ -0,0 +1,76 @@
+/*
+ * 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_CALLSTACK_H
+#define ANDROID_CALLSTACK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/String8.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class CallStack
+{
+public:
+    enum {
+        MAX_DEPTH = 31
+    };
+
+    CallStack();
+    CallStack(const CallStack& rhs);
+    ~CallStack();
+
+    CallStack& operator = (const CallStack& rhs);
+    
+    bool operator == (const CallStack& rhs) const;
+    bool operator != (const CallStack& rhs) const;
+    bool operator < (const CallStack& rhs) const;
+    bool operator >= (const CallStack& rhs) const;
+    bool operator > (const CallStack& rhs) const;
+    bool operator <= (const CallStack& rhs) const;
+    
+    const void* operator [] (int index) const;
+    
+    void clear();
+
+    void update(int32_t ignoreDepth=0, int32_t maxDepth=MAX_DEPTH);
+
+    // Dump a stack trace to the log
+    void dump(const char* prefix = 0) const;
+
+    // Return a string (possibly very long) containing the complete stack trace
+    String8 toString(const char* prefix = 0) const;
+    
+    size_t size() const { return mCount; }
+
+private:
+    // Internal helper function
+    String8 toStringSingleLevel(const char* prefix, int32_t level) const;
+
+    size_t      mCount;
+    const void* mStack[MAX_DEPTH];
+};
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_CALLSTACK_H
diff --git a/include/utils/Debug.h b/include/utils/Debug.h
new file mode 100644
index 0000000..a662b9c
--- /dev/null
+++ b/include/utils/Debug.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Debugging tools.  These should be able to be stripped
+// in release builds.
+//
+#ifndef ANDROID_DEBUG_H
+#define ANDROID_DEBUG_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace android {
+
+template<bool> struct CompileTimeAssert;
+template<> struct CompileTimeAssert<true> {};
+
+const char* stringForIndent(int32_t indentLevel);
+
+typedef void (*debugPrintFunc)(void* cookie, const char* txt);
+
+void printTypeCode(uint32_t typeCode,
+    debugPrintFunc func = 0, void* cookie = 0);
+void printHexData(int32_t indent, const void *buf, size_t length,
+    size_t bytesPerLine=16, int32_t singleLineBytesCutoff=16,
+    size_t alignment=0, bool cArrayStyle=false,
+    debugPrintFunc func = 0, void* cookie = 0);
+
+}; // namespace android
+
+#endif // ANDROID_DEBUG_H
diff --git a/include/utils/Endian.h b/include/utils/Endian.h
new file mode 100644
index 0000000..19f2504
--- /dev/null
+++ b/include/utils/Endian.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Android endian-ness defines.
+//
+#ifndef _LIBS_UTILS_ENDIAN_H
+#define _LIBS_UTILS_ENDIAN_H
+
+#if defined(HAVE_ENDIAN_H)
+
+#include <endian.h>
+
+#else /*not HAVE_ENDIAN_H*/
+
+#define __BIG_ENDIAN 0x1000
+#define __LITTLE_ENDIAN 0x0001
+
+#if defined(HAVE_LITTLE_ENDIAN)
+# define __BYTE_ORDER __LITTLE_ENDIAN
+#else
+# define __BYTE_ORDER __BIG_ENDIAN
+#endif
+
+#endif /*not HAVE_ENDIAN_H*/
+
+#endif /*_LIBS_UTILS_ENDIAN_H*/
diff --git a/include/utils/Errors.h b/include/utils/Errors.h
new file mode 100644
index 0000000..1bf9e6f
--- /dev/null
+++ b/include/utils/Errors.h
@@ -0,0 +1,87 @@
+/*
+ * 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_ERRORS_H
+#define ANDROID_ERRORS_H
+
+#include <sys/types.h>
+#include <errno.h>
+
+namespace android {
+
+// use this type to return error codes
+#ifdef HAVE_MS_C_RUNTIME
+typedef int         status_t;
+#else
+typedef int32_t     status_t;
+#endif
+
+/* the MS C runtime lacks a few error codes */
+
+/*
+ * Error codes. 
+ * All error codes are negative values.
+ */
+
+// Win32 #defines NO_ERROR as well.  It has the same value, so there's no
+// real conflict, though it's a bit awkward.
+#ifdef _WIN32
+# undef NO_ERROR
+#endif
+ 
+enum {
+    OK                = 0,    // Everything's swell.
+    NO_ERROR          = 0,    // No errors.
+    
+    UNKNOWN_ERROR       = 0x80000000,
+
+    NO_MEMORY           = -ENOMEM,
+    INVALID_OPERATION   = -ENOSYS,
+    BAD_VALUE           = -EINVAL,
+    BAD_TYPE            = 0x80000001,
+    NAME_NOT_FOUND      = -ENOENT,
+    PERMISSION_DENIED   = -EPERM,
+    NO_INIT             = -ENODEV,
+    ALREADY_EXISTS      = -EEXIST,
+    DEAD_OBJECT         = -EPIPE,
+    FAILED_TRANSACTION  = 0x80000002,
+    JPARKS_BROKE_IT     = -EPIPE,
+#if !defined(HAVE_MS_C_RUNTIME)
+    BAD_INDEX           = -EOVERFLOW,
+    NOT_ENOUGH_DATA     = -ENODATA,
+    WOULD_BLOCK         = -EWOULDBLOCK, 
+    TIMED_OUT           = -ETIME,
+    UNKNOWN_TRANSACTION = -EBADMSG,
+#else    
+    BAD_INDEX           = -E2BIG,
+    NOT_ENOUGH_DATA     = 0x80000003,
+    WOULD_BLOCK         = 0x80000004,
+    TIMED_OUT           = 0x80000005,
+    UNKNOWN_TRANSACTION = 0x80000006,
+#endif    
+};
+
+// Restore define; enumeration is in "android" namespace, so the value defined
+// there won't work for Win32 code in a different namespace.
+#ifdef _WIN32
+# define NO_ERROR 0L
+#endif
+
+}; // namespace android
+    
+// ---------------------------------------------------------------------------
+    
+#endif // ANDROID_ERRORS_H
diff --git a/include/utils/FileMap.h b/include/utils/FileMap.h
new file mode 100644
index 0000000..8dfd3be
--- /dev/null
+++ b/include/utils/FileMap.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Encapsulate a shared file mapping.
+//
+#ifndef __LIBS_FILE_MAP_H
+#define __LIBS_FILE_MAP_H
+
+#include <sys/types.h>
+
+#ifdef HAVE_WIN32_FILEMAP
+#include <windows.h>
+#endif
+
+namespace android {
+
+/*
+ * This represents a memory-mapped file.  It might be the entire file or
+ * only part of it.  This requires a little bookkeeping because the mapping
+ * needs to be aligned on page boundaries, and in some cases we'd like to
+ * have multiple references to the mapped area without creating additional
+ * maps.
+ *
+ * This always uses MAP_SHARED.
+ *
+ * TODO: we should be able to create a new FileMap that is a subset of
+ * an existing FileMap and shares the underlying mapped pages.  Requires
+ * completing the refcounting stuff and possibly introducing the notion
+ * of a FileMap hierarchy.
+ */
+class FileMap {
+public:
+    FileMap(void);
+
+    /*
+     * Create a new mapping on an open file.
+     *
+     * Closing the file descriptor does not unmap the pages, so we don't
+     * claim ownership of the fd.
+     *
+     * Returns "false" on failure.
+     */
+    bool create(const char* origFileName, int fd,
+                off_t offset, size_t length, bool readOnly);
+
+    /*
+     * Return the name of the file this map came from, if known.
+     */
+    const char* getFileName(void) const { return mFileName; }
+    
+    /*
+     * Get a pointer to the piece of the file we requested.
+     */
+    void* getDataPtr(void) const { return mDataPtr; }
+
+    /*
+     * Get the length we requested.
+     */
+    size_t getDataLength(void) const { return mDataLength; }
+
+    /*
+     * Get the data offset used to create this map.
+     */
+    off_t getDataOffset(void) const { return mDataOffset; }
+
+    /*
+     * Get a "copy" of the object.
+     */
+    FileMap* acquire(void) { mRefCount++; return this; }
+
+    /*
+     * Call this when mapping is no longer needed.
+     */
+    void release(void) {
+        if (--mRefCount <= 0)
+            delete this;
+    }
+
+    /*
+     * This maps directly to madvise() values, but allows us to avoid
+     * including <sys/mman.h> everywhere.
+     */
+    enum MapAdvice {
+        NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED
+    };
+
+    /*
+     * Apply an madvise() call to the entire file.
+     *
+     * Returns 0 on success, -1 on failure.
+     */
+    int advise(MapAdvice advice);
+
+protected:
+    // don't delete objects; call release()
+    ~FileMap(void);
+
+private:
+    // these are not implemented
+    FileMap(const FileMap& src);
+    const FileMap& operator=(const FileMap& src);
+
+    int         mRefCount;      // reference count
+    char*       mFileName;      // original file name, if known
+    void*       mBasePtr;       // base of mmap area; page aligned
+    size_t      mBaseLength;    // length, measured from "mBasePtr"
+    off_t       mDataOffset;    // offset used when map was created
+    void*       mDataPtr;       // start of requested data, offset from base
+    size_t      mDataLength;    // length, measured from "mDataPtr"
+#ifdef HAVE_WIN32_FILEMAP
+    HANDLE      mFileHandle;    // Win32 file handle
+    HANDLE      mFileMapping;   // Win32 file mapping handle
+#endif
+
+    static long mPageSize;
+};
+
+}; // namespace android
+
+#endif // __LIBS_FILE_MAP_H
diff --git a/include/utils/IBinder.h b/include/utils/IBinder.h
new file mode 100644
index 0000000..7370330
--- /dev/null
+++ b/include/utils/IBinder.h
@@ -0,0 +1,159 @@
+/*
+ * 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_IBINDER_H
+#define ANDROID_IBINDER_H
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+
+#define B_PACK_CHARS(c1, c2, c3, c4) \
+    ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class BBinder;
+class BpBinder;
+class IInterface;
+class Parcel;
+
+/**
+ * Base class and low-level protocol for a remotable object.
+ * You can derive from this class to create an object for which other
+ * processes can hold references to it.  Communication between processes
+ * (method calls, property get and set) is down through a low-level
+ * protocol implemented on top of the transact() API.
+ */
+class IBinder : public virtual RefBase
+{
+public:
+    enum {
+        FIRST_CALL_TRANSACTION  = 0x00000001,
+        LAST_CALL_TRANSACTION   = 0x00ffffff,
+
+        PING_TRANSACTION        = B_PACK_CHARS('_','P','N','G'),
+        DUMP_TRANSACTION        = B_PACK_CHARS('_','D','M','P'),
+        INTERFACE_TRANSACTION   = B_PACK_CHARS('_', 'N', 'T', 'F'),
+
+        // Corresponds to tfOneWay -- an asynchronous call.
+        FLAG_ONEWAY             = 0x00000001
+    };
+
+    inline                  IBinder() { }
+
+    /**
+     * Check if this IBinder implements the interface named by
+     * @a descriptor.  If it does, the base pointer to it is returned,
+     * which you can safely static_cast<> to the concrete C++ interface.
+     */
+    virtual sp<IInterface>  queryLocalInterface(const String16& descriptor);
+
+    /**
+     * Return the canonical name of the interface provided by this IBinder
+     * object.
+     */
+    virtual String16        getInterfaceDescriptor() const = 0;
+
+    virtual bool            isBinderAlive() const = 0;
+    virtual status_t        pingBinder() = 0;
+    virtual status_t        dump(int fd, const Vector<String16>& args) = 0;
+
+    virtual status_t        transact(   uint32_t code,
+                                        const Parcel& data,
+                                        Parcel* reply,
+                                        uint32_t flags = 0) = 0;
+
+    /**
+     * This method allows you to add data that is transported through
+     * IPC along with your IBinder pointer.  When implementing a Binder
+     * object, override it to write your desired data in to @a outData.
+     * You can then call getConstantData() on your IBinder to retrieve
+     * that data, from any process.  You MUST return the number of bytes
+     * written in to the parcel (including padding).
+     */
+    class DeathRecipient : public virtual RefBase
+    {
+    public:
+        virtual void binderDied(const wp<IBinder>& who) = 0;
+    };
+
+    /**
+     * Register the @a recipient for a notification if this binder
+     * goes away.  If this binder object unexpectedly goes away
+     * (typically because its hosting process has been killed),
+     * then DeathRecipient::binderDied() will be called with a referene
+     * to this.
+     *
+     * The @a cookie is optional -- if non-NULL, it should be a
+     * memory address that you own (that is, you know it is unique).
+     *
+     * @note You will only receive death notifications for remote binders,
+     * as local binders by definition can't die without you dying as well.
+     * Trying to use this function on a local binder will result in an
+     * INVALID_OPERATION code being returned and nothing happening.
+     *
+     * @note This link always holds a weak reference to its recipient.
+     *
+     * @note You will only receive a weak reference to the dead
+     * binder.  You should not try to promote this to a strong reference.
+     * (Nor should you need to, as there is nothing useful you can
+     * directly do with it now that it has passed on.)
+     */
+    virtual status_t        linkToDeath(const sp<DeathRecipient>& recipient,
+                                        void* cookie = NULL,
+                                        uint32_t flags = 0) = 0;
+
+    /**
+     * Remove a previously registered death notification.
+     * The @a recipient will no longer be called if this object
+     * dies.  The @a cookie is optional.  If non-NULL, you can
+     * supply a NULL @a recipient, and the recipient previously
+     * added with that cookie will be unlinked.
+     */
+    virtual status_t        unlinkToDeath(  const wp<DeathRecipient>& recipient,
+                                            void* cookie = NULL,
+                                            uint32_t flags = 0,
+                                            wp<DeathRecipient>* outRecipient = NULL) = 0;
+
+    virtual bool            checkSubclass(const void* subclassID) const;
+
+    typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie);
+
+    virtual void            attachObject(   const void* objectID,
+                                            void* object,
+                                            void* cleanupCookie,
+                                            object_cleanup_func func) = 0;
+    virtual void*           findObject(const void* objectID) const = 0;
+    virtual void            detachObject(const void* objectID) = 0;
+
+    virtual BBinder*        localBinder();
+    virtual BpBinder*       remoteBinder();
+
+protected:
+    inline virtual          ~IBinder() { }
+
+private:
+};
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_IBINDER_H
diff --git a/include/utils/IInterface.h b/include/utils/IInterface.h
new file mode 100644
index 0000000..959722a
--- /dev/null
+++ b/include/utils/IInterface.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_IINTERFACE_H
+#define ANDROID_IINTERFACE_H
+
+#include <utils/Binder.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IInterface : public virtual RefBase
+{
+public:
+            sp<IBinder>         asBinder();
+            sp<const IBinder>   asBinder() const;
+
+protected:
+    virtual IBinder*            onAsBinder() = 0;
+};
+
+// ----------------------------------------------------------------------
+
+template<typename INTERFACE>
+inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
+{
+    return INTERFACE::asInterface(obj);
+}
+
+// ----------------------------------------------------------------------
+
+template<typename INTERFACE>
+class BnInterface : public INTERFACE, public BBinder
+{
+public:
+    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
+    virtual String16            getInterfaceDescriptor() const;
+
+protected:
+    virtual IBinder*            onAsBinder();
+};
+
+// ----------------------------------------------------------------------
+
+template<typename INTERFACE>
+class BpInterface : public INTERFACE, public BpRefBase
+{
+public:
+                                BpInterface(const sp<IBinder>& remote);
+
+protected:
+    virtual IBinder*            onAsBinder();
+};
+
+// ----------------------------------------------------------------------
+
+#define DECLARE_META_INTERFACE(INTERFACE)                               \
+    static const String16 descriptor;                                   \
+    static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj);        \
+    virtual String16 getInterfaceDescriptor() const;                    \
+
+#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
+    const String16 I##INTERFACE::descriptor(NAME);                      \
+    String16 I##INTERFACE::getInterfaceDescriptor() const {             \
+        return I##INTERFACE::descriptor;                                \
+    }                                                                   \
+    sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)  \
+    {                                                                   \
+        sp<I##INTERFACE> intr;                                          \
+        if (obj != NULL) {                                              \
+            intr = static_cast<I##INTERFACE*>(                          \
+                obj->queryLocalInterface(                               \
+                        I##INTERFACE::descriptor).get());               \
+            if (intr == NULL) {                                         \
+                intr = new Bp##INTERFACE(obj);                          \
+            }                                                           \
+        }                                                               \
+        return intr;                                                    \
+    }                                                                   \
+
+// ----------------------------------------------------------------------
+// No user-servicable parts after this...
+
+template<typename INTERFACE>
+inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
+        const String16& _descriptor)
+{
+    if (_descriptor == INTERFACE::descriptor) return this;
+    return NULL;
+}
+
+template<typename INTERFACE>
+inline String16 BnInterface<INTERFACE>::getInterfaceDescriptor() const
+{
+    return INTERFACE::getInterfaceDescriptor();
+}
+
+template<typename INTERFACE>
+IBinder* BnInterface<INTERFACE>::onAsBinder()
+{
+    return this;
+}
+
+template<typename INTERFACE>
+inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
+    : BpRefBase(remote)
+{
+}
+
+template<typename INTERFACE>
+inline IBinder* BpInterface<INTERFACE>::onAsBinder()
+{
+    return remote();
+}
+    
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IINTERFACE_H
diff --git a/include/utils/IMemory.h b/include/utils/IMemory.h
new file mode 100644
index 0000000..35a3fd7
--- /dev/null
+++ b/include/utils/IMemory.h
@@ -0,0 +1,94 @@
+/*
+ * 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_IMEMORY_H
+#define ANDROID_IMEMORY_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <utils/IInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IMemoryHeap : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(MemoryHeap);
+
+    // flags returned by getFlags()
+    enum {
+        READ_ONLY   = 0x00000001,
+        MAP_ONCE    = 0x00000002
+    };
+
+    virtual int         getHeapID() const = 0;
+    virtual void*       getBase() const = 0;
+    virtual size_t      getSize() const = 0;
+    virtual uint32_t    getFlags() const = 0;
+
+    // these are there just for backward source compatibility
+    int32_t heapID() const { return getHeapID(); }
+    void*   base() const  { return getBase(); }
+    size_t  virtualSize() const { return getSize(); }
+};
+
+class BnMemoryHeap : public BnInterface<IMemoryHeap>
+{
+public:
+    virtual status_t onTransact( 
+            uint32_t code,
+            const Parcel& data,
+            Parcel* reply,
+            uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+class IMemory : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(Memory);
+
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const = 0;
+
+    // helpers
+    void* fastPointer(const sp<IBinder>& heap, ssize_t offset) const;
+    void* pointer() const;
+    size_t size() const;
+    ssize_t offset() const;
+};
+
+class BnMemory : public BnInterface<IMemory>
+{
+public:
+    virtual status_t onTransact(
+            uint32_t code,
+            const Parcel& data,
+            Parcel* reply,
+            uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IMEMORY_H
diff --git a/include/utils/IPCThreadState.h b/include/utils/IPCThreadState.h
new file mode 100644
index 0000000..47043b8
--- /dev/null
+++ b/include/utils/IPCThreadState.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_IPC_THREAD_STATE_H
+#define ANDROID_IPC_THREAD_STATE_H
+
+#include <utils/Errors.h>
+#include <utils/Parcel.h>
+#include <utils/ProcessState.h>
+
+#ifdef HAVE_WIN32_PROC
+typedef  int  uid_t;
+#endif
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class IPCThreadState
+{
+public:
+    static  IPCThreadState*     self();
+    
+            sp<ProcessState>    process();
+            
+            status_t            clearLastError();
+
+            int                 getCallingPid();
+            int                 getCallingUid();
+            
+            int64_t             clearCallingIdentity();
+            void                restoreCallingIdentity(int64_t token);
+            
+            void                flushCommands();
+
+            void                joinThreadPool(bool isMain = true);
+            
+            // Stop the local process.
+            void                stopProcess(bool immediate = true);
+            
+            status_t            transact(int32_t handle,
+                                         uint32_t code, const Parcel& data,
+                                         Parcel* reply, uint32_t flags);
+
+            void                incStrongHandle(int32_t handle);
+            void                decStrongHandle(int32_t handle);
+            void                incWeakHandle(int32_t handle);
+            void                decWeakHandle(int32_t handle);
+            status_t            attemptIncStrongHandle(int32_t handle);
+    static  void                expungeHandle(int32_t handle, IBinder* binder);
+            status_t            requestDeathNotification(   int32_t handle,
+                                                            BpBinder* proxy); 
+            status_t            clearDeathNotification( int32_t handle,
+                                                        BpBinder* proxy); 
+
+    static  void                shutdown();
+    
+private:
+                                IPCThreadState();
+                                ~IPCThreadState();
+
+            status_t            sendReply(const Parcel& reply, uint32_t flags);
+            status_t            waitForResponse(Parcel *reply,
+                                                status_t *acquireResult=NULL);
+            status_t            talkWithDriver(bool doReceive=true);
+            status_t            writeTransactionData(int32_t cmd,
+                                                     uint32_t binderFlags,
+                                                     int32_t handle,
+                                                     uint32_t code,
+                                                     const Parcel& data,
+                                                     status_t* statusBuffer);
+            status_t            executeCommand(int32_t command);
+            
+            void                clearCaller();
+            
+    static  void                threadDestructor(void *st);
+    static  void                freeBuffer(Parcel* parcel,
+                                           const uint8_t* data, size_t dataSize,
+                                           const size_t* objects, size_t objectsSize,
+                                           void* cookie);
+    
+    const   sp<ProcessState>    mProcess;
+                                
+            Parcel              mIn;
+            Parcel              mOut;
+            status_t            mLastError;
+            pid_t               mCallingPid;
+            uid_t               mCallingUid;
+};
+    
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_IPC_THREAD_STATE_H
diff --git a/include/utils/IPermissionController.h b/include/utils/IPermissionController.h
new file mode 100644
index 0000000..cb1dd34
--- /dev/null
+++ b/include/utils/IPermissionController.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_IPERMISSION_CONTROLLER_H
+#define ANDROID_IPERMISSION_CONTROLLER_H
+
+#include <utils/IInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IPermissionController : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(PermissionController);
+
+    virtual bool                checkPermission(const String16& permission,
+                                                int32_t pid, int32_t uid) = 0;
+    
+    enum {
+        CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION
+    };
+};
+
+// ----------------------------------------------------------------------
+
+class BnPermissionController : public BnInterface<IPermissionController>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IPERMISSION_CONTROLLER_H
+
diff --git a/include/utils/IServiceManager.h b/include/utils/IServiceManager.h
new file mode 100644
index 0000000..e3d99fe
--- /dev/null
+++ b/include/utils/IServiceManager.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_ISERVICE_MANAGER_H
+#define ANDROID_ISERVICE_MANAGER_H
+
+#include <utils/IInterface.h>
+#include <utils/IPermissionController.h>
+#include <utils/Vector.h>
+#include <utils/String16.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IServiceManager : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(ServiceManager);
+
+    /**
+     * Retrieve an existing service, blocking for a few seconds
+     * if it doesn't yet exist.
+     */
+    virtual sp<IBinder>         getService( const String16& name) const = 0;
+
+    /**
+     * Retrieve an existing service, non-blocking.
+     */
+    virtual sp<IBinder>         checkService( const String16& name) const = 0;
+
+    /**
+     * Register a service.
+     */
+    virtual status_t            addService( const String16& name,
+                                            const sp<IBinder>& service) = 0;
+
+    /**
+     * Return list of all existing services.
+     */
+    virtual Vector<String16>    listServices() = 0;
+
+    enum {
+        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+        CHECK_SERVICE_TRANSACTION,
+        ADD_SERVICE_TRANSACTION,
+        LIST_SERVICES_TRANSACTION,
+    };
+};
+
+sp<IServiceManager> defaultServiceManager();
+
+template<typename INTERFACE>
+status_t getService(const String16& name, sp<INTERFACE>* outService)
+{
+    const sp<IServiceManager> sm = defaultServiceManager();
+    if (sm != NULL) {
+        *outService = interface_cast<INTERFACE>(sm->getService(name));
+        if ((*outService) != NULL) return NO_ERROR;
+    }
+    return NAME_NOT_FOUND;
+}
+
+bool checkCallingPermission(const String16& permission);
+bool checkCallingPermission(const String16& permission,
+                            int32_t* outPid, int32_t* outUid);
+
+// ----------------------------------------------------------------------
+
+class BnServiceManager : public BnInterface<IServiceManager>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_ISERVICE_MANAGER_H
+
diff --git a/include/utils/KeyedVector.h b/include/utils/KeyedVector.h
new file mode 100644
index 0000000..f4513ee
--- /dev/null
+++ b/include/utils/KeyedVector.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_KEYED_VECTOR_H
+#define ANDROID_KEYED_VECTOR_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/SortedVector.h>
+#include <utils/TypeHelpers.h>
+#include <utils/Errors.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+template <typename KEY, typename VALUE>
+class KeyedVector
+{
+public:
+    typedef KEY    key_type;
+    typedef VALUE  value_type;
+
+    inline                  KeyedVector();
+
+    /*
+     * empty the vector
+     */
+
+    inline  void            clear()                     { mVector.clear(); }
+
+    /*! 
+     * vector stats
+     */
+
+    //! returns number of items in the vector
+    inline  size_t          size() const                { return mVector.size(); }
+    //! returns wether or not the vector is empty
+    inline  bool            isEmpty() const             { return mVector.isEmpty(); }
+    //! returns how many items can be stored without reallocating the backing store
+    inline  size_t          capacity() const            { return mVector.capacity(); }
+    //! setst the capacity. capacity can never be reduced less than size()
+    inline ssize_t          setCapacity(size_t size)    { return mVector.setCapacity(size); }
+    
+    /*! 
+     * accessors
+     */
+            const VALUE&    valueFor(const KEY& key) const;
+            const VALUE&    valueAt(size_t index) const;
+            const KEY&      keyAt(size_t index) const;
+            ssize_t         indexOfKey(const KEY& key) const;
+
+    /*!
+     * modifing the array
+     */
+
+            VALUE&          editValueFor(const KEY& key);
+            VALUE&          editValueAt(size_t index);
+
+            /*! 
+             * add/insert/replace items
+             */
+             
+            ssize_t         add(const KEY& key, const VALUE& item);
+            ssize_t         replaceValueFor(const KEY& key, const VALUE& item);
+            ssize_t         replaceValueAt(size_t index, const VALUE& item);
+
+    /*!
+     * remove items
+     */
+
+            ssize_t         removeItem(const KEY& key);
+            ssize_t         removeItemsAt(size_t index, size_t count = 1);
+            
+private:
+            SortedVector< key_value_pair_t<KEY, VALUE> >    mVector;
+};
+
+// ---------------------------------------------------------------------------
+
+/**
+ * Variation of KeyedVector that holds a default value to return when
+ * valueFor() is called with a key that doesn't exist.
+ */
+template <typename KEY, typename VALUE>
+class DefaultKeyedVector : public KeyedVector<KEY, VALUE>
+{
+public:
+    inline                  DefaultKeyedVector(const VALUE& defValue = VALUE());
+            const VALUE&    valueFor(const KEY& key) const;
+
+private:
+            VALUE                                           mDefault;
+};
+
+// ---------------------------------------------------------------------------
+
+template<typename KEY, typename VALUE> inline
+KeyedVector<KEY,VALUE>::KeyedVector()
+{
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const {
+    return mVector.indexOf( key_value_pair_t<KEY,VALUE>(key) );
+}
+
+template<typename KEY, typename VALUE> inline
+const VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
+    ssize_t i = indexOfKey(key);
+    assert(i>=0);
+    return mVector.itemAt(i).value;
+}
+
+template<typename KEY, typename VALUE> inline
+const VALUE& KeyedVector<KEY,VALUE>::valueAt(size_t index) const {
+    return mVector.itemAt(index).value;
+}
+
+template<typename KEY, typename VALUE> inline
+const KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const {
+    return mVector.itemAt(index).key;
+}
+
+template<typename KEY, typename VALUE> inline
+VALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) {
+    ssize_t i = indexOfKey(key);
+    assert(i>=0);
+    return mVector.editItemAt(i).value;
+}
+
+template<typename KEY, typename VALUE> inline
+VALUE& KeyedVector<KEY,VALUE>::editValueAt(size_t index) {
+    return mVector.editItemAt(index).value;
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::add(const KEY& key, const VALUE& value) {
+    return mVector.add( key_value_pair_t<KEY,VALUE>(key, value) );
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::replaceValueFor(const KEY& key, const VALUE& value) {
+    key_value_pair_t<KEY,VALUE> pair(key, value);
+    mVector.remove(pair);
+    return mVector.add(pair);
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) {
+    if (index<size()) {
+        mVector.editValueAt(index).value = item;
+        return index;
+    }
+    return BAD_INDEX;
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::removeItem(const KEY& key) {
+    return mVector.remove(key_value_pair_t<KEY,VALUE>(key));
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY, VALUE>::removeItemsAt(size_t index, size_t count) {
+    return mVector.removeItemsAt(index, count);
+}
+
+// ---------------------------------------------------------------------------
+
+template<typename KEY, typename VALUE> inline
+DefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue)
+    : mDefault(defValue)
+{
+}
+
+template<typename KEY, typename VALUE> inline
+const VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
+    ssize_t i = indexOfKey(key);
+    return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault;
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_KEYED_VECTOR_H
diff --git a/include/utils/List.h b/include/utils/List.h
new file mode 100644
index 0000000..1a6be9a
--- /dev/null
+++ b/include/utils/List.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Templated list class.  Normally we'd use STL, but we don't have that.
+// This class mimics STL's interfaces.
+//
+// Objects are copied into the list with the '=' operator or with copy-
+// construction, so if the compiler's auto-generated versions won't work for
+// you, define your own.
+//
+// The only class you want to use from here is "List".  Do not use classes
+// starting with "_" directly.
+//
+#ifndef _LIBS_UTILS_LIST_H
+#define _LIBS_UTILS_LIST_H
+
+namespace android {
+
+/*
+ * One element in the list.
+ */
+template<class T> class _ListNode {
+public:
+    typedef _ListNode<T> _Node;
+
+    _ListNode(const T& val) : mVal(val) {}
+    ~_ListNode(void) {}
+
+    T& getRef(void) { return mVal; }
+    void setVal(const T& val) { mVal = val; }
+
+    _Node* getPrev(void) const { return mpPrev; }
+    void setPrev(_Node* ptr) { mpPrev = ptr; }
+    _Node* getNext(void) const { return mpNext; }
+    void setNext(_Node* ptr) { mpNext = ptr; }
+
+private:
+    T           mVal;
+    _Node*      mpPrev;
+    _Node*      mpNext;
+};
+
+/*
+ * Iterator for walking through the list.
+ */
+template<class T, class Tref> class _ListIterator {
+public:
+    typedef _ListIterator<T,Tref> _Iter;
+    typedef _ListNode<T> _Node;
+
+    _ListIterator(void) {}
+    _ListIterator(_Node* ptr) : mpNode(ptr) {}
+    ~_ListIterator(void) {}
+
+    /*
+     * Dereference operator.  Used to get at the juicy insides.
+     */
+    Tref operator*() const { return mpNode->getRef(); }
+
+    /*
+     * Iterator comparison.
+     */
+    bool operator==(const _Iter& right) const { return mpNode == right.mpNode; }
+    bool operator!=(const _Iter& right) const { return mpNode != right.mpNode; }
+
+    /*
+     * Incr/decr, used to move through the list.
+     */
+    _Iter& operator++(void) {        // pre-increment
+        mpNode = mpNode->getNext();
+        return *this;
+    }
+    _Iter operator++(int) {          // post-increment
+        _Iter tmp = *this;
+        ++*this;
+        return tmp;
+    }
+    _Iter& operator--(void) {        // pre-increment
+        mpNode = mpNode->getPrev();
+        return *this;
+    }
+    _Iter operator--(int) {          // post-increment
+        _Iter tmp = *this;
+        --*this;
+        return tmp;
+    }
+
+    _Node* getNode(void) const { return mpNode; }
+
+private:
+    _Node*      mpNode;
+};
+
+
+/*
+ * Doubly-linked list.  Instantiate with "List<MyClass> myList".
+ *
+ * Objects added to the list are copied using the assignment operator,
+ * so this must be defined.
+ */
+template<class T> class List {
+public:
+    typedef _ListNode<T> _Node;
+
+    List(void) {
+        prep();
+    }
+    List(const List<T>& src) {      // copy-constructor
+        prep();
+        insert(begin(), src.begin(), src.end());
+    }
+    virtual ~List(void) {
+        clear();
+        delete[] (unsigned char*) mpMiddle;
+    }
+
+    typedef _ListIterator<T,T&> iterator;
+    typedef _ListIterator<T, const T&> const_iterator;
+
+    List<T>& operator=(const List<T>& right);
+
+    /* returns true if the list is empty */
+    bool empty(void) const { return mpMiddle->getNext() == mpMiddle; }
+
+    /* return #of elements in list */
+    unsigned int size(void) const {
+        return distance(begin(), end());
+    }
+
+    /*
+     * Return the first element or one past the last element.  The
+     * _ListNode* we're returning is converted to an "iterator" by a
+     * constructor in _ListIterator.
+     */
+    iterator begin()                { return mpMiddle->getNext(); }
+    const_iterator begin() const    { return mpMiddle->getNext(); }
+    iterator end()                  { return mpMiddle; }
+    const_iterator end() const      { return mpMiddle; }
+
+    /* add the object to the head or tail of the list */
+    void push_front(const T& val) { insert(begin(), val); }
+    void push_back(const T& val) { insert(end(), val); }
+
+    /* insert before the current node; returns iterator at new node */
+    iterator insert(iterator posn, const T& val) {
+        _Node* newNode = new _Node(val);        // alloc & copy-construct
+        newNode->setNext(posn.getNode());
+        newNode->setPrev(posn.getNode()->getPrev());
+        posn.getNode()->getPrev()->setNext(newNode);
+        posn.getNode()->setPrev(newNode);
+        return newNode;
+    }
+
+    /* insert a range of elements before the current node */
+    void insert(iterator posn, const_iterator first, const_iterator last) {
+        for ( ; first != last; ++first)
+            insert(posn, *first);
+    }
+
+    /* remove one entry; returns iterator at next node */
+    iterator erase(iterator posn) {
+        _Node* pNext = posn.getNode()->getNext();
+        _Node* pPrev = posn.getNode()->getPrev();
+        pPrev->setNext(pNext);
+        pNext->setPrev(pPrev);
+        delete posn.getNode();
+        return pNext;
+    }
+
+    /* remove a range of elements */
+    iterator erase(iterator first, iterator last) {
+        while (first != last)
+            erase(first++);     // don't erase than incr later!
+        return last;
+    }
+
+    /* remove all contents of the list */
+    void clear(void) {
+        _Node* pCurrent = mpMiddle->getNext();
+        _Node* pNext;
+
+        while (pCurrent != mpMiddle) {
+            pNext = pCurrent->getNext();
+            delete pCurrent;
+            pCurrent = pNext;
+        }
+        mpMiddle->setPrev(mpMiddle);
+        mpMiddle->setNext(mpMiddle);
+    }
+
+    /*
+     * Measure the distance between two iterators.  On exist, "first"
+     * will be equal to "last".  The iterators must refer to the same
+     * list.
+     *
+     * (This is actually a generic iterator function.  It should be part
+     * of some other class, possibly an iterator base class.  It needs to
+     * know the difference between a list, which has to march through,
+     * and a vector, which can just do pointer math.)
+     */
+    unsigned int distance(iterator first, iterator last) {
+        unsigned int count = 0;
+        while (first != last) {
+            ++first;
+            ++count;
+        }
+        return count;
+    }
+    unsigned int distance(const_iterator first, const_iterator last) const {
+        unsigned int count = 0;
+        while (first != last) {
+            ++first;
+            ++count;
+        }
+        return count;
+    }
+
+private:
+    /*
+     * I want a _ListNode but don't need it to hold valid data.  More
+     * to the point, I don't want T's constructor to fire, since it
+     * might have side-effects or require arguments.  So, we do this
+     * slightly uncouth storage alloc.
+     */
+    void prep(void) {
+        mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];
+        mpMiddle->setPrev(mpMiddle);
+        mpMiddle->setNext(mpMiddle);
+    }
+
+    /*
+     * This node plays the role of "pointer to head" and "pointer to tail".
+     * It sits in the middle of a circular list of nodes.  The iterator
+     * runs around the circle until it encounters this one.
+     */
+    _Node*      mpMiddle;
+};
+
+/*
+ * Assignment operator.
+ *
+ * The simplest way to do this would be to clear out the target list and
+ * fill it with the source.  However, we can speed things along by
+ * re-using existing elements.
+ */
+template<class T>
+List<T>& List<T>::operator=(const List<T>& right)
+{
+    if (this == &right)
+        return *this;       // self-assignment
+    iterator firstDst = begin();
+    iterator lastDst = end();
+    const_iterator firstSrc = right.begin();
+    const_iterator lastSrc = right.end();
+    while (firstSrc != lastSrc && firstDst != lastDst)
+        *firstDst++ = *firstSrc++;
+    if (firstSrc == lastSrc)        // ran out of elements in source?
+        erase(firstDst, lastDst);   // yes, erase any extras
+    else
+        insert(lastDst, firstSrc, lastSrc);     // copy remaining over
+    return *this;
+}
+
+}; // namespace android
+
+#endif // _LIBS_UTILS_LIST_H
diff --git a/include/utils/Log.h b/include/utils/Log.h
new file mode 100644
index 0000000..3c6cc8b
--- /dev/null
+++ b/include/utils/Log.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// C/C++ logging functions.  See the logging documentation for API details.
+//
+// We'd like these to be available from C code (in case we import some from
+// somewhere), so this has a C interface.
+//
+// The output will be correct when the log file is shared between multiple
+// threads and/or multiple processes so long as the operating system
+// supports O_APPEND.  These calls have mutex-protected data structures
+// and so are NOT reentrant.  Do not use LOG in a signal handler.
+//
+#ifndef _LIBS_UTILS_LOG_H
+#define _LIBS_UTILS_LOG_H
+
+#include <cutils/log.h>
+
+#endif // _LIBS_UTILS_LOG_H
diff --git a/include/utils/LogSocket.h b/include/utils/LogSocket.h
new file mode 100644
index 0000000..01fbfb5
--- /dev/null
+++ b/include/utils/LogSocket.h
@@ -0,0 +1,20 @@
+/* utils/LogSocket.h
+** 
+** Copyright 2008, The Android Open Source Project
+**
+** This file is dual licensed.  It may be redistributed and/or modified
+** under the terms of the Apache 2.0 License OR version 2 of the GNU
+** General Public License.
+*/
+
+#ifndef _UTILS_LOGSOCKET_H
+#define _UTILS_LOGSOCKET_H
+
+#define SOCKET_CLOSE_LOCAL 0
+
+void add_send_stats(int fd, int send);
+void add_recv_stats(int fd, int recv);
+void log_socket_close(int fd, short reason);
+void log_socket_connect(int fd, unsigned int ip, unsigned short port);
+
+#endif /* _UTILS_LOGSOCKET_H */
diff --git a/include/utils/MemoryBase.h b/include/utils/MemoryBase.h
new file mode 100644
index 0000000..eb5a9d2
--- /dev/null
+++ b/include/utils/MemoryBase.h
@@ -0,0 +1,51 @@
+/*
+ * 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_MEMORY_BASE_H
+#define ANDROID_MEMORY_BASE_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <utils/IMemory.h>
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MemoryBase : public BnMemory 
+{
+public:
+    MemoryBase(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);
+    virtual ~MemoryBase();
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+
+protected:
+    size_t getSize() const { return mSize; }
+    ssize_t getOffset() const { return mOffset; }
+    const sp<IMemoryHeap>& getHeap() const { return mHeap; }
+
+private:
+    size_t          mSize;
+    ssize_t         mOffset;
+    sp<IMemoryHeap> mHeap;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_BASE_H
diff --git a/include/utils/MemoryDealer.h b/include/utils/MemoryDealer.h
new file mode 100644
index 0000000..454b627
--- /dev/null
+++ b/include/utils/MemoryDealer.h
@@ -0,0 +1,238 @@
+/*
+ * 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_MEMORY_DEALER_H
+#define ANDROID_MEMORY_DEALER_H
+
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/IMemory.h>
+#include <utils/threads.h>
+#include <utils/MemoryHeapBase.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+class String8;
+
+/*
+ * interface for implementing a "heap". A heap basically provides
+ * the IMemoryHeap interface for cross-process sharing and the
+ * ability to map/unmap pages within the heap.
+ */
+class HeapInterface : public virtual BnMemoryHeap
+{
+public:
+    // all values must be page-aligned
+    virtual sp<IMemory> mapMemory(size_t offset, size_t size) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+/*
+ * interface for implementing an allocator. An allocator provides
+ * methods for allocating and freeing memory blocks and dumping
+ * its state.
+ */
+class AllocatorInterface : public RefBase
+{
+public:
+    enum {
+        PAGE_ALIGNED = 0x00000001
+    };
+
+    virtual size_t      allocate(size_t size, uint32_t flags = 0) = 0;
+    virtual status_t    deallocate(size_t offset) = 0;
+    virtual size_t      size() const = 0;
+    virtual void        dump(const char* what, uint32_t flags = 0) const = 0;
+    virtual void        dump(String8& res,
+            const char* what, uint32_t flags = 0) const = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+/*
+ * concrete implementation of HeapInterface on top of mmap() 
+ */
+class SharedHeap : public HeapInterface, public MemoryHeapBase
+{
+public:
+                        SharedHeap(size_t size, uint32_t flags = 0, char const * name = NULL);
+    virtual             ~SharedHeap();
+    virtual sp<IMemory> mapMemory(size_t offset, size_t size);
+};
+
+// ----------------------------------------------------------------------------
+
+/*
+ * A simple templatized doubly linked-list implementation
+ */
+
+template <typename NODE>
+class LinkedList
+{
+    NODE*  mFirst;
+    NODE*  mLast;
+
+public:
+                LinkedList() : mFirst(0), mLast(0) { }
+    bool        isEmpty() const { return mFirst == 0; }
+    NODE const* head() const { return mFirst; }
+    NODE*       head() { return mFirst; }
+    NODE const* tail() const { return mLast; }
+    NODE*       tail() { return mLast; }
+
+    void insertAfter(NODE* node, NODE* newNode) {
+        newNode->prev = node;
+        newNode->next = node->next;
+        if (node->next == 0) mLast = newNode;
+        else                 node->next->prev = newNode;
+        node->next = newNode;
+    }
+
+    void insertBefore(NODE* node, NODE* newNode) {
+         newNode->prev = node->prev;
+         newNode->next = node;
+         if (node->prev == 0)   mFirst = newNode;
+         else                   node->prev->next = newNode;
+         node->prev = newNode;
+    }
+
+    void insertHead(NODE* newNode) {
+        if (mFirst == 0) {
+            mFirst = mLast = newNode;
+            newNode->prev = newNode->next = 0;
+        } else {
+            insertBefore(mFirst, newNode);
+        }
+    }
+    
+    void insertTail(NODE* newNode) {
+        if (mLast == 0) insertBeginning(newNode);
+        else            insertAfter(mLast, newNode);
+    }
+
+    NODE* remove(NODE* node) {
+        if (node->prev == 0)    mFirst = node->next;
+        else                    node->prev->next = node->next;
+        if (node->next == 0)    mLast = node->prev;
+        else                    node->next->prev = node->prev;
+        return node;
+    }
+};
+
+
+/*
+ * concrete implementation of AllocatorInterface using a simple
+ * best-fit allocation scheme
+ */
+class SimpleBestFitAllocator : public AllocatorInterface
+{
+public:
+
+                        SimpleBestFitAllocator(size_t size);
+    virtual             ~SimpleBestFitAllocator();
+
+    virtual size_t      allocate(size_t size, uint32_t flags = 0);
+    virtual status_t    deallocate(size_t offset);
+    virtual size_t      size() const;
+    virtual void        dump(const char* what, uint32_t flags = 0) const;
+    virtual void        dump(String8& res,
+            const char* what, uint32_t flags = 0) const;
+
+private:
+
+    struct chunk_t {
+        chunk_t(size_t start, size_t size) 
+            : start(start), size(size), free(1), prev(0), next(0) {
+        }
+        size_t              start;
+        size_t              size : 28;
+        int                 free : 4;
+        mutable chunk_t*    prev;
+        mutable chunk_t*    next;
+    };
+
+    ssize_t  alloc(size_t size, uint32_t flags);
+    chunk_t* dealloc(size_t start);
+    void     dump_l(const char* what, uint32_t flags = 0) const;
+    void     dump_l(String8& res, const char* what, uint32_t flags = 0) const;
+
+    static const int    kMemoryAlign;
+    mutable Mutex       mLock;
+    LinkedList<chunk_t> mList;
+    size_t              mHeapSize;
+};
+
+// ----------------------------------------------------------------------------
+
+class MemoryDealer : public RefBase
+{
+public:
+
+    enum {
+        READ_ONLY = MemoryHeapBase::READ_ONLY,
+        PAGE_ALIGNED = AllocatorInterface::PAGE_ALIGNED
+    };
+
+    // creates a memory dealer with the SharedHeap and SimpleBestFitAllocator
+    MemoryDealer(size_t size, uint32_t flags = 0, const char* name = 0);
+
+    // provide a custom heap but use the SimpleBestFitAllocator
+    MemoryDealer(const sp<HeapInterface>& heap);
+
+    // provide both custom heap and allocotar
+    MemoryDealer(
+            const sp<HeapInterface>& heap,
+            const sp<AllocatorInterface>& allocator);
+
+    virtual ~MemoryDealer();
+
+    virtual sp<IMemory> allocate(size_t size, uint32_t flags = 0);
+    virtual void        deallocate(size_t offset);
+    virtual void        dump(const char* what, uint32_t flags = 0) const;
+
+
+    sp<IMemoryHeap> getMemoryHeap() const { return heap(); }
+    sp<AllocatorInterface> getAllocator() const { return allocator(); }
+
+private:    
+    const sp<HeapInterface>&        heap() const;
+    const sp<AllocatorInterface>&   allocator() const;
+
+    class Allocation : public BnMemory {
+    public:
+        Allocation(const sp<MemoryDealer>& dealer,
+                ssize_t offset, size_t size, const sp<IMemory>& memory);
+        virtual ~Allocation();
+        virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+    private:
+        sp<MemoryDealer>        mDealer;
+        ssize_t                 mOffset;
+        size_t                  mSize;
+        sp<IMemory>             mMemory;
+    };
+
+    sp<HeapInterface>           mHeap;
+    sp<AllocatorInterface>      mAllocator;
+};
+
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_DEALER_H
diff --git a/include/utils/MemoryHeapBase.h b/include/utils/MemoryHeapBase.h
new file mode 100644
index 0000000..ff89738
--- /dev/null
+++ b/include/utils/MemoryHeapBase.h
@@ -0,0 +1,95 @@
+/*
+ * 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_MEMORY_HEAP_BASE_H
+#define ANDROID_MEMORY_HEAP_BASE_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <utils/IMemory.h>
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MemoryHeapBase : public virtual BnMemoryHeap 
+{
+public:
+    enum {
+        READ_ONLY = IMemoryHeap::READ_ONLY,
+        MAP_ONCE = IMemoryHeap::MAP_ONCE
+    };
+
+    /* 
+     * maps the memory referenced by fd. but DOESN'T take ownership
+     * of the filedescriptor (it makes a copy with dup()
+     */
+    MemoryHeapBase(int fd, size_t size, uint32_t flags = 0);
+    
+    /*
+     * maps memory from the given device
+     */
+    MemoryHeapBase(const char* device, size_t size = 0, uint32_t flags = 0);
+
+    /*
+     * maps memory from ashmem, with the given name for debugging
+     */
+    MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = NULL);
+
+    virtual ~MemoryHeapBase();
+
+    /* implement IMemoryHeap interface */
+    virtual int         getHeapID() const;
+    virtual void*       getBase() const;
+    virtual size_t      getSize() const;
+    virtual uint32_t    getFlags() const;
+
+    const char*         getDevice() const;
+    
+    /* this closes this heap -- use carefully */
+    void dispose();
+
+    /* this is only needed as a workaround, use only if you know
+     * what you are doing */
+    status_t setDevice(const char* device) {
+        if (mDevice == 0)
+            mDevice = device;
+        return mDevice ? NO_ERROR : ALREADY_EXISTS;
+    }
+    
+protected:
+            MemoryHeapBase();
+    // init() takes ownership of fd
+    status_t init(int fd, void *base, int size,
+            int flags = 0, const char* device = NULL);    
+
+private:
+    status_t mapfd(int fd, size_t size);
+
+    int         mFD;
+    size_t      mSize;
+    void*       mBase;
+    uint32_t    mFlags;
+    const char* mDevice;
+    bool        mNeedUnmap;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_HEAP_BASE_H
diff --git a/include/utils/MemoryHeapPmem.h b/include/utils/MemoryHeapPmem.h
new file mode 100644
index 0000000..b694b20
--- /dev/null
+++ b/include/utils/MemoryHeapPmem.h
@@ -0,0 +1,65 @@
+/*
+ * 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_MEMORY_HEAP_PMEM_H
+#define ANDROID_MEMORY_HEAP_PMEM_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryHeapBase.h>
+#include <utils/IMemory.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class MemoryHeapBase;
+
+// ---------------------------------------------------------------------------
+
+class SubRegionMemory;
+
+class MemoryHeapPmem : public HeapInterface, public MemoryHeapBase
+{
+public:
+    MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
+                uint32_t flags = IMemoryHeap::MAP_ONCE);
+    ~MemoryHeapPmem();
+
+    /* HeapInterface additions */
+    virtual sp<IMemory> mapMemory(size_t offset, size_t size);
+
+    /* make the whole heap visible (you know who you are) */
+    virtual status_t slap();
+    
+    /* hide (revoke) the whole heap (the client will see the garbage page) */
+    virtual status_t unslap();
+    
+    /* revoke all allocations made by this heap */
+    virtual void revoke();
+    
+private:
+    sp<MemoryHeapBase>              mParentHeap;
+    mutable Mutex                   mLock;
+    Vector< wp<SubRegionMemory> >   mAllocations;
+};
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_HEAP_PMEM_H
diff --git a/include/utils/Parcel.h b/include/utils/Parcel.h
new file mode 100644
index 0000000..7c451ab
--- /dev/null
+++ b/include/utils/Parcel.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_PARCEL_H
+#define ANDROID_PARCEL_H
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class IBinder;
+class ProcessState;
+class String8;
+class TextOutput;
+
+struct flat_binder_object;  // defined in support_p/binder_module.h
+
+class Parcel
+{
+public:
+                        Parcel();
+                        ~Parcel();
+    
+    const uint8_t*      data() const;
+    size_t              dataSize() const;
+    size_t              dataAvail() const;
+    size_t              dataPosition() const;
+    size_t              dataCapacity() const;
+    
+    status_t            setDataSize(size_t size);
+    void                setDataPosition(size_t pos) const;
+    status_t            setDataCapacity(size_t size);
+    
+    status_t            setData(const uint8_t* buffer, size_t len);
+
+    status_t            appendFrom(Parcel *parcel, size_t start, size_t len);
+
+    bool                hasFileDescriptors() const;
+
+    status_t            writeInterfaceToken(const String16& interface);
+    bool                enforceInterface(const String16& interface) const;
+            
+    void                freeData();
+
+    const size_t*       objects() const;
+    size_t              objectsCount() const;
+    
+    status_t            errorCheck() const;
+    void                setError(status_t err);
+    
+    status_t            write(const void* data, size_t len);
+    void*               writeInplace(size_t len);
+    status_t            writeUnpadded(const void* data, size_t len);
+    status_t            writeInt32(int32_t val);
+    status_t            writeInt64(int64_t val);
+    status_t            writeFloat(float val);
+    status_t            writeDouble(double val);
+    status_t            writeCString(const char* str);
+    status_t            writeString8(const String8& str);
+    status_t            writeString16(const String16& str);
+    status_t            writeString16(const char16_t* str, size_t len);
+    status_t            writeStrongBinder(const sp<IBinder>& val);
+    status_t            writeWeakBinder(const wp<IBinder>& val);
+    
+    // Place a file descriptor into the parcel.  The given fd must remain
+    // valid for the lifetime of the parcel.
+    status_t            writeFileDescriptor(int fd);
+    
+    // Place a file descriptor into the parcel.  A dup of the fd is made, which
+    // will be closed once the parcel is destroyed.
+    status_t            writeDupFileDescriptor(int fd);
+    
+    status_t            writeObject(const flat_binder_object& val, bool nullMetaData);
+
+    void                remove(size_t start, size_t amt);
+    
+    status_t            read(void* outData, size_t len) const;
+    const void*         readInplace(size_t len) const;
+    int32_t             readInt32() const;
+    status_t            readInt32(int32_t *pArg) const;
+    int64_t             readInt64() const;
+    status_t            readInt64(int64_t *pArg) const;
+    float               readFloat() const;
+    status_t            readFloat(float *pArg) const;
+    double              readDouble() const;
+    status_t            readDouble(double *pArg) const;
+
+    const char*         readCString() const;
+    String8             readString8() const;
+    String16            readString16() const;
+    const char16_t*     readString16Inplace(size_t* outLen) const;
+    sp<IBinder>         readStrongBinder() const;
+    wp<IBinder>         readWeakBinder() const;
+    
+    // Retrieve a file descriptor from the parcel.  This returns the raw fd
+    // in the parcel, which you do not own -- use dup() to get your own copy.
+    int                 readFileDescriptor() const;
+    
+    const flat_binder_object* readObject(bool nullMetaData) const;
+
+    // Explicitly close all file descriptors in the parcel.
+    void                closeFileDescriptors();
+    
+    typedef void        (*release_func)(Parcel* parcel,
+                                        const uint8_t* data, size_t dataSize,
+                                        const size_t* objects, size_t objectsSize,
+                                        void* cookie);
+                        
+    const uint8_t*      ipcData() const;
+    size_t              ipcDataSize() const;
+    const size_t*       ipcObjects() const;
+    size_t              ipcObjectsCount() const;
+    void                ipcSetDataReference(const uint8_t* data, size_t dataSize,
+                                            const size_t* objects, size_t objectsCount,
+                                            release_func relFunc, void* relCookie);
+    
+    void                print(TextOutput& to, uint32_t flags = 0) const;
+    
+private:
+                        Parcel(const Parcel& o);
+    Parcel&             operator=(const Parcel& o);
+    
+    status_t            finishWrite(size_t len);
+    void                releaseObjects();
+    void                acquireObjects();
+    status_t            growData(size_t len);
+    status_t            restartWrite(size_t desired);
+    status_t            continueWrite(size_t desired);
+    void                freeDataNoInit();
+    void                initState();
+    void                scanForFds() const;
+                        
+    status_t            mError;
+    uint8_t*            mData;
+    size_t              mDataSize;
+    size_t              mDataCapacity;
+    mutable size_t      mDataPos;
+    size_t*             mObjects;
+    size_t              mObjectsSize;
+    size_t              mObjectsCapacity;
+    mutable size_t      mNextObjectHint;
+
+    mutable bool        mFdsKnown;
+    mutable bool        mHasFds;
+    
+    release_func        mOwner;
+    void*               mOwnerCookie;
+};
+
+// ---------------------------------------------------------------------------
+
+inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)
+{
+    parcel.print(to);
+    return to;
+}
+
+// ---------------------------------------------------------------------------
+
+// Generic acquire and release of objects.
+void acquire_object(const sp<ProcessState>& proc,
+                    const flat_binder_object& obj, const void* who);
+void release_object(const sp<ProcessState>& proc,
+                    const flat_binder_object& obj, const void* who);
+
+void flatten_binder(const sp<ProcessState>& proc,
+                    const sp<IBinder>& binder, flat_binder_object* out);
+void flatten_binder(const sp<ProcessState>& proc,
+                    const wp<IBinder>& binder, flat_binder_object* out);
+status_t unflatten_binder(const sp<ProcessState>& proc,
+                          const flat_binder_object& flat, sp<IBinder>* out);
+status_t unflatten_binder(const sp<ProcessState>& proc,
+                          const flat_binder_object& flat, wp<IBinder>* out);
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_PARCEL_H
diff --git a/include/utils/Pipe.h b/include/utils/Pipe.h
new file mode 100644
index 0000000..6404168
--- /dev/null
+++ b/include/utils/Pipe.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// FIFO I/O.
+//
+#ifndef _LIBS_UTILS_PIPE_H
+#define _LIBS_UTILS_PIPE_H
+
+#ifdef HAVE_ANDROID_OS
+#error DO NOT USE THIS FILE IN THE DEVICE BUILD
+#endif
+
+namespace android {
+
+/*
+ * Simple anonymous unidirectional pipe.
+ *
+ * The primary goal is to create an implementation with minimal overhead
+ * under Linux.  Making Windows, Mac OS X, and Linux all work the same way
+ * is a secondary goal.  Part of this goal is to have something that can
+ * be fed to a select() call, so that the application can sleep in the
+ * kernel until something interesting happens.
+ */
+class Pipe {
+public:
+    Pipe(void);
+    virtual ~Pipe(void);
+
+    /* Create the pipe */
+    bool create(void);
+
+    /* Create a read-only pipe, using the supplied handle as read handle */
+    bool createReader(unsigned long handle);
+    /* Create a write-only pipe, using the supplied handle as write handle */
+    bool createWriter(unsigned long handle);
+
+    /* Is this object ready to go? */
+    bool isCreated(void);
+
+    /*
+     * Read "count" bytes from the pipe.  Returns the amount of data read,
+     * or 0 if no data available and we're non-blocking.
+     * Returns -1 on error.
+     */
+    int read(void* buf, int count);
+
+    /*
+     * Write "count" bytes into the pipe.  Returns number of bytes written,
+     * or 0 if there's no room for more data and we're non-blocking.
+     * Returns -1 on error.
+     */
+    int write(const void* buf, int count);
+
+    /* Returns "true" if data is available to read */
+    bool readReady(void);
+
+    /* Enable or disable non-blocking I/O for reads */
+    bool setReadNonBlocking(bool val);
+    /* Enable or disable non-blocking I/O for writes.  Only works on Linux. */
+    bool setWriteNonBlocking(bool val);
+
+    /*
+     * Get the handle.  Only useful in some platform-specific situations.
+     */
+    unsigned long getReadHandle(void);
+    unsigned long getWriteHandle(void);
+
+    /*
+     * Modify inheritance, i.e. whether or not a child process will get
+     * copies of the descriptors.  Systems with fork+exec allow us to close
+     * the descriptors before launching the child process, but Win32
+     * doesn't allow it.
+     */
+    bool disallowReadInherit(void);
+    bool disallowWriteInherit(void);
+
+    /*
+     * Close one side or the other.  Useful in the parent after launching
+     * a child process.
+     */
+    bool closeRead(void);
+    bool closeWrite(void);
+
+private:
+    bool    mReadNonBlocking;
+    bool    mWriteNonBlocking;
+
+    unsigned long mReadHandle;
+    unsigned long mWriteHandle;
+};
+
+}; // android
+
+#endif // _LIBS_UTILS_PIPE_H
diff --git a/include/utils/ProcessState.h b/include/utils/ProcessState.h
new file mode 100644
index 0000000..39584f4
--- /dev/null
+++ b/include/utils/ProcessState.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_PROCESS_STATE_H
+#define ANDROID_PROCESS_STATE_H
+
+#include <utils/IBinder.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+#include <utils/threads.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+// Global variables
+extern int                 mArgC;
+extern const char* const*  mArgV;
+extern int                 mArgLen;
+
+class IPCThreadState;
+
+class ProcessState : public virtual RefBase
+{
+public:
+    static  sp<ProcessState>    self();
+
+    static  void                setSingleProcess(bool singleProcess);
+
+            void                setContextObject(const sp<IBinder>& object);
+            sp<IBinder>         getContextObject(const sp<IBinder>& caller);
+        
+            void                setContextObject(const sp<IBinder>& object,
+                                                 const String16& name);
+            sp<IBinder>         getContextObject(const String16& name,
+                                                 const sp<IBinder>& caller);
+                                                 
+            bool                supportsProcesses() const;
+
+            void                startThreadPool();
+                        
+    typedef bool (*context_check_func)(const String16& name,
+                                       const sp<IBinder>& caller,
+                                       void* userData);
+        
+            bool                isContextManager(void) const;
+            bool                becomeContextManager(
+                                    context_check_func checkFunc,
+                                    void* userData);
+
+            sp<IBinder>         getStrongProxyForHandle(int32_t handle);
+            wp<IBinder>         getWeakProxyForHandle(int32_t handle);
+            void                expungeHandle(int32_t handle, IBinder* binder);
+
+            void                setArgs(int argc, const char* const argv[]);
+            int                 getArgC() const;
+            const char* const*  getArgV() const;
+
+            void                setArgV0(const char* txt);
+
+            void                spawnPooledThread(bool isMain);
+            
+private:
+    friend class IPCThreadState;
+    
+                                ProcessState();
+                                ~ProcessState();
+
+                                ProcessState(const ProcessState& o);
+            ProcessState&       operator=(const ProcessState& o);
+            
+            struct handle_entry {
+                IBinder* binder;
+                RefBase::weakref_type* refs;
+            };
+            
+            handle_entry*       lookupHandleLocked(int32_t handle);
+
+            int                 mDriverFD;
+            void*               mVMStart;
+            
+    mutable Mutex               mLock;  // protects everything below.
+            
+            Vector<handle_entry>mHandleToObject;
+
+            bool                mManagesContexts;
+            context_check_func  mBinderContextCheckFunc;
+            void*               mBinderContextUserData;
+            
+            KeyedVector<String16, sp<IBinder> >
+                                mContexts;
+
+
+            String8             mRootDir;
+            bool                mThreadPoolStarted;
+    volatile int32_t            mThreadPoolSeq;
+};
+    
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_PROCESS_STATE_H
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
new file mode 100644
index 0000000..e37b56f
--- /dev/null
+++ b/include/utils/RefBase.h
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_REF_BASE_H
+#define ANDROID_REF_BASE_H
+
+#include <utils/TextOutput.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+template<typename T> class wp;
+
+// ---------------------------------------------------------------------------
+
+#define COMPARE(_op_)                                           \
+inline bool operator _op_ (const sp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+inline bool operator _op_ (const wp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+inline bool operator _op_ (const T* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const sp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const wp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const U* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}
+
+// ---------------------------------------------------------------------------
+
+class RefBase
+{
+public:
+            void            incStrong(const void* id) const;
+            void            decStrong(const void* id) const;
+    
+            void            forceIncStrong(const void* id) const;
+
+            //! DEBUGGING ONLY: Get current strong ref count.
+            int32_t         getStrongCount() const;
+
+    class weakref_type
+    {
+    public:
+        RefBase*            refBase() const;
+        
+        void                incWeak(const void* id);
+        void                decWeak(const void* id);
+        
+        bool                attemptIncStrong(const void* id);
+        
+        //! This is only safe if you have set OBJECT_LIFETIME_FOREVER.
+        bool                attemptIncWeak(const void* id);
+
+        //! DEBUGGING ONLY: Get current weak ref count.
+        int32_t             getWeakCount() const;
+
+        //! DEBUGGING ONLY: Print references held on object.
+        void                printRefs() const;
+
+        //! DEBUGGING ONLY: Enable tracking for this object.
+        // enable -- enable/disable tracking
+        // retain -- when tracking is enable, if true, then we save a stack trace
+        //           for each reference and dereference; when retain == false, we
+        //           match up references and dereferences and keep only the 
+        //           outstanding ones.
+        
+        void                trackMe(bool enable, bool retain);
+    };
+    
+            weakref_type*   createWeak(const void* id) const;
+            
+            weakref_type*   getWeakRefs() const;
+
+            //! DEBUGGING ONLY: Print references held on object.
+    inline  void            printRefs() const { getWeakRefs()->printRefs(); }
+
+            //! DEBUGGING ONLY: Enable tracking of object.
+    inline  void            trackMe(bool enable, bool retain)
+    { 
+        getWeakRefs()->trackMe(enable, retain); 
+    }
+
+protected:
+                            RefBase();
+    virtual                 ~RefBase();
+    
+    //! Flags for extendObjectLifetime()
+    enum {
+        OBJECT_LIFETIME_WEAK    = 0x0001,
+        OBJECT_LIFETIME_FOREVER = 0x0003
+    };
+    
+            void            extendObjectLifetime(int32_t mode);
+            
+    //! Flags for onIncStrongAttempted()
+    enum {
+        FIRST_INC_STRONG = 0x0001
+    };
+    
+    virtual void            onFirstRef();
+    virtual void            onLastStrongRef(const void* id);
+    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
+    virtual void            onLastWeakRef(const void* id);
+
+private:
+    friend class weakref_type;
+    class weakref_impl;
+    
+                            RefBase(const RefBase& o);
+            RefBase&        operator=(const RefBase& o);
+            
+        weakref_impl* const mRefs;
+};
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class sp
+{
+public:
+    typedef typename RefBase::weakref_type weakref_type;
+    
+    inline sp() : m_ptr(0) { }
+
+    sp(T* other);
+    sp(const sp<T>& other);
+    template<typename U> sp(U* other);
+    template<typename U> sp(const sp<U>& other);
+
+    ~sp();
+    
+    // Assignment
+
+    sp& operator = (T* other);
+    sp& operator = (const sp<T>& other);
+    
+    template<typename U> sp& operator = (const sp<U>& other);
+    template<typename U> sp& operator = (U* other);
+    
+    //! Special optimization for use by ProcessState (and nobody else).
+    void force_set(T* other);
+    
+    // Reset
+    
+    void clear();
+    
+    // Accessors
+
+    inline  T&      operator* () const  { return *m_ptr; }
+    inline  T*      operator-> () const { return m_ptr;  }
+    inline  T*      get() const         { return m_ptr; }
+
+    // Operators
+        
+    COMPARE(==)
+    COMPARE(!=)
+    COMPARE(>)
+    COMPARE(<)
+    COMPARE(<=)
+    COMPARE(>=)
+
+private:    
+    template<typename Y> friend class sp;
+    template<typename Y> friend class wp;
+
+    // Optimization for wp::promote().
+    sp(T* p, weakref_type* refs);
+    
+    T*              m_ptr;
+};
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const sp<T>& val);
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class wp
+{
+public:
+    typedef typename RefBase::weakref_type weakref_type;
+    
+    inline wp() : m_ptr(0) { }
+
+    wp(T* other);
+    wp(const wp<T>& other);
+    wp(const sp<T>& other);
+    template<typename U> wp(U* other);
+    template<typename U> wp(const sp<U>& other);
+    template<typename U> wp(const wp<U>& other);
+
+    ~wp();
+    
+    // Assignment
+
+    wp& operator = (T* other);
+    wp& operator = (const wp<T>& other);
+    wp& operator = (const sp<T>& other);
+    
+    template<typename U> wp& operator = (U* other);
+    template<typename U> wp& operator = (const wp<U>& other);
+    template<typename U> wp& operator = (const sp<U>& other);
+    
+    void set_object_and_refs(T* other, weakref_type* refs);
+
+    // promotion to sp
+    
+    sp<T> promote() const;
+
+    // Reset
+    
+    void clear();
+
+    // Accessors
+    
+    inline  weakref_type* get_refs() const { return m_refs; }
+    
+    inline  T* unsafe_get() const { return m_ptr; }
+
+    // Operators
+        
+    COMPARE(==)
+    COMPARE(!=)
+    COMPARE(>)
+    COMPARE(<)
+    COMPARE(<=)
+    COMPARE(>=)
+
+private:
+    template<typename Y> friend class sp;
+    template<typename Y> friend class wp;
+
+    T*              m_ptr;
+    weakref_type*   m_refs;
+};
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const wp<T>& val);
+
+#undef COMPARE
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts below here.
+
+template<typename T>
+sp<T>::sp(T* other)
+    : m_ptr(other)
+{
+    if (other) other->incStrong(this);
+}
+
+template<typename T>
+sp<T>::sp(const sp<T>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) m_ptr->incStrong(this);
+}
+
+template<typename T> template<typename U>
+sp<T>::sp(U* other) : m_ptr(other)
+{
+    if (other) other->incStrong(this);
+}
+
+template<typename T> template<typename U>
+sp<T>::sp(const sp<U>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) m_ptr->incStrong(this);
+}
+
+template<typename T>
+sp<T>::~sp()
+{
+    if (m_ptr) m_ptr->decStrong(this);
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (const sp<T>& other) {
+    if (other.m_ptr) other.m_ptr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other.m_ptr;
+    return *this;
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (T* other)
+{
+    if (other) other->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (const sp<U>& other)
+{
+    if (other.m_ptr) other.m_ptr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other.m_ptr;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (U* other)
+{
+    if (other) other->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T>    
+void sp<T>::force_set(T* other)
+{
+    other->forceIncStrong(this);
+    m_ptr = other;
+}
+
+template<typename T>
+void sp<T>::clear()
+{
+    if (m_ptr) {
+        m_ptr->decStrong(this);
+        m_ptr = 0;
+    }
+}
+
+template<typename T>
+sp<T>::sp(T* p, weakref_type* refs)
+    : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
+{
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
+{
+    to << "sp<>(" << val.get() << ")";
+    return to;
+}
+
+// ---------------------------------------------------------------------------
+
+template<typename T>
+wp<T>::wp(T* other)
+    : m_ptr(other)
+{
+    if (other) m_refs = other->createWeak(this);
+}
+
+template<typename T>
+wp<T>::wp(const wp<T>& other)
+    : m_ptr(other.m_ptr), m_refs(other.m_refs)
+{
+    if (m_ptr) m_refs->incWeak(this);
+}
+
+template<typename T>
+wp<T>::wp(const sp<T>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) {
+        m_refs = m_ptr->createWeak(this);
+    }
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(U* other)
+    : m_ptr(other)
+{
+    if (other) m_refs = other->createWeak(this);
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(const wp<U>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) {
+        m_refs = other.m_refs;
+        m_refs->incWeak(this);
+    }
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(const sp<U>& other)
+    : m_ptr(other.m_ptr)
+{
+    if (m_ptr) {
+        m_refs = m_ptr->createWeak(this);
+    }
+}
+
+template<typename T>
+wp<T>::~wp()
+{
+    if (m_ptr) m_refs->decWeak(this);
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (T* other)
+{
+    weakref_type* newRefs =
+        other ? other->createWeak(this) : 0;
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (const wp<T>& other)
+{
+    if (other.m_ptr) other.m_refs->incWeak(this);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other.m_ptr;
+    m_refs = other.m_refs;
+    return *this;
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (const sp<T>& other)
+{
+    weakref_type* newRefs =
+        other != NULL ? other->createWeak(this) : 0;
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other.get();
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (U* other)
+{
+    weakref_type* newRefs =
+        other ? other->createWeak(this) : 0;
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other;
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (const wp<U>& other)
+{
+    if (other.m_ptr) other.m_refs->incWeak(this);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other.m_ptr;
+    m_refs = other.m_refs;
+    return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (const sp<U>& other)
+{
+    weakref_type* newRefs =
+        other != NULL ? other->createWeak(this) : 0;
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other.get();
+    m_refs = newRefs;
+    return *this;
+}
+
+template<typename T>
+void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
+{
+    if (other) refs->incWeak(this);
+    if (m_ptr) m_refs->decWeak(this);
+    m_ptr = other;
+    m_refs = refs;
+}
+
+template<typename T>
+sp<T> wp<T>::promote() const
+{
+    return sp<T>(m_ptr, m_refs);
+}
+
+template<typename T>
+void wp<T>::clear()
+{
+    if (m_ptr) {
+        m_refs->decWeak(this);
+        m_ptr = 0;
+    }
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
+{
+    to << "wp<>(" << val.unsafe_get() << ")";
+    return to;
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_REF_BASE_H
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
new file mode 100644
index 0000000..31b9aa8
--- /dev/null
+++ b/include/utils/ResourceTypes.h
@@ -0,0 +1,1685 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Definitions of resource data structures.
+//
+#ifndef _LIBS_UTILS_RESOURCE_TYPES_H
+#define _LIBS_UTILS_RESOURCE_TYPES_H
+
+#include <utils/Asset.h>
+#include <utils/ByteOrder.h>
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+#include <utils/threads.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace android {
+
+/** ********************************************************************
+ *  PNG Extensions
+ *
+ *  New private chunks that may be placed in PNG images.
+ *
+ *********************************************************************** */
+
+/**
+ * This chunk specifies how to split an image into segments for
+ * scaling.
+ *
+ * There are J horizontal and K vertical segments.  These segments divide
+ * the image into J*K regions as follows (where J=4 and K=3):
+ *
+ *      F0   S0    F1     S1
+ *   +-----+----+------+-------+
+ * S2|  0  |  1 |  2   |   3   |
+ *   +-----+----+------+-------+
+ *   |     |    |      |       |
+ *   |     |    |      |       |
+ * F2|  4  |  5 |  6   |   7   |
+ *   |     |    |      |       |
+ *   |     |    |      |       |
+ *   +-----+----+------+-------+
+ * S3|  8  |  9 |  10  |   11  |
+ *   +-----+----+------+-------+
+ *
+ * Each horizontal and vertical segment is considered to by either
+ * stretchable (marked by the Sx labels) or fixed (marked by the Fy
+ * labels), in the horizontal or vertical axis, respectively. In the
+ * above example, the first is horizontal segment (F0) is fixed, the
+ * next is stretchable and then they continue to alternate. Note that
+ * the segment list for each axis can begin or end with a stretchable
+ * or fixed segment.
+ *
+ * The relative sizes of the stretchy segments indicates the relative
+ * amount of stretchiness of the regions bordered by the segments.  For
+ * example, regions 3, 7 and 11 above will take up more horizontal space
+ * than regions 1, 5 and 9 since the horizonal segment associated with
+ * the first set of regions is larger than the other set of regions.  The
+ * ratios of the amount of horizontal (or vertical) space taken by any
+ * two stretchable slices is exactly the ratio of their corresponding
+ * segment lengths.
+ *
+ * xDivs and yDivs point to arrays of horizontal and vertical pixel
+ * indices.  The first pair of Divs (in either array) indicate the
+ * starting and ending points of the first stretchable segment in that
+ * axis. The next pair specifies the next stretchable segment, etc. So
+ * in the above example xDiv[0] and xDiv[1] specify the horizontal
+ * coordinates for the regions labeled 1, 5 and 9.  xDiv[2] and
+ * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that
+ * the leftmost slices always start at x=0 and the rightmost slices
+ * always end at the end of the image. So, for example, the regions 0,
+ * 4 and 8 (which are fixed along the X axis) start at x value 0 and
+ * go to xDiv[0] amd slices 2, 6 and 10 start at xDiv[1] and end at
+ * xDiv[2].
+ *
+ * The array pointed to by the colors field lists contains hints for
+ * each of the regions.  They are ordered according left-to-right and
+ * top-to-bottom as indicated above. For each segment that is a solid
+ * color the array entry will contain that color value; otherwise it
+ * will contain NO_COLOR.  Segments that are completely transparent
+ * will always have the value TRANSPARENT_COLOR.
+ *
+ * The PNG chunk type is "npTc".
+ */
+struct Res_png_9patch
+{
+    Res_png_9patch() : wasDeserialized(false), xDivs(NULL),
+                       yDivs(NULL), colors(NULL) { }
+
+    int8_t wasDeserialized;
+    int8_t numXDivs;
+    int8_t numYDivs;
+    int8_t numColors;
+
+    // These tell where the next section of a patch starts.
+    // For example, the first patch includes the pixels from
+    // 0 to xDivs[0]-1 and the second patch includes the pixels
+    // from xDivs[0] to xDivs[1]-1.
+    // Note: allocation/free of these pointers is left to the caller.
+    int32_t* xDivs;
+    int32_t* yDivs;
+
+    int32_t paddingLeft, paddingRight;
+    int32_t paddingTop, paddingBottom;
+
+    enum {
+        // The 9 patch segment is not a solid color.
+        NO_COLOR = 0x00000001,
+
+        // The 9 patch segment is completely transparent.
+        TRANSPARENT_COLOR = 0x00000000
+    };
+    // Note: allocation/free of this pointer is left to the caller.
+    uint32_t* colors;
+
+    // Convert data from device representation to PNG file representation.
+    void deviceToFile();
+    // Convert data from PNG file representation to device representation.
+    void fileToDevice();
+    // Serialize/Marshall the patch data into a newly malloc-ed block
+    void* serialize();
+    // Serialize/Marshall the patch data
+    void serialize(void* outData);
+    // Deserialize/Unmarshall the patch data
+    static Res_png_9patch* deserialize(const void* data);
+    // Deserialize/Unmarshall the patch data into a newly malloc-ed block
+    static void deserialize(const void* data, Res_png_9patch* outData);
+    // Compute the size of the serialized data structure
+    size_t serializedSize();
+};
+
+/** ********************************************************************
+ *  Base Types
+ *
+ *  These are standard types that are shared between multiple specific
+ *  resource types.
+ *
+ *********************************************************************** */
+
+/**
+ * Header that appears at the front of every data chunk in a resource.
+ */
+struct ResChunk_header
+{
+    // Type identifier for this chunk.  The meaning of this value depends
+    // on the containing chunk.
+    uint16_t type;
+
+    // Size of the chunk header (in bytes).  Adding this value to
+    // the address of the chunk allows you to find its associated data
+    // (if any).
+    uint16_t headerSize;
+
+    // Total size of this chunk (in bytes).  This is the chunkSize plus
+    // the size of any data associated with the chunk.  Adding this value
+    // to the chunk allows you to completely skip its contents (including
+    // any child chunks).  If this value is the same as chunkSize, there is
+    // no data associated with the chunk.
+    uint32_t size;
+};
+
+enum {
+    RES_NULL_TYPE               = 0x0000,
+    RES_STRING_POOL_TYPE        = 0x0001,
+    RES_TABLE_TYPE              = 0x0002,
+    RES_XML_TYPE                = 0x0003,
+
+    // Chunk types in RES_XML_TYPE
+    RES_XML_FIRST_CHUNK_TYPE    = 0x0100,
+    RES_XML_START_NAMESPACE_TYPE= 0x0100,
+    RES_XML_END_NAMESPACE_TYPE  = 0x0101,
+    RES_XML_START_ELEMENT_TYPE  = 0x0102,
+    RES_XML_END_ELEMENT_TYPE    = 0x0103,
+    RES_XML_CDATA_TYPE          = 0x0104,
+    RES_XML_LAST_CHUNK_TYPE     = 0x017f,
+    // This contains a uint32_t array mapping strings in the string
+    // pool back to resource identifiers.  It is optional.
+    RES_XML_RESOURCE_MAP_TYPE   = 0x0180,
+
+    // Chunk types in RES_TABLE_TYPE
+    RES_TABLE_PACKAGE_TYPE      = 0x0200,
+    RES_TABLE_TYPE_TYPE         = 0x0201,
+    RES_TABLE_TYPE_SPEC_TYPE    = 0x0202
+};
+
+/**
+ * Macros for building/splitting resource identifiers.
+ */
+#define Res_VALIDID(resid) (resid != 0)
+#define Res_CHECKID(resid) ((resid&0xFFFF0000) != 0)
+#define Res_MAKEID(package, type, entry) \
+    (((package+1)<<24) | (((type+1)&0xFF)<<16) | (entry&0xFFFF))
+#define Res_GETPACKAGE(id) ((id>>24)-1)
+#define Res_GETTYPE(id) (((id>>16)&0xFF)-1)
+#define Res_GETENTRY(id) (id&0xFFFF)
+
+#define Res_INTERNALID(resid) ((resid&0xFFFF0000) != 0 && (resid&0xFF0000) == 0)
+#define Res_MAKEINTERNAL(entry) (0x01000000 | (entry&0xFFFF))
+#define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF))
+
+#define Res_MAXPACKAGE 255
+
+/**
+ * Representation of a value in a resource, supplying type
+ * information.
+ */
+struct Res_value
+{
+    // Number of bytes in this structure.
+    uint16_t size;
+    
+    // Always set to 0.
+    uint8_t res0;
+        
+    // Type of the data value.
+    enum {
+        // Contains no data.
+        TYPE_NULL = 0x00,
+        // The 'data' holds a ResTable_ref, a reference to another resource
+        // table entry.
+        TYPE_REFERENCE = 0x01,
+        // The 'data' holds an attribute resource identifier.
+        TYPE_ATTRIBUTE = 0x02,
+        // The 'data' holds an index into the containing resource table's
+        // global value string pool.
+        TYPE_STRING = 0x03,
+        // The 'data' holds a single-precision floating point number.
+        TYPE_FLOAT = 0x04,
+        // The 'data' holds a complex number encoding a dimension value,
+        // such as "100in".
+        TYPE_DIMENSION = 0x05,
+        // The 'data' holds a complex number encoding a fraction of a
+        // container.
+        TYPE_FRACTION = 0x06,
+
+        // Beginning of integer flavors...
+        TYPE_FIRST_INT = 0x10,
+
+        // The 'data' is a raw integer value of the form n..n.
+        TYPE_INT_DEC = 0x10,
+        // The 'data' is a raw integer value of the form 0xn..n.
+        TYPE_INT_HEX = 0x11,
+        // The 'data' is either 0 or 1, for input "false" or "true" respectively.
+        TYPE_INT_BOOLEAN = 0x12,
+
+        // Beginning of color integer flavors...
+        TYPE_FIRST_COLOR_INT = 0x1c,
+
+        // The 'data' is a raw integer value of the form #aarrggbb.
+        TYPE_INT_COLOR_ARGB8 = 0x1c,
+        // The 'data' is a raw integer value of the form #rrggbb.
+        TYPE_INT_COLOR_RGB8 = 0x1d,
+        // The 'data' is a raw integer value of the form #argb.
+        TYPE_INT_COLOR_ARGB4 = 0x1e,
+        // The 'data' is a raw integer value of the form #rgb.
+        TYPE_INT_COLOR_RGB4 = 0x1f,
+
+        // ...end of integer flavors.
+        TYPE_LAST_COLOR_INT = 0x1f,
+
+        // ...end of integer flavors.
+        TYPE_LAST_INT = 0x1f
+    };
+    uint8_t dataType;
+
+    // Structure of complex data values (TYPE_UNIT and TYPE_FRACTION)
+    enum {
+        // Where the unit type information is.  This gives us 16 possible
+        // types, as defined below.
+        COMPLEX_UNIT_SHIFT = 0,
+        COMPLEX_UNIT_MASK = 0xf,
+
+        // TYPE_DIMENSION: Value is raw pixels.
+        COMPLEX_UNIT_PX = 0,
+        // TYPE_DIMENSION: Value is Device Independent Pixels.
+        COMPLEX_UNIT_DIP = 1,
+        // TYPE_DIMENSION: Value is a Scaled device independent Pixels.
+        COMPLEX_UNIT_SP = 2,
+        // TYPE_DIMENSION: Value is in points.
+        COMPLEX_UNIT_PT = 3,
+        // TYPE_DIMENSION: Value is in inches.
+        COMPLEX_UNIT_IN = 4,
+        // TYPE_DIMENSION: Value is in millimeters.
+        COMPLEX_UNIT_MM = 5,
+
+        // TYPE_FRACTION: A basic fraction of the overall size.
+        COMPLEX_UNIT_FRACTION = 0,
+        // TYPE_FRACTION: A fraction of the parent size.
+        COMPLEX_UNIT_FRACTION_PARENT = 1,
+
+        // Where the radix information is, telling where the decimal place
+        // appears in the mantissa.  This give us 4 possible fixed point
+        // representations as defined below.
+        COMPLEX_RADIX_SHIFT = 4,
+        COMPLEX_RADIX_MASK = 0x3,
+
+        // The mantissa is an integral number -- i.e., 0xnnnnnn.0
+        COMPLEX_RADIX_23p0 = 0,
+        // The mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn
+        COMPLEX_RADIX_16p7 = 1,
+        // The mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn
+        COMPLEX_RADIX_8p15 = 2,
+        // The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn
+        COMPLEX_RADIX_0p23 = 3,
+
+        // Where the actual value is.  This gives us 23 bits of
+        // precision.  The top bit is the sign.
+        COMPLEX_MANTISSA_SHIFT = 8,
+        COMPLEX_MANTISSA_MASK = 0xffffff
+    };
+
+    // The data for this item, as interpreted according to dataType.
+    uint32_t data;
+
+    void copyFrom_dtoh(const Res_value& src);
+};
+
+/**
+ *  This is a reference to a unique entry (a ResTable_entry structure)
+ *  in a resource table.  The value is structured as: 0xpptteeee,
+ *  where pp is the package index, tt is the type index in that
+ *  package, and eeee is the entry index in that type.  The package
+ *  and type values start at 1 for the first item, to help catch cases
+ *  where they have not been supplied.
+ */
+struct ResTable_ref
+{
+    uint32_t ident;
+};
+
+/**
+ * Reference to a string in a string pool.
+ */
+struct ResStringPool_ref
+{
+    // Index into the string pool table (uint32_t-offset from the indices
+    // immediately after ResStringPool_header) at which to find the location
+    // of the string data in the pool.
+    uint32_t index;
+};
+
+/** ********************************************************************
+ *  String Pool
+ *
+ *  A set of strings that can be references by others through a
+ *  ResStringPool_ref.
+ *
+ *********************************************************************** */
+
+/**
+ * Definition for a pool of strings.  The data of this chunk is an
+ * array of uint32_t providing indices into the pool, relative to
+ * stringsStart.  At stringsStart are all of the UTF-16 strings
+ * concatenated together; each starts with a uint16_t of the string's
+ * length and each ends with a 0x0000 terminator.  If a string is >
+ * 32767 characters, the high bit of the length is set meaning to take
+ * those 15 bits as a high word and it will be followed by another
+ * uint16_t containing the low word.
+ *
+ * If styleCount is not zero, then immediately following the array of
+ * uint32_t indices into the string table is another array of indices
+ * into a style table starting at stylesStart.  Each entry in the
+ * style table is an array of ResStringPool_span structures.
+ */
+struct ResStringPool_header
+{
+    struct ResChunk_header header;
+
+    // Number of strings in this pool (number of uint32_t indices that follow
+    // in the data).
+    uint32_t stringCount;
+
+    // Number of style span arrays in the pool (number of uint32_t indices
+    // follow the string indices).
+    uint32_t styleCount;
+
+    // Flags.
+    enum {
+        // If set, the string index is sorted by the string values (based
+        // on strcmp16()).
+        SORTED_FLAG = 1<<0
+    };
+    uint32_t flags;
+
+    // Index from header of the string data.
+    uint32_t stringsStart;
+
+    // Index from header of the style data.
+    uint32_t stylesStart;
+};
+
+/**
+ * This structure defines a span of style information associated with
+ * a string in the pool.
+ */
+struct ResStringPool_span
+{
+    enum {
+        END = 0xFFFFFFFF
+    };
+
+    // This is the name of the span -- that is, the name of the XML
+    // tag that defined it.  The special value END (0xFFFFFFFF) indicates
+    // the end of an array of spans.
+    ResStringPool_ref name;
+
+    // The range of characters in the string that this span applies to.
+    uint32_t firstChar, lastChar;
+};
+
+/**
+ * Convenience class for accessing data in a ResStringPool resource.
+ */
+class ResStringPool
+{
+public:
+    ResStringPool();
+    ResStringPool(const void* data, size_t size, bool copyData=false);
+    ~ResStringPool();
+
+    status_t setTo(const void* data, size_t size, bool copyData=false);
+
+    status_t getError() const;
+
+    void uninit();
+
+    inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {
+        return stringAt(ref.index, outLen);
+    }
+    const char16_t* stringAt(size_t idx, size_t* outLen) const;
+
+    const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;
+    const ResStringPool_span* styleAt(size_t idx) const;
+
+    ssize_t indexOfString(const char16_t* str, size_t strLen) const;
+
+    size_t size() const;
+
+private:
+    status_t                    mError;
+    void*                       mOwnedData;
+    const ResStringPool_header* mHeader;
+    size_t                      mSize;
+    const uint32_t*             mEntries;
+    const uint32_t*             mEntryStyles;
+    const char16_t*             mStrings;
+    uint32_t                    mStringPoolSize;    // number of uint16_t
+    const uint32_t*             mStyles;
+    uint32_t                    mStylePoolSize;    // number of uint32_t
+};
+
+/** ********************************************************************
+ *  XML Tree
+ *
+ *  Binary representation of an XML document.  This is designed to
+ *  express everything in an XML document, in a form that is much
+ *  easier to parse on the device.
+ *
+ *********************************************************************** */
+
+/**
+ * XML tree header.  This appears at the front of an XML tree,
+ * describing its content.  It is followed by a flat array of
+ * ResXMLTree_node structures; the hierarchy of the XML document
+ * is described by the occurrance of RES_XML_START_ELEMENT_TYPE
+ * and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array.
+ */
+struct ResXMLTree_header
+{
+    struct ResChunk_header header;
+};
+
+/**
+ * Basic XML tree node.  A single item in the XML document.  Extended info
+ * about the node can be found after header.headerSize.
+ */
+struct ResXMLTree_node
+{
+    struct ResChunk_header header;
+
+    // Line number in original source file at which this element appeared.
+    uint32_t lineNumber;
+
+    // Optional XML comment that was associated with this element; -1 if none.
+    struct ResStringPool_ref comment;
+};
+
+/**
+ * Extended XML tree node for CDATA tags -- includes the CDATA string.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_cdataExt
+{
+    // The raw CDATA character data.
+    struct ResStringPool_ref data;
+    
+    // The typed value of the character data if this is a CDATA node.
+    struct Res_value typedData;
+};
+
+/**
+ * Extended XML tree node for namespace start/end nodes.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_namespaceExt
+{
+    // The prefix of the namespace.
+    struct ResStringPool_ref prefix;
+    
+    // The URI of the namespace.
+    struct ResStringPool_ref uri;
+};
+
+/**
+ * Extended XML tree node for element start/end nodes.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_endElementExt
+{
+    // String of the full namespace of this element.
+    struct ResStringPool_ref ns;
+    
+    // String name of this node if it is an ELEMENT; the raw
+    // character data if this is a CDATA node.
+    struct ResStringPool_ref name;
+};
+
+/**
+ * Extended XML tree node for start tags -- includes attribute
+ * information.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_attrExt
+{
+    // String of the full namespace of this element.
+    struct ResStringPool_ref ns;
+    
+    // String name of this node if it is an ELEMENT; the raw
+    // character data if this is a CDATA node.
+    struct ResStringPool_ref name;
+    
+    // Byte offset from the start of this structure where the attributes start.
+    uint16_t attributeStart;
+    
+    // Size of the ResXMLTree_attribute structures that follow.
+    uint16_t attributeSize;
+    
+    // Number of attributes associated with an ELEMENT.  These are
+    // available as an array of ResXMLTree_attribute structures
+    // immediately following this node.
+    uint16_t attributeCount;
+    
+    // Index (1-based) of the "id" attribute. 0 if none.
+    uint16_t idIndex;
+    
+    // Index (1-based) of the "class" attribute. 0 if none.
+    uint16_t classIndex;
+    
+    // Index (1-based) of the "style" attribute. 0 if none.
+    uint16_t styleIndex;
+};
+
+struct ResXMLTree_attribute
+{
+    // Namespace of this attribute.
+    struct ResStringPool_ref ns;
+    
+    // Name of this attribute.
+    struct ResStringPool_ref name;
+
+    // The original raw string value of this attribute.
+    struct ResStringPool_ref rawValue;
+    
+    // Processesd typed value of this attribute.
+    struct Res_value typedValue;
+};
+
+class ResXMLTree;
+
+class ResXMLParser
+{
+public:
+    ResXMLParser(const ResXMLTree& tree);
+
+    enum event_code_t {
+        BAD_DOCUMENT = -1,
+        START_DOCUMENT = 0,
+        END_DOCUMENT = 1,
+        
+        FIRST_CHUNK_CODE = RES_XML_FIRST_CHUNK_TYPE, 
+        
+        START_NAMESPACE = RES_XML_START_NAMESPACE_TYPE,
+        END_NAMESPACE = RES_XML_END_NAMESPACE_TYPE,
+        START_TAG = RES_XML_START_ELEMENT_TYPE,
+        END_TAG = RES_XML_END_ELEMENT_TYPE,
+        TEXT = RES_XML_CDATA_TYPE
+    };
+
+    struct ResXMLPosition
+    {
+        event_code_t                eventCode;
+        const ResXMLTree_node*      curNode;
+        const void*                 curExt;
+    };
+
+    void restart();
+
+    event_code_t getEventType() const;
+    // Note, unlike XmlPullParser, the first call to next() will return
+    // START_TAG of the first element.
+    event_code_t next();
+
+    // These are available for all nodes:
+    const int32_t getCommentID() const;
+    const uint16_t* getComment(size_t* outLen) const;
+    const uint32_t getLineNumber() const;
+    
+    // This is available for TEXT:
+    const int32_t getTextID() const;
+    const uint16_t* getText(size_t* outLen) const;
+    ssize_t getTextValue(Res_value* outValue) const;
+    
+    // These are available for START_NAMESPACE and END_NAMESPACE:
+    const int32_t getNamespacePrefixID() const;
+    const uint16_t* getNamespacePrefix(size_t* outLen) const;
+    const int32_t getNamespaceUriID() const;
+    const uint16_t* getNamespaceUri(size_t* outLen) const;
+    
+    // These are available for START_TAG and END_TAG:
+    const int32_t getElementNamespaceID() const;
+    const uint16_t* getElementNamespace(size_t* outLen) const;
+    const int32_t getElementNameID() const;
+    const uint16_t* getElementName(size_t* outLen) const;
+    
+    // Remaining methods are for retrieving information about attributes
+    // associated with a START_TAG:
+    
+    size_t getAttributeCount() const;
+    
+    // Returns -1 if no namespace, -2 if idx out of range.
+    const int32_t getAttributeNamespaceID(size_t idx) const;
+    const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;
+    
+    const int32_t getAttributeNameID(size_t idx) const;
+    const uint16_t* getAttributeName(size_t idx, size_t* outLen) const;
+    const uint32_t getAttributeNameResID(size_t idx) const;
+    
+    const int32_t getAttributeValueStringID(size_t idx) const;
+    const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;
+    
+    int32_t getAttributeDataType(size_t idx) const;
+    int32_t getAttributeData(size_t idx) const;
+    ssize_t getAttributeValue(size_t idx, Res_value* outValue) const;
+
+    ssize_t indexOfAttribute(const char* ns, const char* attr) const;
+    ssize_t indexOfAttribute(const char16_t* ns, size_t nsLen,
+                             const char16_t* attr, size_t attrLen) const;
+
+    ssize_t indexOfID() const;
+    ssize_t indexOfClass() const;
+    ssize_t indexOfStyle() const;
+
+    void getPosition(ResXMLPosition* pos) const;
+    void setPosition(const ResXMLPosition& pos);
+
+private:
+    friend class ResXMLTree;
+    
+    event_code_t nextNode();
+
+    const ResXMLTree&           mTree;
+    event_code_t                mEventCode;
+    const ResXMLTree_node*      mCurNode;
+    const void*                 mCurExt;
+};
+
+/**
+ * Convenience class for accessing data in a ResXMLTree resource.
+ */
+class ResXMLTree : public ResXMLParser
+{
+public:
+    ResXMLTree();
+    ResXMLTree(const void* data, size_t size, bool copyData=false);
+    ~ResXMLTree();
+
+    status_t setTo(const void* data, size_t size, bool copyData=false);
+
+    status_t getError() const;
+
+    void uninit();
+
+    const ResStringPool& getStrings() const;
+
+private:
+    friend class ResXMLParser;
+
+    status_t validateNode(const ResXMLTree_node* node) const;
+
+    status_t                    mError;
+    void*                       mOwnedData;
+    const ResXMLTree_header*    mHeader;
+    size_t                      mSize;
+    const uint8_t*              mDataEnd;
+    ResStringPool               mStrings;
+    const uint32_t*             mResIds;
+    size_t                      mNumResIds;
+    const ResXMLTree_node*      mRootNode;
+    const void*                 mRootExt;
+    event_code_t                mRootCode;
+};
+
+/** ********************************************************************
+ *  RESOURCE TABLE
+ *
+ *********************************************************************** */
+
+/**
+ * Header for a resource table.  Its data contains a series of
+ * additional chunks:
+ *   * A ResStringPool_header containing all table values.
+ *   * One or more ResTable_package chunks.
+ *
+ * Specific entries within a resource table can be uniquely identified
+ * with a single integer as defined by the ResTable_ref structure.
+ */
+struct ResTable_header
+{
+    struct ResChunk_header header;
+
+    // The number of ResTable_package structures.
+    uint32_t packageCount;
+};
+
+/**
+ * A collection of resource data types within a package.  Followed by
+ * one or more ResTable_type and ResTable_typeSpec structures containing the
+ * entry values for each resource type.
+ */
+struct ResTable_package
+{
+    struct ResChunk_header header;
+
+    // If this is a base package, its ID.  Package IDs start
+    // at 1 (corresponding to the value of the package bits in a
+    // resource identifier).  0 means this is not a base package.
+    uint32_t id;
+
+    // Actual name of this package, \0-terminated.
+    char16_t name[128];
+
+    // Offset to a ResStringPool_header defining the resource
+    // type symbol table.  If zero, this package is inheriting from
+    // another base package (overriding specific values in it).
+    uint32_t typeStrings;
+
+    // Last index into typeStrings that is for public use by others.
+    uint32_t lastPublicType;
+
+    // Offset to a ResStringPool_header defining the resource
+    // key symbol table.  If zero, this package is inheriting from
+    // another base package (overriding specific values in it).
+    uint32_t keyStrings;
+
+    // Last index into keyStrings that is for public use by others.
+    uint32_t lastPublicKey;
+};
+
+/**
+ * Describes a particular resource configuration.
+ */
+struct ResTable_config
+{
+    // Number of bytes in this structure.
+    uint32_t size;
+    
+    union {
+        struct {
+            // Mobile country code (from SIM).  0 means "any".
+            uint16_t mcc;
+            // Mobile network code (from SIM).  0 means "any".
+            uint16_t mnc;
+        };
+        uint32_t imsi;
+    };
+    
+    union {
+        struct {
+            // \0\0 means "any".  Otherwise, en, fr, etc.
+            char language[2];
+            
+            // \0\0 means "any".  Otherwise, US, CA, etc.
+            char country[2];
+        };
+        uint32_t locale;
+    };
+    
+    enum {
+        ORIENTATION_ANY  = 0x0000,
+        ORIENTATION_PORT = 0x0001,
+        ORIENTATION_LAND = 0x0002,
+        ORIENTATION_SQUARE = 0x0002,
+    };
+    
+    enum {
+        TOUCHSCREEN_ANY  = 0x0000,
+        TOUCHSCREEN_NOTOUCH  = 0x0001,
+        TOUCHSCREEN_STYLUS  = 0x0002,
+        TOUCHSCREEN_FINGER  = 0x0003,
+    };
+    
+    enum {
+        DENSITY_ANY = 0
+    };
+    
+    union {
+        struct {
+            uint8_t orientation;
+            uint8_t touchscreen;
+            uint16_t density;
+        };
+        uint32_t screenType;
+    };
+    
+    enum {
+        KEYBOARD_ANY  = 0x0000,
+        KEYBOARD_NOKEYS  = 0x0001,
+        KEYBOARD_QWERTY  = 0x0002,
+        KEYBOARD_12KEY  = 0x0003,
+    };
+    
+    enum {
+        NAVIGATION_ANY  = 0x0000,
+        NAVIGATION_NONAV  = 0x0001,
+        NAVIGATION_DPAD  = 0x0002,
+        NAVIGATION_TRACKBALL  = 0x0003,
+        NAVIGATION_WHEEL  = 0x0004,
+    };
+    
+    enum {
+        MASK_KEYSHIDDEN = 0x0003,
+        SHIFT_KEYSHIDDEN = 0,
+        KEYSHIDDEN_ANY = 0x0000,
+        KEYSHIDDEN_NO = 0x0001,
+        KEYSHIDDEN_YES = 0x0002,
+    };
+    
+    union {
+        struct {
+            uint8_t keyboard;
+            uint8_t navigation;
+            uint8_t inputFlags;
+            uint8_t pad0;
+        };
+        uint32_t input;
+    };
+    
+    enum {
+        SCREENWIDTH_ANY = 0
+    };
+    
+    enum {
+        SCREENHEIGHT_ANY = 0
+    };
+    
+    union {
+        struct {
+            uint16_t screenWidth;
+            uint16_t screenHeight;
+        };
+        uint32_t screenSize;
+    };
+    
+    enum {
+        SDKVERSION_ANY = 0
+    };
+    
+    enum {
+        MINORVERSION_ANY = 0
+    };
+    
+    union {
+        struct {
+            uint16_t sdkVersion;
+            // For now minorVersion must always be 0!!!  Its meaning
+            // is currently undefined.
+            uint16_t minorVersion;
+        };
+        uint32_t version;
+    };
+    
+    inline void copyFromDeviceNoSwap(const ResTable_config& o) {
+        const size_t size = dtohl(o.size);
+        if (size >= sizeof(ResTable_config)) {
+            *this = o;
+        } else {
+            memcpy(this, &o, size);
+            memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
+        }
+    }
+    
+    inline void copyFromDtoH(const ResTable_config& o) {
+        copyFromDeviceNoSwap(o);
+        size = sizeof(ResTable_config);
+        mcc = dtohs(mcc);
+        mnc = dtohs(mnc);
+        density = dtohs(density);
+        screenWidth = dtohs(screenWidth);
+        screenHeight = dtohs(screenHeight);
+        sdkVersion = dtohs(sdkVersion);
+        minorVersion = dtohs(minorVersion);
+    }
+    
+    inline void swapHtoD() {
+        size = htodl(size);
+        mcc = htods(mcc);
+        mnc = htods(mnc);
+        density = htods(density);
+        screenWidth = htods(screenWidth);
+        screenHeight = htods(screenHeight);
+        sdkVersion = htods(sdkVersion);
+        minorVersion = htods(minorVersion);
+    }
+    
+    inline int compare(const ResTable_config& o) const {
+        int32_t diff = (int32_t)(imsi - o.imsi);
+        if (diff != 0) return diff;
+        diff = (int32_t)(locale - o.locale);
+        if (diff != 0) return diff;
+        diff = (int32_t)(screenType - o.screenType);
+        if (diff != 0) return diff;
+        diff = (int32_t)(input - o.input);
+        if (diff != 0) return diff;
+        diff = (int32_t)(screenSize - o.screenSize);
+        if (diff != 0) return diff;
+        diff = (int32_t)(version - o.version);
+        return (int)diff;
+    }
+    
+    // Flags indicating a set of config values.  These flag constants must
+    // 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
+    };
+    
+    // Compare two configuration, returning CONFIG_* flags set for each value
+    // that is different.
+    inline int diff(const ResTable_config& o) const {
+        int diffs = 0;
+        if (mcc != o.mcc) diffs |= CONFIG_MCC;
+        if (mnc != o.mnc) diffs |= CONFIG_MNC;
+        if (locale != o.locale) diffs |= CONFIG_LOCALE;
+        if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
+        if (density != o.density) diffs |= CONFIG_DENSITY;
+        if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
+        if (((inputFlags^o.inputFlags)&MASK_KEYSHIDDEN) != 0) diffs |= CONFIG_KEYBOARD_HIDDEN;
+        if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
+        if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
+        if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
+        if (version != o.version) diffs |= CONFIG_VERSION;
+        return diffs;
+    }
+    
+    // Return true if 'this' is more specific than 'o'.
+    inline bool
+    isBetterThan(const ResTable_config& o, const ResTable_config* requested = NULL) const {
+        if (imsi != 0 && (!requested || requested->imsi != 0)) {
+            if (mcc != 0 && (!requested || requested->mcc!= 0)) {
+                if (o.mcc == 0) {
+                    return true;
+                }
+            }
+            if (mnc != 0 && (!requested || requested->mnc != 0)) {
+                if (o.mnc == 0) {
+                    return true;
+                }
+            }
+        }
+        if (locale != 0 && (!requested || requested->locale != 0)) {
+            if (language[0] != 0 && (!requested || requested->language[0] != 0)) {
+                if (o.language[0] == 0) {
+                    return true;
+                }
+            }
+            if (country[0] != 0 && (!requested || requested->country[0] != 0)) {
+                if (o.country[0] == 0) {
+                    return true;
+                }
+            }
+        }
+        if (screenType != 0 && (!requested || requested->screenType != 0)) {
+            if (orientation != 0 && (!requested || requested->orientation != 0)) {
+                if (o.orientation == 0) {
+                    return true;
+                }
+            }
+            if (density != 0 && (!requested || requested->density != 0)) {
+                if (o.density == 0) {
+                    return true;
+                }
+            }
+            if (touchscreen != 0 && (!requested || requested->touchscreen != 0)) {
+                if (o.touchscreen == 0) {
+                    return true;
+                }
+            }
+        }
+        if (input != 0 && (!requested || requested->input != 0)) {
+            if ((inputFlags&MASK_KEYSHIDDEN) != 0 && (!requested
+                                                      || (requested->inputFlags&MASK_KEYSHIDDEN) != 0)) {
+                if ((o.inputFlags&MASK_KEYSHIDDEN) == 0) {
+                    return true;
+                }
+            }
+            if (keyboard != 0 && (!requested || requested->keyboard != 0)) {
+                if (o.keyboard == 0) {
+                    return true;
+                }
+            }
+            if (navigation != 0 && (!requested || requested->navigation != 0)) {
+                if (o.navigation == 0) {
+                    return true;
+                }
+            }
+        }
+        if (screenSize != 0 && (!requested || requested->screenSize != 0)) {
+            if (screenWidth != 0 && (!requested || requested->screenWidth != 0)) {
+                if (o.screenWidth == 0) {
+                    return true;
+                }
+            }
+            if (screenHeight != 0 && (!requested || requested->screenHeight != 0)) {
+                if (o.screenHeight == 0) {
+                    return true;
+                }
+            }
+        }
+        if (version != 0 && (!requested || requested->version != 0)) {
+            if (sdkVersion != 0 && (!requested || requested->sdkVersion != 0)) {
+                if (o.sdkVersion == 0) {
+                    return true;
+                }
+            }
+            if (minorVersion != 0 && (!requested || requested->minorVersion != 0)) {
+                if (o.minorVersion == 0) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
+    // Return true if 'this' matches the parameters in 'settings'.
+    inline bool match(const ResTable_config& settings) const {
+        if (imsi != 0) {
+            if (settings.mcc != 0 && mcc != 0
+                && mcc != settings.mcc) {
+                return false;
+            }
+            if (settings.mnc != 0 && mnc != 0
+                && mnc != settings.mnc) {
+                return false;
+            }
+        }
+        if (locale != 0) {
+            if (settings.language[0] != 0 && language[0] != 0
+                && (language[0] != settings.language[0]
+                    || language[1] != settings.language[1])) {
+                return false;
+            }
+            if (settings.country[0] != 0 && country[0] != 0
+                && (country[0] != settings.country[0]
+                    || country[1] != settings.country[1])) {
+                return false;
+            }
+        }
+        if (screenType != 0) {
+            if (settings.orientation != 0 && orientation != 0
+                && orientation != settings.orientation) {
+                return false;
+            }
+            if (settings.density != 0 && density != 0
+                && density != settings.density) {
+                return false;
+            }
+            if (settings.touchscreen != 0 && touchscreen != 0
+                && touchscreen != settings.touchscreen) {
+                return false;
+            }
+        }
+        if (input != 0) {
+            const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
+            const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
+            if (setKeysHidden != 0 && keysHidden != 0
+                && keysHidden != setKeysHidden) {
+                return false;
+            }
+            if (settings.keyboard != 0 && keyboard != 0
+                && keyboard != settings.keyboard) {
+                return false;
+            }
+            if (settings.navigation != 0 && navigation != 0
+                && navigation != settings.navigation) {
+                return false;
+            }
+        }
+        if (screenSize != 0) {
+            if (settings.screenWidth != 0 && screenWidth != 0
+                && screenWidth != settings.screenWidth) {
+                return false;
+            }
+            if (settings.screenHeight != 0 && screenHeight != 0
+                && screenHeight != settings.screenHeight) {
+                return false;
+            }
+        }
+        if (version != 0) {
+            if (settings.sdkVersion != 0 && sdkVersion != 0
+                && sdkVersion != settings.sdkVersion) {
+                return false;
+            }
+            if (settings.minorVersion != 0 && minorVersion != 0
+                && minorVersion != settings.minorVersion) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void getLocale(char str[6]) const {
+        memset(str, 0, 6);
+        if (language[0]) {
+            str[0] = language[0];
+            str[1] = language[1];
+            if (country[0]) {
+                str[2] = '_';
+                str[3] = country[0];
+                str[4] = country[1];
+            }
+        }
+    }
+
+    String8 toString() const {
+        char buf[200];
+        sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=0x%02x touch=0x%02x dens=0x%02x "
+                "kbd=0x%02x nav=0x%02x input=0x%02x screenW=0x%04x screenH=0x%04x vers=%d.%d",
+                mcc, mnc,
+                language[0] ? language[0] : '-', language[1] ? language[1] : '-',
+                country[0] ? country[0] : '-', country[1] ? country[1] : '-',
+                orientation, touchscreen, density, keyboard, navigation, inputFlags,
+                screenWidth, screenHeight, sdkVersion, minorVersion);
+        return String8(buf);
+    }
+};
+
+/**
+ * A specification of the resources defined by a particular type.
+ *
+ * There should be one of these chunks for each resource type.
+ *
+ * This structure is followed by an array of integers providing the set of
+ * configuation change flags (ResTable_config::CONFIG_*) that have multiple
+ * resources for that configuration.  In addition, the high bit is set if that
+ * resource has been made public.
+ */
+struct ResTable_typeSpec
+{
+    struct ResChunk_header header;
+
+    // The type identifier this chunk is holding.  Type IDs start
+    // at 1 (corresponding to the value of the type bits in a
+    // resource identifier).  0 is invalid.
+    uint8_t id;
+    
+    // Must be 0.
+    uint8_t res0;
+    // Must be 0.
+    uint16_t res1;
+    
+    // Number of uint32_t entry configuration masks that follow.
+    uint32_t entryCount;
+
+    enum {
+        // Additional flag indicating an entry is public.
+        SPEC_PUBLIC = 0x40000000
+    };
+};
+
+/**
+ * A collection of resource entries for a particular resource data
+ * type. Followed by an array of uint32_t defining the resource
+ * values, corresponding to the array of type strings in the
+ * ResTable_package::typeStrings string block. Each of these hold an
+ * index from entriesStart; a value of NO_ENTRY means that entry is
+ * not defined.
+ *
+ * There may be multiple of these chunks for a particular resource type,
+ * supply different configuration variations for the resource values of
+ * that type.
+ *
+ * It would be nice to have an additional ordered index of entries, so
+ * we can do a binary search if trying to find a resource by string name.
+ */
+struct ResTable_type
+{
+    struct ResChunk_header header;
+
+    enum {
+        NO_ENTRY = 0xFFFFFFFF
+    };
+    
+    // The type identifier this chunk is holding.  Type IDs start
+    // at 1 (corresponding to the value of the type bits in a
+    // resource identifier).  0 is invalid.
+    uint8_t id;
+    
+    // Must be 0.
+    uint8_t res0;
+    // Must be 0.
+    uint16_t res1;
+    
+    // Number of uint32_t entry indices that follow.
+    uint32_t entryCount;
+
+    // Offset from header where ResTable_entry data starts.
+    uint32_t entriesStart;
+    
+    // Configuration this collection of entries is designed for.
+    ResTable_config config;
+};
+
+/**
+ * This is the beginning of information about an entry in the resource
+ * table.  It holds the reference to the name of this entry, and is
+ * immediately followed by one of:
+ *   * A Res_value structures, if FLAG_COMPLEX is -not- set.
+ *   * An array of ResTable_map structures, if FLAG_COMPLEX is set.
+ *     These supply a set of name/value mappings of data.
+ */
+struct ResTable_entry
+{
+    // Number of bytes in this structure.
+    uint16_t size;
+
+    enum {
+        // If set, this is a complex entry, holding a set of name/value
+        // mappings.  It is followed by an array of ResTable_map structures.
+        FLAG_COMPLEX = 0x0001,
+        // If set, this resource has been declared public, so libraries
+        // are allowed to reference it.
+        FLAG_PUBLIC = 0x0002
+    };
+    uint16_t flags;
+    
+    // Reference into ResTable_package::keyStrings identifying this entry.
+    struct ResStringPool_ref key;
+};
+
+/**
+ * Extended form of a ResTable_entry for map entries, defining a parent map
+ * resource from which to inherit values.
+ */
+struct ResTable_map_entry : public ResTable_entry
+{
+    // Resource identifier of the parent mapping, or 0 if there is none.
+    ResTable_ref parent;
+    // Number of name/value pairs that follow for FLAG_COMPLEX.
+    uint32_t count;
+};
+
+/**
+ * A single name/value mapping that is part of a complex resource
+ * entry.
+ */
+struct ResTable_map
+{
+    // The resource identifier defining this mapping's name.  For attribute
+    // resources, 'name' can be one of the following special resource types
+    // to supply meta-data about the attribute; for all other resource types
+    // it must be an attribute resource.
+    ResTable_ref name;
+
+    // Special values for 'name' when defining attribute resources.
+    enum {
+        // This entry holds the attribute's type code.
+        ATTR_TYPE = Res_MAKEINTERNAL(0),
+
+        // For integral attributes, this is the minimum value it can hold.
+        ATTR_MIN = Res_MAKEINTERNAL(1),
+
+        // For integral attributes, this is the maximum value it can hold.
+        ATTR_MAX = Res_MAKEINTERNAL(2),
+
+        // Localization of this resource is can be encouraged or required with
+        // an aapt flag if this is set
+        ATTR_L10N = Res_MAKEINTERNAL(3),
+
+        // for plural support, see android.content.res.PluralRules#attrForQuantity(int)
+        ATTR_OTHER = Res_MAKEINTERNAL(4),
+        ATTR_ZERO = Res_MAKEINTERNAL(5),
+        ATTR_ONE = Res_MAKEINTERNAL(6),
+        ATTR_TWO = Res_MAKEINTERNAL(7),
+        ATTR_FEW = Res_MAKEINTERNAL(8),
+        ATTR_MANY = Res_MAKEINTERNAL(9)
+        
+    };
+
+    // Bit mask of allowed types, for use with ATTR_TYPE.
+    enum {
+        // No type has been defined for this attribute, use generic
+        // type handling.  The low 16 bits are for types that can be
+        // handled generically; the upper 16 require additional information
+        // in the bag so can not be handled generically for TYPE_ANY.
+        TYPE_ANY = 0x0000FFFF,
+
+        // Attribute holds a references to another resource.
+        TYPE_REFERENCE = 1<<0,
+
+        // Attribute holds a generic string.
+        TYPE_STRING = 1<<1,
+
+        // Attribute holds an integer value.  ATTR_MIN and ATTR_MIN can
+        // optionally specify a constrained range of possible integer values.
+        TYPE_INTEGER = 1<<2,
+
+        // Attribute holds a boolean integer.
+        TYPE_BOOLEAN = 1<<3,
+
+        // Attribute holds a color value.
+        TYPE_COLOR = 1<<4,
+
+        // Attribute holds a floating point value.
+        TYPE_FLOAT = 1<<5,
+
+        // Attribute holds a dimension value, such as "20px".
+        TYPE_DIMENSION = 1<<6,
+
+        // Attribute holds a fraction value, such as "20%".
+        TYPE_FRACTION = 1<<7,
+
+        // Attribute holds an enumeration.  The enumeration values are
+        // supplied as additional entries in the map.
+        TYPE_ENUM = 1<<16,
+
+        // Attribute holds a bitmaks of flags.  The flag bit values are
+        // supplied as additional entries in the map.
+        TYPE_FLAGS = 1<<17
+    };
+
+    // Enum of localization modes, for use with ATTR_L10N.
+    enum {
+        L10N_NOT_REQUIRED = 0,
+        L10N_SUGGESTED    = 1
+    };
+    
+    // This mapping's value.
+    Res_value value;
+};
+
+/**
+ * Convenience class for accessing data in a ResTable resource.
+ */
+class ResTable
+{
+public:
+    ResTable();
+    ResTable(const void* data, size_t size, void* cookie,
+             bool copyData=false);
+    ~ResTable();
+
+    status_t add(const void* data, size_t size, void* cookie,
+                 bool copyData=false);
+    status_t add(Asset* asset, void* cookie,
+                 bool copyData=false);
+
+    status_t getError() const;
+
+    void uninit();
+
+    struct resource_name
+    {
+        const char16_t* package;
+        size_t packageLen;
+        const char16_t* type;
+        size_t typeLen;
+        const char16_t* name;
+        size_t nameLen;
+    };
+
+    bool getResourceName(uint32_t resID, resource_name* outName) const;
+
+    /**
+     * Retrieve the value of a resource.  If the resource is found, returns a
+     * value >= 0 indicating the table it is in (for use with
+     * getTableStringBlock() and getTableCookie()) and fills in 'outValue'.  If
+     * not found, returns a negative error code.
+     *
+     * Note that this function does not do reference traversal.  If you want
+     * to follow references to other resources to get the "real" value to
+     * use, you need to call resolveReference() after this function.
+     *
+     * @param resID The desired resoruce identifier.
+     * @param outValue Filled in with the resource data that was found.
+     *
+     * @return ssize_t Either a >= 0 table index or a negative error code.
+     */
+    ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag=false,
+            uint32_t* outSpecFlags=NULL) const;
+
+    inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,
+            uint32_t* outSpecFlags=NULL) const {
+        return getResource(res.ident, outValue, outSpecFlags);
+    }
+
+    ssize_t resolveReference(Res_value* inOutValue,
+                             ssize_t blockIndex,
+                             uint32_t* outLastRef = NULL,
+                             uint32_t* inoutTypeSpecFlags = NULL) const;
+
+    enum {
+        TMP_BUFFER_SIZE = 16
+    };
+    const char16_t* valueToString(const Res_value* value, size_t stringBlock,
+                                  char16_t tmpBuffer[TMP_BUFFER_SIZE],
+                                  size_t* outLen);
+
+    struct bag_entry {
+        ssize_t stringBlock;
+        ResTable_map map;
+    };
+
+    /**
+     * Retrieve the bag of a resource.  If the resoruce is found, returns the
+     * number of bags it contains and 'outBag' points to an array of their
+     * values.  If not found, a negative error code is returned.
+     *
+     * Note that this function -does- do reference traversal of the bag data.
+     *
+     * @param resID The desired resource identifier.
+     * @param outBag Filled inm with a pointer to the bag mappings.
+     *
+     * @return ssize_t Either a >= 0 bag count of negative error code.
+     */
+    ssize_t lockBag(uint32_t resID, const bag_entry** outBag) const;
+
+    void unlockBag(const bag_entry* bag) const;
+
+    void lock() const;
+
+    ssize_t getBagLocked(uint32_t resID, const bag_entry** outBag,
+            uint32_t* outTypeSpecFlags=NULL) const;
+
+    void unlock() const;
+
+    class Theme {
+    public:
+        Theme(const ResTable& table);
+        ~Theme();
+
+        inline const ResTable& getResTable() const { return mTable; }
+
+        status_t applyStyle(uint32_t resID, bool force=false);
+        status_t setTo(const Theme& other);
+
+        /**
+         * Retrieve a value in the theme.  If the theme defines this
+         * value, returns a value >= 0 indicating the table it is in
+         * (for use with getTableStringBlock() and getTableCookie) and
+         * fills in 'outValue'.  If not found, returns a negative error
+         * code.
+         *
+         * Note that this function does not do reference traversal.  If you want
+         * to follow references to other resources to get the "real" value to
+         * use, you need to call resolveReference() after this function.
+         *
+         * @param resID A resource identifier naming the desired theme
+         *              attribute.
+         * @param outValue Filled in with the theme value that was
+         *                 found.
+         *
+         * @return ssize_t Either a >= 0 table index or a negative error code.
+         */
+        ssize_t getAttribute(uint32_t resID, Res_value* outValue,
+                uint32_t* outTypeSpecFlags = NULL) const;
+
+        /**
+         * This is like ResTable::resolveReference(), but also takes
+         * care of resolving attribute references to the theme.
+         */
+        ssize_t resolveAttributeReference(Res_value* inOutValue,
+                ssize_t blockIndex, uint32_t* outLastRef = NULL,
+                uint32_t* inoutTypeSpecFlags = NULL) const;
+
+        void dumpToLog() const;
+        
+    private:
+        Theme(const Theme&);
+        Theme& operator=(const Theme&);
+
+        struct theme_entry {
+            ssize_t stringBlock;
+            uint32_t typeSpecFlags;
+            Res_value value;
+        };
+        struct type_info {
+            size_t numEntries;
+            theme_entry* entries;
+        };
+        struct package_info {
+            size_t numTypes;
+            type_info types[];
+        };
+
+        void free_package(package_info* pi);
+        package_info* copy_package(package_info* pi);
+
+        const ResTable& mTable;
+        package_info*   mPackages[Res_MAXPACKAGE];
+    };
+
+    void setParameters(const ResTable_config* params);
+    void getParameters(ResTable_config* params) const;
+
+    // Retrieve an identifier (which can be passed to getResource)
+    // for a given resource name.  The 'name' can be fully qualified
+    // (<package>:<type>.<basename>) or the package or type components
+    // can be dropped if default values are supplied here.
+    //
+    // Returns 0 if no such resource was found, else a valid resource ID.
+    uint32_t identifierForName(const char16_t* name, size_t nameLen,
+                               const char16_t* type = 0, size_t typeLen = 0,
+                               const char16_t* defPackage = 0,
+                               size_t defPackageLen = 0,
+                               uint32_t* outTypeSpecFlags = NULL) const;
+
+    static bool expandResourceRef(const uint16_t* refStr, size_t refLen,
+                                  String16* outPackage,
+                                  String16* outType,
+                                  String16* outName,
+                                  const String16* defType = NULL,
+                                  const String16* defPackage = NULL,
+                                  const char** outErrorMsg = NULL);
+
+    static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue);
+    static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue);
+
+    // Used with stringToValue.
+    class Accessor
+    {
+    public:
+        inline virtual ~Accessor() { }
+
+        virtual uint32_t getCustomResource(const String16& package,
+                                           const String16& type,
+                                           const String16& name) const = 0;
+        virtual uint32_t getCustomResourceWithCreation(const String16& package,
+                                                       const String16& type,
+                                                       const String16& name,
+                                                       const bool createIfNeeded = false) = 0;
+        virtual uint32_t getRemappedPackage(uint32_t origPackage) const = 0;
+        virtual bool getAttributeType(uint32_t attrID, uint32_t* outType) = 0;
+        virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin) = 0;
+        virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax) = 0;
+        virtual bool getAttributeEnum(uint32_t attrID,
+                                      const char16_t* name, size_t nameLen,
+                                      Res_value* outValue) = 0;
+        virtual bool getAttributeFlags(uint32_t attrID,
+                                       const char16_t* name, size_t nameLen,
+                                       Res_value* outValue) = 0;
+        virtual uint32_t getAttributeL10N(uint32_t attrID) = 0;
+        virtual bool getLocalizationSetting() = 0;
+        virtual void reportError(void* accessorCookie, const char* fmt, ...) = 0;
+    };
+
+    // Convert a string to a resource value.  Handles standard "@res",
+    // "#color", "123", and "0x1bd" types; performs escaping of strings.
+    // The resulting value is placed in 'outValue'; if it is a string type,
+    // 'outString' receives the string.  If 'attrID' is supplied, the value is
+    // type checked against this attribute and it is used to perform enum
+    // evaluation.  If 'acccessor' is supplied, it will be used to attempt to
+    // resolve resources that do not exist in this ResTable.  If 'attrType' is
+    // supplied, the value will be type checked for this format if 'attrID'
+    // is not supplied or found.
+    bool stringToValue(Res_value* outValue, String16* outString,
+                       const char16_t* s, size_t len,
+                       bool preserveSpaces, bool coerceType,
+                       uint32_t attrID = 0,
+                       const String16* defType = NULL,
+                       const String16* defPackage = NULL,
+                       Accessor* accessor = NULL,
+                       void* accessorCookie = NULL,
+                       uint32_t attrType = ResTable_map::TYPE_ANY,
+                       bool enforcePrivate = true) const;
+
+    // Perform processing of escapes and quotes in a string.
+    static bool collectString(String16* outString,
+                              const char16_t* s, size_t len,
+                              bool preserveSpaces,
+                              const char** outErrorMsg = NULL,
+                              bool append = false);
+
+    size_t getBasePackageCount() const;
+    const char16_t* getBasePackageName(size_t idx) const;
+    uint32_t getBasePackageId(size_t idx) const;
+
+    size_t getTableCount() const;
+    const ResStringPool* getTableStringBlock(size_t index) const;
+    void* getTableCookie(size_t index) const;
+
+    // Return the configurations (ResTable_config) that we know about
+    void getConfigurations(Vector<ResTable_config>* configs) const;
+
+    void getLocales(Vector<String8>* locales) const;
+
+#ifndef HAVE_ANDROID_OS
+    void print() const;
+#endif
+
+private:
+    struct Header;
+    struct Type;
+    struct Package;
+    struct PackageGroup;
+    struct bag_set;
+
+    status_t add(const void* data, size_t size, void* cookie,
+                 Asset* asset, bool copyData);
+
+    ssize_t getResourcePackageIndex(uint32_t resID) const;
+    ssize_t getEntry(
+        const Package* package, int typeIndex, int entryIndex,
+        const ResTable_config* config,
+        const ResTable_type** outType, const ResTable_entry** outEntry,
+        const Type** outTypeClass) const;
+    status_t parsePackage(
+        const ResTable_package* const pkg, const Header* const header);
+
+    mutable Mutex               mLock;
+
+    status_t                    mError;
+
+    ResTable_config             mParams;
+
+    // Array of all resource tables.
+    Vector<Header*>             mHeaders;
+
+    // Array of packages in all resource tables.
+    Vector<PackageGroup*>       mPackageGroups;
+
+    // Mapping from resource package IDs to indices into the internal
+    // package array.
+    uint8_t                     mPackageMap[256];
+};
+
+}   // namespace android
+
+#endif // _LIBS_UTILS_RESOURCE_TYPES_H
diff --git a/include/utils/SharedBuffer.h b/include/utils/SharedBuffer.h
new file mode 100644
index 0000000..24508b0
--- /dev/null
+++ b/include/utils/SharedBuffer.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SHARED_BUFFER_H
+#define ANDROID_SHARED_BUFFER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class SharedBuffer
+{
+public:
+
+    /* flags to use with release() */
+    enum {
+        eKeepStorage = 0x00000001
+    };
+
+    /*! allocate a buffer of size 'size' and acquire() it.
+     *  call release() to free it.
+     */
+    static          SharedBuffer*           alloc(size_t size);
+    
+    /*! free the memory associated with the SharedBuffer.
+     * Fails if there are any users associated with this SharedBuffer.
+     * In other words, the buffer must have been release by all its
+     * users.
+     */
+    static          ssize_t                 dealloc(const SharedBuffer* released);
+    
+    //! get the SharedBuffer from the data pointer
+    static  inline  const SharedBuffer*     sharedBuffer(const void* data);
+
+    //! access the data for read
+    inline          const void*             data() const;
+    
+    //! access the data for read/write
+    inline          void*                   data();
+
+    //! get size of the buffer
+    inline          size_t                  size() const;
+ 
+    //! get back a SharedBuffer object from its data
+    static  inline  SharedBuffer*           bufferFromData(void* data);
+    
+    //! get back a SharedBuffer object from its data
+    static  inline  const SharedBuffer*     bufferFromData(const void* data);
+
+    //! get the size of a SharedBuffer object from its data
+    static  inline  size_t                  sizeFromData(const void* data);
+    
+    //! edit the buffer (get a writtable, or non-const, version of it)
+                    SharedBuffer*           edit() const;
+
+    //! edit the buffer, resizing if needed
+                    SharedBuffer*           editResize(size_t size) const;
+
+    //! like edit() but fails if a copy is required
+                    SharedBuffer*           attemptEdit() const;
+    
+    //! resize and edit the buffer, loose it's content.
+                    SharedBuffer*           reset(size_t size) const;
+
+    //! acquire/release a reference on this buffer
+                    void                    acquire() const;
+                    
+    /*! release a reference on this buffer, with the option of not
+     * freeing the memory associated with it if it was the last reference
+     * returns the previous reference count
+     */     
+                    int32_t                 release(uint32_t flags = 0) const;
+    
+    //! returns wether or not we're the only owner
+    inline          bool                    onlyOwner() const;
+    
+
+private:
+        inline SharedBuffer() { }
+        inline ~SharedBuffer() { }
+        inline SharedBuffer(const SharedBuffer&);
+ 
+        // 16 bytes. must be sized to preserve correct alingment.
+        mutable int32_t        mRefs;
+                size_t         mSize;
+                uint32_t       mReserved[2];
+};
+
+// ---------------------------------------------------------------------------
+
+const SharedBuffer* SharedBuffer::sharedBuffer(const void* data) {
+    return data ? reinterpret_cast<const SharedBuffer *>(data)-1 : 0;
+}
+
+const void* SharedBuffer::data() const {
+    return this + 1;
+}
+
+void* SharedBuffer::data() {
+    return this + 1;
+}
+
+size_t SharedBuffer::size() const {
+    return mSize;
+}
+
+SharedBuffer* SharedBuffer::bufferFromData(void* data)
+{
+    return ((SharedBuffer*)data)-1;
+}
+    
+const SharedBuffer* SharedBuffer::bufferFromData(const void* data)
+{
+    return ((const SharedBuffer*)data)-1;
+}
+
+size_t SharedBuffer::sizeFromData(const void* data)
+{
+    return (((const SharedBuffer*)data)-1)->mSize;
+}
+
+bool SharedBuffer::onlyOwner() const {
+    return (mRefs == 1);
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_VECTOR_H
diff --git a/include/utils/Socket.h b/include/utils/Socket.h
new file mode 100644
index 0000000..8b7f406
--- /dev/null
+++ b/include/utils/Socket.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Socket class.  Modeled after Java classes.
+//
+#ifndef _RUNTIME_SOCKET_H
+#define _RUNTIME_SOCKET_H
+
+#include <utils/inet_address.h>
+#include <sys/types.h>
+
+namespace android {
+
+/*
+ * Basic socket class, needed to abstract away the differences between
+ * BSD sockets and WinSock.  This establishes a streaming network
+ * connection (TCP/IP) to somebody.
+ */
+class Socket {
+public:
+    Socket(void);
+    ~Socket(void);
+
+    // Create a connection to somewhere.
+    // Return 0 on success.
+    int connect(const char* host, int port);
+    int connect(const InetAddress* addr, int port);
+
+
+    // Close the socket.  Don't try to use this object again after
+    // calling this.  Returns false on failure.
+    bool close(void);
+
+    // If we created the socket without an address, we can use these
+    // to finish the connection.  Returns 0 on success.
+    int bind(const SocketAddress& bindPoint);
+    int connect(const SocketAddress& endPoint);
+
+    // Here we deviate from the traditional object-oriented fanciness
+    // and just provide read/write operators instead of getters for
+    // objects that abstract a stream.
+    //
+    // Standard read/write semantics.
+    int read(void* buf, ssize_t len) const;
+    int write(const void* buf, ssize_t len) const;
+
+    // This must be called once, at program startup.
+    static bool bootInit(void);
+    static void finalShutdown(void);
+
+private:
+    // Internal function that establishes a connection.
+    int doConnect(const InetSocketAddress& addr);
+
+    unsigned long   mSock;      // holds SOCKET or int
+
+    static bool     mBootInitialized;
+};
+
+
+// debug -- unit tests
+void TestSockets(void);
+
+}; // namespace android
+
+#endif // _RUNTIME_SOCKET_H
diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h
new file mode 100644
index 0000000..c8a6153
--- /dev/null
+++ b/include/utils/SortedVector.h
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SORTED_VECTOR_H
+#define ANDROID_SORTED_VECTOR_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Vector.h>
+#include <utils/VectorImpl.h>
+#include <utils/TypeHelpers.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+template <class TYPE>
+class SortedVector : private SortedVectorImpl
+{
+public:
+            typedef TYPE    value_type;
+    
+    /*! 
+     * Constructors and destructors
+     */
+    
+                            SortedVector();
+                            SortedVector(const SortedVector<TYPE>& rhs);
+    virtual                 ~SortedVector();
+
+    /*! copy operator */
+    const SortedVector<TYPE>&   operator = (const SortedVector<TYPE>& rhs) const;    
+    SortedVector<TYPE>&         operator = (const SortedVector<TYPE>& rhs);    
+
+    /*
+     * empty the vector
+     */
+
+    inline  void            clear()             { VectorImpl::clear(); }
+
+    /*! 
+     * vector stats
+     */
+
+    //! returns number of items in the vector
+    inline  size_t          size() const                { return VectorImpl::size(); }
+    //! returns wether or not the vector is empty
+    inline  bool            isEmpty() const             { return VectorImpl::isEmpty(); }
+    //! returns how many items can be stored without reallocating the backing store
+    inline  size_t          capacity() const            { return VectorImpl::capacity(); }
+    //! setst the capacity. capacity can never be reduced less than size()
+    inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }
+
+    /*! 
+     * C-style array access
+     */
+     
+    //! read-only C-style access 
+    inline  const TYPE*     array() const;
+
+    //! read-write C-style access. BE VERY CAREFUL when modifying the array
+    //! you ust keep it sorted! You usually don't use this function.
+            TYPE*           editArray();
+
+            //! finds the index of an item
+            ssize_t         indexOf(const TYPE& item) const;
+            
+            //! finds where this item should be inserted
+            size_t          orderOf(const TYPE& item) const;
+            
+    
+    /*! 
+     * accessors
+     */
+
+    //! read-only access to an item at a given index
+    inline  const TYPE&     operator [] (size_t index) const;
+    //! alternate name for operator []
+    inline  const TYPE&     itemAt(size_t index) const;
+    //! stack-usage of the vector. returns the top of the stack (last element)
+            const TYPE&     top() const;
+    //! same as operator [], but allows to access the vector backward (from the end) with a negative index
+            const TYPE&     mirrorItemAt(ssize_t index) const;
+
+    /*!
+     * modifing the array
+     */
+
+            //! add an item in the right place (and replace the one that is there)
+            ssize_t         add(const TYPE& item);
+            
+            //! editItemAt() MUST NOT change the order of this item
+            TYPE&           editItemAt(size_t index) {
+                return *( static_cast<TYPE *>(VectorImpl::editItemLocation(index)) );
+            }
+
+            //! merges a vector into this one
+            ssize_t         merge(const Vector<TYPE>& vector);
+            ssize_t         merge(const SortedVector<TYPE>& vector);
+            
+            //! removes an item
+            ssize_t         remove(const TYPE&);
+
+    //! remove several items
+    inline  ssize_t         removeItemsAt(size_t index, size_t count = 1);
+    //! remove one item
+    inline  ssize_t         removeAt(size_t index)  { return removeItemsAt(index); }
+            
+protected:
+    virtual void    do_construct(void* storage, size_t num) const;
+    virtual void    do_destroy(void* storage, size_t num) const;
+    virtual void    do_copy(void* dest, const void* from, size_t num) const;
+    virtual void    do_splat(void* dest, const void* item, size_t num) const;
+    virtual void    do_move_forward(void* dest, const void* from, size_t num) const;
+    virtual void    do_move_backward(void* dest, const void* from, size_t num) const;
+    virtual int     do_compare(const void* lhs, const void* rhs) const;
+};
+
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts from here...
+// ---------------------------------------------------------------------------
+
+template<class TYPE> inline
+SortedVector<TYPE>::SortedVector()
+    : SortedVectorImpl(sizeof(TYPE),
+                ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)
+                |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)
+                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0)
+                |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
+                )
+{
+}
+
+template<class TYPE> inline
+SortedVector<TYPE>::SortedVector(const SortedVector<TYPE>& rhs)
+    : SortedVectorImpl(rhs) {
+}
+
+template<class TYPE> inline
+SortedVector<TYPE>::~SortedVector() {
+    finish_vector();
+}
+
+template<class TYPE> inline
+SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
+    SortedVectorImpl::operator = (rhs);
+    return *this; 
+}
+
+template<class TYPE> inline
+const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
+    SortedVectorImpl::operator = (rhs);
+    return *this; 
+}
+
+template<class TYPE> inline
+const TYPE* SortedVector<TYPE>::array() const {
+    return static_cast<const TYPE *>(arrayImpl());
+}
+
+template<class TYPE> inline
+TYPE* SortedVector<TYPE>::editArray() {
+    return static_cast<TYPE *>(editArrayImpl());
+}
+
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::operator[](size_t index) const {
+    assert( index<size() );
+    return *(array() + index);
+}
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::itemAt(size_t index) const {
+    return operator[](index);
+}
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::mirrorItemAt(ssize_t index) const {
+    assert( (index>0 ? index : -index)<size() );
+    return *(array() + ((index<0) ? (size()-index) : index));
+}
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::top() const {
+    return *(array() + size() - 1);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::add(const TYPE& item) {
+    return SortedVectorImpl::add(&item);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::indexOf(const TYPE& item) const {
+    return SortedVectorImpl::indexOf(&item);
+}
+
+template<class TYPE> inline
+size_t SortedVector<TYPE>::orderOf(const TYPE& item) const {
+    return SortedVectorImpl::orderOf(&item);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::merge(const Vector<TYPE>& vector) {
+    return SortedVectorImpl::merge(reinterpret_cast<const VectorImpl&>(vector));
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::merge(const SortedVector<TYPE>& vector) {
+    return SortedVectorImpl::merge(reinterpret_cast<const SortedVectorImpl&>(vector));
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::remove(const TYPE& item) {
+    return SortedVectorImpl::remove(&item);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::removeItemsAt(size_t index, size_t count) {
+    return VectorImpl::removeItemsAt(index, count);
+}
+
+// ---------------------------------------------------------------------------
+
+template<class TYPE>
+void SortedVector<TYPE>::do_construct(void* storage, size_t num) const {
+    construct_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_destroy(void* storage, size_t num) const {
+    destroy_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
+    copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
+    splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
+    move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
+    move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+int SortedVector<TYPE>::do_compare(const void* lhs, const void* rhs) const {
+    return compare_type( *reinterpret_cast<const TYPE*>(lhs), *reinterpret_cast<const TYPE*>(rhs) );
+}
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_SORTED_VECTOR_H
diff --git a/include/utils/StopWatch.h b/include/utils/StopWatch.h
new file mode 100644
index 0000000..cc0bebc
--- /dev/null
+++ b/include/utils/StopWatch.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_STOPWATCH_H
+#define ANDROID_STOPWATCH_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Timers.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class StopWatch
+{
+public:
+        StopWatch(  const char *name,
+                    int clock = SYSTEM_TIME_MONOTONIC,
+                    uint32_t flags = 0);
+        ~StopWatch();
+        
+        const char* name() const;
+        nsecs_t     lap();
+        nsecs_t     elapsedTime() const;
+        
+private:
+    const char*     mName;
+    int             mClock;
+    uint32_t        mFlags;
+    
+    struct lap_t {
+        nsecs_t     soFar;
+        nsecs_t     thisLap;
+    };
+    
+    nsecs_t         mStartTime;
+    lap_t           mLaps[8];
+    int             mNumLaps;
+};
+
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_STOPWATCH_H
diff --git a/include/utils/String16.h b/include/utils/String16.h
new file mode 100644
index 0000000..a2d22ee
--- /dev/null
+++ b/include/utils/String16.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_STRING16_H
+#define ANDROID_STRING16_H
+
+#include <utils/Errors.h>
+#include <utils/SharedBuffer.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+extern "C" {
+
+typedef uint16_t char16_t;
+
+// Standard string functions on char16 strings.
+int strcmp16(const char16_t *, const char16_t *);
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
+size_t strlen16(const char16_t *);
+size_t strnlen16(const char16_t *, size_t);
+char16_t *strcpy16(char16_t *, const char16_t *);
+char16_t *strncpy16(char16_t *, const char16_t *, size_t);
+
+// Version of comparison that supports embedded nulls.
+// This is different than strncmp() because we don't stop
+// at a nul character and consider the strings to be different
+// if the lengths are different (thus we need to supply the
+// lengths of both strings).  This can also be used when
+// your string is not nul-terminated as it will have the
+// equivalent result as strcmp16 (unlike strncmp16).
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2);
+
+// Version of strzcmp16 for comparing strings in different endianness.
+int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
+
+}
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class String8;
+class TextOutput;
+
+//! This is a string holding UTF-16 characters.
+class String16
+{
+public:
+                                String16();
+                                String16(const String16& o);
+                                String16(const String16& o,
+                                         size_t len,
+                                         size_t begin=0);
+    explicit                    String16(const char16_t* o);
+    explicit                    String16(const char16_t* o, size_t len);
+    explicit                    String16(const String8& o);
+    explicit                    String16(const char* o);
+    explicit                    String16(const char* o, size_t len);
+
+                                ~String16();
+    
+    inline  const char16_t*     string() const;
+    inline  size_t              size() const;
+    
+    inline  const SharedBuffer* sharedBuffer() const;
+    
+            void                setTo(const String16& other);
+            status_t            setTo(const char16_t* other);
+            status_t            setTo(const char16_t* other, size_t len);
+            status_t            setTo(const String16& other,
+                                      size_t len,
+                                      size_t begin=0);
+    
+            status_t            append(const String16& other);
+            status_t            append(const char16_t* other, size_t len);
+            
+    inline  String16&           operator=(const String16& other);
+    
+    inline  String16&           operator+=(const String16& other);
+    inline  String16            operator+(const String16& other) const;
+
+            status_t            insert(size_t pos, const char16_t* chrs);
+            status_t            insert(size_t pos,
+                                       const char16_t* chrs, size_t len);
+
+            ssize_t             findFirst(char16_t c) const;
+            ssize_t             findLast(char16_t c) const;
+
+            bool                startsWith(const String16& prefix) const;
+            bool                startsWith(const char16_t* prefix) const;
+            
+            status_t            makeLower();
+
+            status_t            replaceAll(char16_t replaceThis,
+                                           char16_t withThis);
+
+            status_t            remove(size_t len, size_t begin=0);
+
+    inline  int                 compare(const String16& other) const;
+
+    inline  bool                operator<(const String16& other) const;
+    inline  bool                operator<=(const String16& other) const;
+    inline  bool                operator==(const String16& other) const;
+    inline  bool                operator!=(const String16& other) const;
+    inline  bool                operator>=(const String16& other) const;
+    inline  bool                operator>(const String16& other) const;
+    
+    inline  bool                operator<(const char16_t* other) const;
+    inline  bool                operator<=(const char16_t* other) const;
+    inline  bool                operator==(const char16_t* other) const;
+    inline  bool                operator!=(const char16_t* other) const;
+    inline  bool                operator>=(const char16_t* other) const;
+    inline  bool                operator>(const char16_t* other) const;
+    
+    inline                      operator const char16_t*() const;
+    
+private:
+            const char16_t*     mString;
+};
+
+TextOutput& operator<<(TextOutput& to, const String16& val);
+
+// ---------------------------------------------------------------------------
+// No user servicable parts below.
+
+inline int compare_type(const String16& lhs, const String16& rhs)
+{
+    return lhs.compare(rhs);
+}
+
+inline int strictly_order_type(const String16& lhs, const String16& rhs)
+{
+    return compare_type(lhs, rhs) < 0;
+}
+
+inline const char16_t* String16::string() const
+{
+    return mString;
+}
+
+inline size_t String16::size() const
+{
+    return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1;
+}
+
+inline const SharedBuffer* String16::sharedBuffer() const
+{
+    return SharedBuffer::bufferFromData(mString);
+}
+
+inline String16& String16::operator=(const String16& other)
+{
+    setTo(other);
+    return *this;
+}
+
+inline String16& String16::operator+=(const String16& other)
+{
+    append(other);
+    return *this;
+}
+
+inline String16 String16::operator+(const String16& other) const
+{
+    String16 tmp;
+    tmp += other;
+    return tmp;
+}
+
+inline int String16::compare(const String16& other) const
+{
+    return strzcmp16(mString, size(), other.mString, other.size());
+}
+
+inline bool String16::operator<(const String16& other) const
+{
+    return strzcmp16(mString, size(), other.mString, other.size()) < 0;
+}
+
+inline bool String16::operator<=(const String16& other) const
+{
+    return strzcmp16(mString, size(), other.mString, other.size()) <= 0;
+}
+
+inline bool String16::operator==(const String16& other) const
+{
+    return strzcmp16(mString, size(), other.mString, other.size()) == 0;
+}
+
+inline bool String16::operator!=(const String16& other) const
+{
+    return strzcmp16(mString, size(), other.mString, other.size()) != 0;
+}
+
+inline bool String16::operator>=(const String16& other) const
+{
+    return strzcmp16(mString, size(), other.mString, other.size()) >= 0;
+}
+
+inline bool String16::operator>(const String16& other) const
+{
+    return strzcmp16(mString, size(), other.mString, other.size()) > 0;
+}
+
+inline bool String16::operator<(const char16_t* other) const
+{
+    return strcmp16(mString, other) < 0;
+}
+
+inline bool String16::operator<=(const char16_t* other) const
+{
+    return strcmp16(mString, other) <= 0;
+}
+
+inline bool String16::operator==(const char16_t* other) const
+{
+    return strcmp16(mString, other) == 0;
+}
+
+inline bool String16::operator!=(const char16_t* other) const
+{
+    return strcmp16(mString, other) != 0;
+}
+
+inline bool String16::operator>=(const char16_t* other) const
+{
+    return strcmp16(mString, other) >= 0;
+}
+
+inline bool String16::operator>(const char16_t* other) const
+{
+    return strcmp16(mString, other) > 0;
+}
+
+inline String16::operator const char16_t*() const
+{
+    return mString;
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_STRING16_H
diff --git a/include/utils/String8.h b/include/utils/String8.h
new file mode 100644
index 0000000..c49faf6
--- /dev/null
+++ b/include/utils/String8.h
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_STRING8_H
+#define ANDROID_STRING8_H
+
+#include <utils/Errors.h>
+
+// Need this for the char16_t type; String8.h should not
+// be depedent on the String16 class.
+#include <utils/String16.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class TextOutput;
+
+//! This is a string holding UTF-8 characters.
+class String8
+{
+public:
+                                String8();
+                                String8(const String8& o);
+    explicit                    String8(const char* o);
+    explicit                    String8(const char* o, size_t numChars);
+    
+    explicit                    String8(const String16& o);
+    explicit                    String8(const char16_t* o);
+    explicit                    String8(const char16_t* o, size_t numChars);
+    
+                                ~String8();
+    
+    inline  const char*         string() const;
+    inline  size_t              size() const;
+    inline  size_t              length() const;
+    inline  size_t              bytes() const;
+    
+    inline  const SharedBuffer* sharedBuffer() const;
+    
+            void                setTo(const String8& other);
+            status_t            setTo(const char* other);
+            status_t            setTo(const char* other, size_t numChars);
+            status_t            setTo(const char16_t* other, size_t numChars);
+    
+            status_t            append(const String8& other);
+            status_t            append(const char* other);
+            status_t            append(const char* other, size_t numChars);
+
+    inline  String8&            operator=(const String8& other);
+    inline  String8&            operator=(const char* other);
+    
+    inline  String8&            operator+=(const String8& other);
+    inline  String8             operator+(const String8& other) const;
+    
+    inline  String8&            operator+=(const char* other);
+    inline  String8             operator+(const char* other) const;
+
+    inline  int                 compare(const String8& other) const;
+
+    inline  bool                operator<(const String8& other) const;
+    inline  bool                operator<=(const String8& other) const;
+    inline  bool                operator==(const String8& other) const;
+    inline  bool                operator!=(const String8& other) const;
+    inline  bool                operator>=(const String8& other) const;
+    inline  bool                operator>(const String8& other) const;
+    
+    inline  bool                operator<(const char* other) const;
+    inline  bool                operator<=(const char* other) const;
+    inline  bool                operator==(const char* other) const;
+    inline  bool                operator!=(const char* other) const;
+    inline  bool                operator>=(const char* other) const;
+    inline  bool                operator>(const char* other) const;
+    
+    inline                      operator const char*() const;
+    
+            char*               lockBuffer(size_t size);
+            void                unlockBuffer();
+            status_t            unlockBuffer(size_t size);
+            
+            // return the index of the first byte of other in this at or after
+            // start, or -1 if not found
+            ssize_t             find(const char* other, size_t start = 0) const;
+
+            void                toLower();
+            void                toLower(size_t start, size_t numChars);
+            void                toUpper();
+            void                toUpper(size_t start, size_t numChars);
+            
+    /*
+     * These methods operate on the string as if it were a path name.
+     */
+
+    /*
+     * Set the filename field to a specific value.
+     *
+     * Normalizes the filename, removing a trailing '/' if present.
+     */
+    void setPathName(const char* name);
+    void setPathName(const char* name, size_t numChars);
+
+    /*
+     * Get just the filename component.
+     *
+     * "/tmp/foo/bar.c" --> "bar.c"
+     */
+    String8 getPathLeaf(void) const;
+
+    /*
+     * Remove the last (file name) component, leaving just the directory
+     * name.
+     *
+     * "/tmp/foo/bar.c" --> "/tmp/foo"
+     * "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX
+     * "bar.c" --> ""
+     */
+    String8 getPathDir(void) const;
+
+    /*
+     * Retrieve the front (root dir) component.  Optionally also return the
+     * remaining components.
+     *
+     * "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c")
+     * "/tmp" --> "tmp" (remain = "")
+     * "bar.c" --> "bar.c" (remain = "")
+     */
+    String8 walkPath(String8* outRemains = NULL) const;
+
+    /*
+     * Return the filename extension.  This is the last '.' and up to
+     * four characters that follow it.  The '.' is included in case we
+     * decide to expand our definition of what constitutes an extension.
+     *
+     * "/tmp/foo/bar.c" --> ".c"
+     * "/tmp" --> ""
+     * "/tmp/foo.bar/baz" --> ""
+     * "foo.jpeg" --> ".jpeg"
+     * "foo." --> ""
+     */
+    String8 getPathExtension(void) const;
+
+    /*
+     * Return the path without the extension.  Rules for what constitutes
+     * an extension are described in the comment for getPathExtension().
+     *
+     * "/tmp/foo/bar.c" --> "/tmp/foo/bar"
+     */
+    String8 getBasePath(void) const;
+
+    /*
+     * Add a component to the pathname.  We guarantee that there is
+     * exactly one path separator between the old path and the new.
+     * If there is no existing name, we just copy the new name in.
+     *
+     * If leaf is a fully qualified path (i.e. starts with '/', it
+     * replaces whatever was there before.
+     */
+    String8& appendPath(const char* leaf);
+    String8& appendPath(const String8& leaf)  { return appendPath(leaf.string()); }
+
+    /*
+     * Like appendPath(), but does not affect this string.  Returns a new one instead.
+     */
+    String8 appendPathCopy(const char* leaf) const
+                                             { String8 p(*this); p.appendPath(leaf); return p; }
+    String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); }
+
+    /*
+     * Converts all separators in this string to /, the default path separator.
+     *
+     * If the default OS separator is backslash, this converts all
+     * backslashes to slashes, in-place. Otherwise it does nothing.
+     * Returns self.
+     */
+    String8& convertToResPath();
+
+private:
+            status_t            real_append(const char* other, size_t numChars);
+            char*               find_extension(void) const;
+
+            const char* mString;
+};
+
+TextOutput& operator<<(TextOutput& to, const String16& val);
+
+// ---------------------------------------------------------------------------
+// No user servicable parts below.
+
+inline int compare_type(const String8& lhs, const String8& rhs)
+{
+    return lhs.compare(rhs);
+}
+
+inline int strictly_order_type(const String8& lhs, const String8& rhs)
+{
+    return compare_type(lhs, rhs) < 0;
+}
+
+inline const char* String8::string() const
+{
+    return mString;
+}
+
+inline size_t String8::length() const
+{
+    return SharedBuffer::sizeFromData(mString)-1;
+}
+
+inline size_t String8::size() const
+{
+    return length();
+}
+
+inline size_t String8::bytes() const
+{
+    return SharedBuffer::sizeFromData(mString)-1;
+}
+
+inline const SharedBuffer* String8::sharedBuffer() const
+{
+    return SharedBuffer::bufferFromData(mString);
+}
+
+inline String8& String8::operator=(const String8& other)
+{
+    setTo(other);
+    return *this;
+}
+
+inline String8& String8::operator=(const char* other)
+{
+    setTo(other);
+    return *this;
+}
+
+inline String8& String8::operator+=(const String8& other)
+{
+    append(other);
+    return *this;
+}
+
+inline String8 String8::operator+(const String8& other) const
+{
+    String8 tmp;
+    tmp += other;
+    return tmp;
+}
+
+inline String8& String8::operator+=(const char* other)
+{
+    append(other);
+    return *this;
+}
+
+inline String8 String8::operator+(const char* other) const
+{
+    String8 tmp;
+    tmp += other;
+    return tmp;
+}
+
+inline int String8::compare(const String8& other) const
+{
+    return strcmp(mString, other.mString);
+}
+
+inline bool String8::operator<(const String8& other) const
+{
+    return strcmp(mString, other.mString) < 0;
+}
+
+inline bool String8::operator<=(const String8& other) const
+{
+    return strcmp(mString, other.mString) <= 0;
+}
+
+inline bool String8::operator==(const String8& other) const
+{
+    return strcmp(mString, other.mString) == 0;
+}
+
+inline bool String8::operator!=(const String8& other) const
+{
+    return strcmp(mString, other.mString) != 0;
+}
+
+inline bool String8::operator>=(const String8& other) const
+{
+    return strcmp(mString, other.mString) >= 0;
+}
+
+inline bool String8::operator>(const String8& other) const
+{
+    return strcmp(mString, other.mString) > 0;
+}
+
+inline bool String8::operator<(const char* other) const
+{
+    return strcmp(mString, other) < 0;
+}
+
+inline bool String8::operator<=(const char* other) const
+{
+    return strcmp(mString, other) <= 0;
+}
+
+inline bool String8::operator==(const char* other) const
+{
+    return strcmp(mString, other) == 0;
+}
+
+inline bool String8::operator!=(const char* other) const
+{
+    return strcmp(mString, other) != 0;
+}
+
+inline bool String8::operator>=(const char* other) const
+{
+    return strcmp(mString, other) >= 0;
+}
+
+inline bool String8::operator>(const char* other) const
+{
+    return strcmp(mString, other) > 0;
+}
+
+inline String8::operator const char*() const
+{
+    return mString;
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_STRING8_H
diff --git a/include/utils/SystemClock.h b/include/utils/SystemClock.h
new file mode 100644
index 0000000..7c319be
--- /dev/null
+++ b/include/utils/SystemClock.h
@@ -0,0 +1,32 @@
+/*
+ * 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_UTILS_SYSTEMCLOCK_H
+#define ANDROID_UTILS_SYSTEMCLOCK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace android {
+
+int setCurrentTimeMillis(int64_t millis);
+int64_t uptimeMillis();
+int64_t elapsedRealtime();
+
+}; // namespace android
+
+#endif // ANDROID_UTILS_SYSTEMCLOCK_H
+
diff --git a/include/utils/TextOutput.h b/include/utils/TextOutput.h
new file mode 100644
index 0000000..d8d86ba
--- /dev/null
+++ b/include/utils/TextOutput.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_TEXTOUTPUT_H
+#define ANDROID_TEXTOUTPUT_H
+
+#include <utils/Errors.h>
+
+#include <stdint.h>
+#include <string.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class TextOutput
+{
+public:
+                        TextOutput() { }
+    virtual             ~TextOutput() { }
+    
+    virtual status_t    print(const char* txt, size_t len) = 0;
+    virtual void        moveIndent(int delta) = 0;
+    
+    class Bundle {
+    public:
+        inline Bundle(TextOutput& to) : mTO(to) { to.pushBundle(); }
+        inline ~Bundle() { mTO.popBundle(); }
+    private:
+        TextOutput&     mTO;
+    };
+    
+    virtual void        pushBundle() = 0;
+    virtual void        popBundle() = 0;
+};
+
+// ---------------------------------------------------------------------------
+
+// Text output stream for printing to the log (via utils/Log.h).
+extern TextOutput& alog;
+
+// Text output stream for printing to stdout.
+extern TextOutput& aout;
+
+// Text output stream for printing to stderr.
+extern TextOutput& aerr;
+
+typedef TextOutput& (*TextOutputManipFunc)(TextOutput&);
+
+TextOutput& endl(TextOutput& to);
+TextOutput& indent(TextOutput& to);
+TextOutput& dedent(TextOutput& to);
+
+TextOutput& operator<<(TextOutput& to, const char* str);
+TextOutput& operator<<(TextOutput& to, char);     // writes raw character
+TextOutput& operator<<(TextOutput& to, bool);
+TextOutput& operator<<(TextOutput& to, int);
+TextOutput& operator<<(TextOutput& to, long);
+TextOutput& operator<<(TextOutput& to, unsigned int);
+TextOutput& operator<<(TextOutput& to, unsigned long);
+TextOutput& operator<<(TextOutput& to, long long);
+TextOutput& operator<<(TextOutput& to, unsigned long long);
+TextOutput& operator<<(TextOutput& to, float);
+TextOutput& operator<<(TextOutput& to, double);
+TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func);
+TextOutput& operator<<(TextOutput& to, const void*);
+
+class TypeCode 
+{
+public:
+    inline TypeCode(uint32_t code);
+    inline ~TypeCode();
+
+    inline uint32_t typeCode() const;
+    
+private:
+    uint32_t mCode;
+};
+
+TextOutput& operator<<(TextOutput& to, const TypeCode& val);
+
+class HexDump
+{
+public:
+    HexDump(const void *buf, size_t size, size_t bytesPerLine=16);
+    inline ~HexDump();
+    
+    inline HexDump& setBytesPerLine(size_t bytesPerLine);
+    inline HexDump& setSingleLineCutoff(int32_t bytes);
+    inline HexDump& setAlignment(size_t alignment);
+    inline HexDump& setCArrayStyle(bool enabled);
+    
+    inline const void* buffer() const;
+    inline size_t size() const;
+    inline size_t bytesPerLine() const;
+    inline int32_t singleLineCutoff() const;
+    inline size_t alignment() const;
+    inline bool carrayStyle() const;
+
+private:
+    const void* mBuffer;
+    size_t mSize;
+    size_t mBytesPerLine;
+    int32_t mSingleLineCutoff;
+    size_t mAlignment;
+    bool mCArrayStyle;
+};
+
+TextOutput& operator<<(TextOutput& to, const HexDump& val);
+
+// ---------------------------------------------------------------------------
+// No user servicable parts below.
+
+inline TextOutput& endl(TextOutput& to)
+{
+    to.print("\n", 1);
+    return to;
+}
+
+inline TextOutput& indent(TextOutput& to)
+{
+    to.moveIndent(1);
+    return to;
+}
+
+inline TextOutput& dedent(TextOutput& to)
+{
+    to.moveIndent(-1);
+    return to;
+}
+
+inline TextOutput& operator<<(TextOutput& to, const char* str)
+{
+    to.print(str, strlen(str));
+    return to;
+}
+
+inline TextOutput& operator<<(TextOutput& to, char c)
+{
+    to.print(&c, 1);
+    return to;
+}
+
+inline TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func)
+{
+    return (*func)(to);
+}
+
+inline TypeCode::TypeCode(uint32_t code) : mCode(code) { }
+inline TypeCode::~TypeCode() { }
+inline uint32_t TypeCode::typeCode() const { return mCode; }
+
+inline HexDump::~HexDump() { }
+
+inline HexDump& HexDump::setBytesPerLine(size_t bytesPerLine) {
+    mBytesPerLine = bytesPerLine; return *this;
+}
+inline HexDump& HexDump::setSingleLineCutoff(int32_t bytes) {
+    mSingleLineCutoff = bytes; return *this;
+}
+inline HexDump& HexDump::setAlignment(size_t alignment) {
+    mAlignment = alignment; return *this;
+}
+inline HexDump& HexDump::setCArrayStyle(bool enabled) {
+    mCArrayStyle = enabled; return *this;
+}
+
+inline const void* HexDump::buffer() const { return mBuffer; }
+inline size_t HexDump::size() const { return mSize; }
+inline size_t HexDump::bytesPerLine() const { return mBytesPerLine; }
+inline int32_t HexDump::singleLineCutoff() const { return mSingleLineCutoff; }
+inline size_t HexDump::alignment() const { return mAlignment; }
+inline bool HexDump::carrayStyle() const { return mCArrayStyle; }
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_TEXTOUTPUT_H
diff --git a/include/utils/TimeUtils.h b/include/utils/TimeUtils.h
new file mode 100644
index 0000000..30e5330
--- /dev/null
+++ b/include/utils/TimeUtils.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_TIME_H
+#define ANDROID_TIME_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+namespace android {
+
+/*
+ * This class is the core implementation of the android.util.Time java
+ * class.  It doesn't implement some of the methods that are implemented
+ * in Java.  They could be done here, but it's not expected that this class
+ * will be used.  If that assumption is incorrect, feel free to update this
+ * file.  The reason to do it here is to not mix the implementation of this
+ * class and the jni glue code.
+ */
+class Time
+{
+public:
+    struct tm t;
+
+    // this object doesn't own this string
+    const char *timezone;
+
+    enum {
+        SEC = 1,
+        MIN = 2,
+        HOUR = 3,
+        MDAY = 4,
+        MON = 5,
+        YEAR = 6,
+        WDAY = 7,
+        YDAY = 8
+    };
+
+    static int compare(Time& a, Time& b);
+
+    Time();
+
+    void switchTimezone(const char *timezone);
+    String8 format(const char *format) const;
+    void format2445(short* buf, bool hasTime) const;
+    String8 toString() const;
+    void setToNow();
+    int64_t toMillis(bool ignoreDst);
+    void set(int64_t millis);
+
+    inline void set(int sec, int min, int hour, int mday, int mon, int year,
+            int isdst)
+    {
+        this->t.tm_sec = sec;
+        this->t.tm_min = min;
+        this->t.tm_hour = hour;
+        this->t.tm_mday = mday;
+        this->t.tm_mon = mon;
+        this->t.tm_year = year;
+        this->t.tm_isdst = isdst;
+#ifdef HAVE_TM_GMTOFF
+        this->t.tm_gmtoff = 0;
+#endif
+        this->t.tm_wday = 0;
+        this->t.tm_yday = 0;
+    }
+};
+
+}; // namespace android
+
+#endif // ANDROID_TIME_H
diff --git a/include/utils/TimerProbe.h b/include/utils/TimerProbe.h
new file mode 100644
index 0000000..f2e32b2
--- /dev/null
+++ b/include/utils/TimerProbe.h
@@ -0,0 +1,72 @@
+/*
+ * 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_TIMER_PROBE_H
+#define ANDROID_TIMER_PROBE_H
+
+#if 0 && defined(HAVE_POSIX_CLOCKS)
+#define ENABLE_TIMER_PROBE 1
+#else
+#define ENABLE_TIMER_PROBE 0
+#endif
+
+#if ENABLE_TIMER_PROBE
+
+#include <time.h>
+#include <sys/time.h>
+#include <utils/Vector.h>
+
+#define TIMER_PROBE(tag) \
+    static int _timer_slot_; \
+    android::TimerProbe probe(tag, &_timer_slot_)
+#define TIMER_PROBE_END() probe.end()
+#else
+#define TIMER_PROBE(tag)
+#define TIMER_PROBE_END()
+#endif
+
+#if ENABLE_TIMER_PROBE
+namespace android {
+
+class TimerProbe {
+public:
+    TimerProbe(const char tag[], int* slot);
+    void end();
+    ~TimerProbe();
+private:
+    struct Bucket {
+        int mStart, mReal, mProcess, mThread, mCount;
+        const char* mTag;
+        int* mSlotPtr;
+        int mIndent;
+    };
+    static Vector<Bucket> gBuckets;
+    static TimerProbe* gExecuteChain;
+    static int gIndent;
+    static timespec gRealBase;
+    TimerProbe* mNext;
+    static uint32_t ElapsedTime(const timespec& start, const timespec& end);
+    void print(const timespec& r, const timespec& p, const timespec& t) const;
+    timespec mRealStart, mPStart, mTStart;
+    const char* mTag;
+    int mIndent;
+    int mBucket;
+};
+
+}; // namespace android
+
+#endif
+#endif
diff --git a/include/utils/Timers.h b/include/utils/Timers.h
new file mode 100644
index 0000000..9610399
--- /dev/null
+++ b/include/utils/Timers.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Timer functions.
+//
+#ifndef _LIBS_UTILS_TIMERS_H
+#define _LIBS_UTILS_TIMERS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+// ------------------------------------------------------------------
+// C API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int64_t nsecs_t;       // nano-seconds
+
+static inline nsecs_t seconds_to_nanoseconds(nsecs_t secs)
+{
+    return secs*1000000000;
+}
+
+static inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs)
+{
+    return secs*1000000;
+}
+
+static inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs)
+{
+    return secs*1000;
+}
+
+static inline nsecs_t nanoseconds_to_seconds(nsecs_t secs)
+{
+    return secs/1000000000;
+}
+
+static inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs)
+{
+    return secs/1000000;
+}
+
+static inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs)
+{
+    return secs/1000;
+}
+
+static inline nsecs_t s2ns(nsecs_t v)  {return seconds_to_nanoseconds(v);}
+static inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);}
+static inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);}
+static inline nsecs_t ns2s(nsecs_t v)  {return nanoseconds_to_seconds(v);}
+static inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);}
+static inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);}
+
+static inline nsecs_t seconds(nsecs_t v)      { return s2ns(v); }
+static inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); }
+static inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); }
+
+enum {
+    SYSTEM_TIME_REALTIME = 0,  // system-wide realtime clock
+    SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point
+    SYSTEM_TIME_PROCESS = 2,   // high-resolution per-process clock
+    SYSTEM_TIME_THREAD = 3     // high-resolution per-thread clock
+};
+    
+// return the system-time according to the specified clock
+#ifdef __cplusplus
+nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
+#else
+nsecs_t systemTime(int clock);
+#endif // def __cplusplus
+
+// return the system-time according to the specified clock
+int sleepForInterval(long interval, struct timeval* pNextTick);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ------------------------------------------------------------------
+// C++ API
+
+#ifdef __cplusplus
+
+namespace android {
+/*
+ * Time the duration of something.
+ *
+ * Includes some timeval manipulation functions.
+ */
+class DurationTimer {
+public:
+    DurationTimer(void) {}
+    ~DurationTimer(void) {}
+
+    // Start the timer.
+    void start(void);
+    // Stop the timer.
+    void stop(void);
+    // Get the duration in microseconds.
+    long long durationUsecs(void) const;
+
+    // Subtract two timevals.  Returns the difference (ptv1-ptv2) in
+    // microseconds.
+    static long long subtractTimevals(const struct timeval* ptv1,
+        const struct timeval* ptv2);
+
+    // Add the specified amount of time to the timeval.
+    static void addToTimeval(struct timeval* ptv, long usec);
+
+private:
+    struct timeval  mStartWhen;
+    struct timeval  mStopWhen;
+};
+
+}; // android
+#endif // def __cplusplus
+
+#endif // _LIBS_UTILS_TIMERS_H
diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h
new file mode 100644
index 0000000..c04c37f
--- /dev/null
+++ b/include/utils/TypeHelpers.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_TYPE_HELPERS_H
+#define ANDROID_TYPE_HELPERS_H
+
+#include <new>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+/*
+ * Types traits
+ */
+    
+template <typename T> struct trait_trivial_ctor  { enum { value = false }; };
+template <typename T> struct trait_trivial_dtor  { enum { value = false }; };
+template <typename T> struct trait_trivial_copy  { enum { value = false }; };
+template <typename T> struct trait_trivial_assign{ enum { value = false }; };
+
+template <typename T> struct trait_pointer     { enum { value = false }; };    
+template <typename T> struct trait_pointer<T*> { enum { value = true }; };
+
+#define ANDROID_BASIC_TYPES_TRAITS( T )                                       \
+    template<> struct trait_trivial_ctor< T >  { enum { value = true }; };    \
+    template<> struct trait_trivial_dtor< T >  { enum { value = true }; };    \
+    template<> struct trait_trivial_copy< T >  { enum { value = true }; };    \
+    template<> struct trait_trivial_assign< T >{ enum { value = true }; }; 
+
+#define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign )                    \
+    template<> struct trait_trivial_ctor< T >  { enum { value = ctor }; };    \
+    template<> struct trait_trivial_dtor< T >  { enum { value = dtor }; };    \
+    template<> struct trait_trivial_copy< T >  { enum { value = copy }; };    \
+    template<> struct trait_trivial_assign< T >{ enum { value = assign }; }; 
+
+template <typename TYPE>
+struct traits {
+    enum {
+        is_pointer          = trait_pointer<TYPE>::value,
+        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
+        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
+        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
+        has_trivial_assign  = is_pointer || trait_trivial_assign<TYPE>::value   
+    };
+};
+
+template <typename T, typename U>
+struct aggregate_traits {
+    enum {
+        is_pointer          = false,
+        has_trivial_ctor    = traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
+        has_trivial_dtor    = traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
+        has_trivial_copy    = traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
+        has_trivial_assign  = traits<T>::has_trivial_assign && traits<U>::has_trivial_assign
+    };
+};
+
+// ---------------------------------------------------------------------------
+
+/*
+ * basic types traits
+ */
+ 
+ANDROID_BASIC_TYPES_TRAITS( void );
+ANDROID_BASIC_TYPES_TRAITS( bool );
+ANDROID_BASIC_TYPES_TRAITS( char );
+ANDROID_BASIC_TYPES_TRAITS( unsigned char );
+ANDROID_BASIC_TYPES_TRAITS( short );
+ANDROID_BASIC_TYPES_TRAITS( unsigned short );
+ANDROID_BASIC_TYPES_TRAITS( int );
+ANDROID_BASIC_TYPES_TRAITS( unsigned int );
+ANDROID_BASIC_TYPES_TRAITS( long );
+ANDROID_BASIC_TYPES_TRAITS( unsigned long );
+ANDROID_BASIC_TYPES_TRAITS( long long );
+ANDROID_BASIC_TYPES_TRAITS( unsigned long long );
+ANDROID_BASIC_TYPES_TRAITS( float );
+ANDROID_BASIC_TYPES_TRAITS( double );
+
+// ---------------------------------------------------------------------------
+
+    
+/*
+ * compare and order types
+ */
+
+template<typename TYPE> inline
+int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
+    return (lhs < rhs) ? 1 : 0;
+}
+
+template<typename TYPE> inline
+int compare_type(const TYPE& lhs, const TYPE& rhs) {
+    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
+}
+
+/*
+ * create, destroy, copy and assign types...
+ */
+ 
+template<typename TYPE> inline
+void construct_type(TYPE* p, size_t n) {
+    if (!traits<TYPE>::has_trivial_ctor) {
+        while (n--) {
+            new(p++) TYPE;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void destroy_type(TYPE* p, size_t n) {
+    if (!traits<TYPE>::has_trivial_dtor) {
+        while (n--) {
+            p->~TYPE();
+            p++;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void copy_type(TYPE* d, const TYPE* s, size_t n) {
+    if (!traits<TYPE>::has_trivial_copy) {
+        while (n--) {
+            new(d) TYPE(*s);
+            d++, s++;
+        }
+    } else {
+        memcpy(d,s,n*sizeof(TYPE));
+    }
+}
+
+template<typename TYPE> inline
+void assign_type(TYPE* d, const TYPE* s, size_t n) {
+    if (!traits<TYPE>::has_trivial_assign) {
+        while (n--) {
+            *d++ = *s++;
+        }
+    } else {
+        memcpy(d,s,n*sizeof(TYPE));
+    }
+}
+
+template<typename TYPE> inline
+void splat_type(TYPE* where, const TYPE* what, size_t n) {
+    if (!traits<TYPE>::has_trivial_copy) {
+        while (n--) {
+            new(where) TYPE(*what);
+            where++;
+        }
+    } else {
+         while (n--) {
+             *where++ = *what;
+        }
+    }
+}
+
+template<typename TYPE> inline
+void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
+        d += n;
+        s += n;
+        while (n--) {
+            --d, --s;
+            if (!traits<TYPE>::has_trivial_copy) {
+                new(d) TYPE(*s);
+            } else {
+                *d = *s;
+            }
+            if (!traits<TYPE>::has_trivial_dtor) {
+                s->~TYPE();
+            }
+        }
+    } else {
+        memmove(d,s,n*sizeof(TYPE));
+    }
+}
+
+template<typename TYPE> inline
+void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+    if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
+        while (n--) {
+            if (!traits<TYPE>::has_trivial_copy) {
+                new(d) TYPE(*s);
+            } else {
+                *d = *s;
+            }
+            if (!traits<TYPE>::has_trivial_dtor) {
+                s->~TYPE();
+            }
+            d++, s++;
+        }
+    } else {
+        memmove(d,s,n*sizeof(TYPE));
+    }
+}
+// ---------------------------------------------------------------------------
+
+/*
+ * a key/value pair
+ */
+
+template <typename KEY, typename VALUE>
+struct key_value_pair_t {
+    KEY     key;
+    VALUE   value;
+    key_value_pair_t() { }
+    key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
+    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
+    key_value_pair_t(const KEY& k) : key(k) { }
+    inline bool operator < (const key_value_pair_t& o) const {
+        return strictly_order_type(key, o.key);
+    }
+};
+
+template<>
+template <typename K, typename V>
+struct trait_trivial_ctor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
+template<> 
+template <typename K, typename V>
+struct trait_trivial_dtor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
+template<> 
+template <typename K, typename V>
+struct trait_trivial_copy< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
+template<> 
+template <typename K, typename V>
+struct trait_trivial_assign< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_assign};};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_TYPE_HELPERS_H
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
new file mode 100644
index 0000000..be365d8
--- /dev/null
+++ b/include/utils/Vector.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_VECTOR_H
+#define ANDROID_VECTOR_H
+
+#include <new>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Log.h>
+#include <utils/VectorImpl.h>
+#include <utils/TypeHelpers.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+/*!
+ * The main templated vector class ensuring type safety
+ * while making use of VectorImpl.
+ * This is the class users want to use.
+ */
+
+template <class TYPE>
+class Vector : private VectorImpl
+{
+public:
+            typedef TYPE    value_type;
+    
+    /*! 
+     * Constructors and destructors
+     */
+    
+                            Vector();
+                            Vector(const Vector<TYPE>& rhs);
+    virtual                 ~Vector();
+
+    /*! copy operator */
+            const Vector<TYPE>&     operator = (const Vector<TYPE>& rhs) const;
+            Vector<TYPE>&           operator = (const Vector<TYPE>& rhs);    
+
+    /*
+     * empty the vector
+     */
+
+    inline  void            clear()             { VectorImpl::clear(); }
+
+    /*! 
+     * vector stats
+     */
+
+    //! returns number of items in the vector
+    inline  size_t          size() const                { return VectorImpl::size(); }
+    //! returns wether or not the vector is empty
+    inline  bool            isEmpty() const             { return VectorImpl::isEmpty(); }
+    //! returns how many items can be stored without reallocating the backing store
+    inline  size_t          capacity() const            { return VectorImpl::capacity(); }
+    //! setst the capacity. capacity can never be reduced less than size()
+    inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }
+
+    /*! 
+     * C-style array access
+     */
+     
+    //! read-only C-style access 
+    inline  const TYPE*     array() const;
+    //! read-write C-style access
+            TYPE*           editArray();
+    
+    /*! 
+     * accessors
+     */
+
+    //! read-only access to an item at a given index
+    inline  const TYPE&     operator [] (size_t index) const;
+    //! alternate name for operator []
+    inline  const TYPE&     itemAt(size_t index) const;
+    //! stack-usage of the vector. returns the top of the stack (last element)
+            const TYPE&     top() const;
+    //! same as operator [], but allows to access the vector backward (from the end) with a negative index
+            const TYPE&     mirrorItemAt(ssize_t index) const;
+
+    /*!
+     * modifing the array
+     */
+
+    //! copy-on write support, grants write access to an item
+            TYPE&           editItemAt(size_t index);
+    //! grants right acces to the top of the stack (last element)
+            TYPE&           editTop();
+
+            /*! 
+             * append/insert another vector
+             */
+            
+    //! insert another vector at a given index
+            ssize_t         insertVectorAt(const Vector<TYPE>& vector, size_t index);
+
+    //! append another vector at the end of this one
+            ssize_t         appendVector(const Vector<TYPE>& vector);
+
+
+            /*! 
+             * 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
+            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();
+    //! pushes an item initialized with its default constructor
+    inline  void            push();
+    //! pushes an item on the top of the stack
+            void            push(const TYPE& item);
+    //! same as push() but returns the index the item was added at (or an error)
+    inline  ssize_t         add();
+    //! same as push() but returns the index the item was added at (or an error)
+            ssize_t         add(const TYPE& item);            
+    //! replace an item with a new one initialized with its default constructor
+    inline  ssize_t         replaceAt(size_t index);
+    //! replace an item with a new one
+            ssize_t         replaceAt(const TYPE& item, size_t index);
+
+    /*!
+     * remove items
+     */
+
+    //! remove several items
+    inline  ssize_t         removeItemsAt(size_t index, size_t count = 1);
+    //! remove one item
+    inline  ssize_t         removeAt(size_t index)  { return removeItemsAt(index); }
+
+    /*!
+     * sort (stable) the array
+     */
+     
+     typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
+     typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
+     
+     inline status_t        sort(compar_t cmp);
+     inline status_t        sort(compar_r_t cmp, void* state);
+
+protected:
+    virtual void    do_construct(void* storage, size_t num) const;
+    virtual void    do_destroy(void* storage, size_t num) const;
+    virtual void    do_copy(void* dest, const void* from, size_t num) const;
+    virtual void    do_splat(void* dest, const void* item, size_t num) const;
+    virtual void    do_move_forward(void* dest, const void* from, size_t num) const;
+    virtual void    do_move_backward(void* dest, const void* from, size_t num) const;
+};
+
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts from here...
+// ---------------------------------------------------------------------------
+
+template<class TYPE> inline
+Vector<TYPE>::Vector()
+    : VectorImpl(sizeof(TYPE),
+                ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)
+                |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)
+                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0)
+                |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
+                )
+{
+}
+
+template<class TYPE> inline
+Vector<TYPE>::Vector(const Vector<TYPE>& rhs)
+    : VectorImpl(rhs) {
+}
+
+template<class TYPE> inline
+Vector<TYPE>::~Vector() {
+    finish_vector();
+}
+
+template<class TYPE> inline
+Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
+    VectorImpl::operator = (rhs);
+    return *this; 
+}
+
+template<class TYPE> inline
+const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {
+    VectorImpl::operator = (rhs);
+    return *this; 
+}
+
+template<class TYPE> inline
+const TYPE* Vector<TYPE>::array() const {
+    return static_cast<const TYPE *>(arrayImpl());
+}
+
+template<class TYPE> inline
+TYPE* Vector<TYPE>::editArray() {
+    return static_cast<TYPE *>(editArrayImpl());
+}
+
+
+template<class TYPE> inline
+const TYPE& Vector<TYPE>::operator[](size_t index) const {
+    LOG_FATAL_IF( index>=size(),
+                  "itemAt: index %d is past size %d", (int)index, (int)size() );
+    return *(array() + index);
+}
+
+template<class TYPE> inline
+const TYPE& Vector<TYPE>::itemAt(size_t index) const {
+    return operator[](index);
+}
+
+template<class TYPE> inline
+const TYPE& Vector<TYPE>::mirrorItemAt(ssize_t index) const {
+    LOG_FATAL_IF( (index>0 ? index : -index)>=size(),
+                  "mirrorItemAt: index %d is past size %d",
+                  (int)index, (int)size() );
+    return *(array() + ((index<0) ? (size()-index) : index));
+}
+
+template<class TYPE> inline
+const TYPE& Vector<TYPE>::top() const {
+    return *(array() + size() - 1);
+}
+
+template<class TYPE> inline
+TYPE& Vector<TYPE>::editItemAt(size_t index) {
+    return *( static_cast<TYPE *>(editItemLocation(index)) );
+}
+
+template<class TYPE> inline
+TYPE& Vector<TYPE>::editTop() {
+    return *( static_cast<TYPE *>(editItemLocation(size()-1)) );
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) {
+    return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) {
+    return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector));
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
+    return VectorImpl::insertAt(&item, index, numItems);
+}
+
+template<class TYPE> inline
+void Vector<TYPE>::push(const TYPE& item) {
+    return VectorImpl::push(&item);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::add(const TYPE& item) {
+    return VectorImpl::add(&item);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) {
+    return VectorImpl::replaceAt(&item, index);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) {
+    return VectorImpl::insertAt(index, numItems);
+}
+
+template<class TYPE> inline
+void Vector<TYPE>::pop() {
+    VectorImpl::pop();
+}
+
+template<class TYPE> inline
+void Vector<TYPE>::push() {
+    VectorImpl::push();
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::add() {
+    return VectorImpl::add();
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::replaceAt(size_t index) {
+    return VectorImpl::replaceAt(index);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) {
+    return VectorImpl::removeItemsAt(index, count);
+}
+
+template<class TYPE> inline
+status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) {
+    return VectorImpl::sort((VectorImpl::compar_t)cmp);
+}
+
+template<class TYPE> inline
+status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) {
+    return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);
+}
+
+// ---------------------------------------------------------------------------
+
+template<class TYPE>
+void Vector<TYPE>::do_construct(void* storage, size_t num) const {
+    construct_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_destroy(void* storage, size_t num) const {
+    destroy_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
+    copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
+    splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
+    move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
+    move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_VECTOR_H
diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h
new file mode 100644
index 0000000..2525229
--- /dev/null
+++ b/include/utils/VectorImpl.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_VECTOR_IMPL_H
+#define ANDROID_VECTOR_IMPL_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts in here...
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+/*!
+ * Implementation of the guts of the vector<> class
+ * this ensures backward binary compatibility and
+ * reduces code size.
+ * For performance reasons, we expose mStorage and mCount
+ * so these fields are set in stone.
+ *
+ */
+
+class VectorImpl
+{
+public:
+    enum { // flags passed to the ctor
+        HAS_TRIVIAL_CTOR    = 0x00000001,
+        HAS_TRIVIAL_DTOR    = 0x00000002,
+        HAS_TRIVIAL_COPY    = 0x00000004,
+        HAS_TRIVIAL_ASSIGN  = 0x00000008
+    };
+
+                            VectorImpl(size_t itemSize, uint32_t flags);
+                            VectorImpl(const VectorImpl& rhs);
+    virtual                 ~VectorImpl();
+
+    /*! must be called from subclasses destructor */
+            void            finish_vector();
+
+            VectorImpl&     operator = (const VectorImpl& rhs);    
+            
+    /*! C-style array access */
+    inline  const void*     arrayImpl() const       { return mStorage; }
+            void*           editArrayImpl();
+            
+    /*! vector stats */
+    inline  size_t          size() const        { return mCount; }
+    inline  bool            isEmpty() const     { return mCount == 0; }
+            size_t          capacity() const;
+            ssize_t         setCapacity(size_t size);
+
+            /*! append/insert another vector */
+            ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);
+            ssize_t         appendVector(const VectorImpl& vector);
+            
+            /*! add/insert/replace items */
+            ssize_t         insertAt(size_t where, size_t numItems = 1);
+            ssize_t         insertAt(const void* item, size_t where, size_t numItems = 1);
+            void            pop();
+            void            push();
+            void            push(const void* item);
+            ssize_t         add();
+            ssize_t         add(const void* item);
+            ssize_t         replaceAt(size_t index);
+            ssize_t         replaceAt(const void* item, size_t index);
+
+            /*! remove items */
+            ssize_t         removeItemsAt(size_t index, size_t count = 1);
+            void            clear();
+
+            const void*     itemLocation(size_t index) const;
+            void*           editItemLocation(size_t index);
+
+            typedef int (*compar_t)(const void* lhs, const void* rhs);
+            typedef int (*compar_r_t)(const void* lhs, const void* rhs, void* state);
+            status_t        sort(compar_t cmp);
+            status_t        sort(compar_r_t cmp, void* state);
+
+protected:
+            size_t          itemSize() const;
+            void            release_storage();
+
+    virtual void            do_construct(void* storage, size_t num) const = 0;
+    virtual void            do_destroy(void* storage, size_t num) const = 0;
+    virtual void            do_copy(void* dest, const void* from, size_t num) const = 0;
+    virtual void            do_splat(void* dest, const void* item, size_t num) const = 0;
+    virtual void            do_move_forward(void* dest, const void* from, size_t num) const = 0;
+    virtual void            do_move_backward(void* dest, const void* from, size_t num) const = 0;
+
+    // take care of FBC...
+    virtual void            reservedVectorImpl1();
+    virtual void            reservedVectorImpl2();
+    virtual void            reservedVectorImpl3();
+    virtual void            reservedVectorImpl4();
+    virtual void            reservedVectorImpl5();
+    virtual void            reservedVectorImpl6();
+    virtual void            reservedVectorImpl7();
+    virtual void            reservedVectorImpl8();
+    
+private:
+        void* _grow(size_t where, size_t amount);
+        void  _shrink(size_t where, size_t amount);
+
+        inline void _do_construct(void* storage, size_t num) const;
+        inline void _do_destroy(void* storage, size_t num) const;
+        inline void _do_copy(void* dest, const void* from, size_t num) const;
+        inline void _do_splat(void* dest, const void* item, size_t num) const;
+        inline void _do_move_forward(void* dest, const void* from, size_t num) const;
+        inline void _do_move_backward(void* dest, const void* from, size_t num) const;
+
+            // These 2 fields are exposed in the inlines below,
+            // so they're set in stone.
+            void *      mStorage;   // base address of the vector
+            size_t      mCount;     // number of items
+
+    const   uint32_t    mFlags;
+    const   size_t      mItemSize;
+};
+
+
+
+class SortedVectorImpl : public VectorImpl
+{
+public:
+                            SortedVectorImpl(size_t itemSize, uint32_t flags);
+                            SortedVectorImpl(const VectorImpl& rhs);
+    virtual                 ~SortedVectorImpl();
+    
+    SortedVectorImpl&     operator = (const SortedVectorImpl& rhs);    
+
+    //! finds the index of an item
+            ssize_t         indexOf(const void* item) const;
+
+    //! finds where this item should be inserted
+            size_t          orderOf(const void* item) const;
+
+    //! add an item in the right place (or replaces it if there is one)
+            ssize_t         add(const void* item);
+
+    //! merges a vector into this one
+            ssize_t         merge(const VectorImpl& vector);
+            ssize_t         merge(const SortedVectorImpl& vector);
+             
+    //! removes an item
+            ssize_t         remove(const void* item);
+        
+protected:
+    virtual int             do_compare(const void* lhs, const void* rhs) const = 0;
+
+    // take care of FBC...
+    virtual void            reservedSortedVectorImpl1();
+    virtual void            reservedSortedVectorImpl2();
+    virtual void            reservedSortedVectorImpl3();
+    virtual void            reservedSortedVectorImpl4();
+    virtual void            reservedSortedVectorImpl5();
+    virtual void            reservedSortedVectorImpl6();
+    virtual void            reservedSortedVectorImpl7();
+    virtual void            reservedSortedVectorImpl8();
+
+private:
+            ssize_t         _indexOrderOf(const void* item, size_t* order = 0) const;
+
+            // these are made private, because they can't be used on a SortedVector
+            // (they don't have an implementation either)
+            ssize_t         add();
+            void            pop();
+            void            push();
+            void            push(const void* item);
+            ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);
+            ssize_t         appendVector(const VectorImpl& vector);
+            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);
+            ssize_t         replaceAt(const void* item, size_t index);
+};
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_VECTOR_IMPL_H
diff --git a/include/utils/ZipEntry.h b/include/utils/ZipEntry.h
new file mode 100644
index 0000000..e4698df
--- /dev/null
+++ b/include/utils/ZipEntry.h
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Zip archive entries.
+//
+// The ZipEntry class is tightly meshed with the ZipFile class.
+//
+#ifndef __LIBS_ZIPENTRY_H
+#define __LIBS_ZIPENTRY_H
+
+#include "Errors.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+namespace android {
+
+class ZipFile;
+
+/*
+ * ZipEntry objects represent a single entry in a Zip archive.
+ *
+ * You can use one of these to get or set information about an entry, but
+ * there are no functions here for accessing the data itself.  (We could
+ * tuck a pointer to the ZipFile in here for convenience, but that raises
+ * the likelihood of using ZipEntry objects after discarding the ZipFile.)
+ *
+ * File information is stored in two places: next to the file data (the Local
+ * File Header, and possibly a Data Descriptor), and at the end of the file
+ * (the Central Directory Entry).  The two must be kept in sync.
+ */
+class ZipEntry {
+public:
+    friend class ZipFile;
+
+    ZipEntry(void)
+        : mDeleted(false), mMarked(false)
+        {}
+    ~ZipEntry(void) {}
+
+    /*
+     * Returns "true" if the data is compressed.
+     */
+    bool isCompressed(void) const {
+        return mCDE.mCompressionMethod != kCompressStored;
+    }
+    int getCompressionMethod(void) const { return mCDE.mCompressionMethod; }
+
+    /*
+     * Return the uncompressed length.
+     */
+    off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; }
+
+    /*
+     * Return the compressed length.  For uncompressed data, this returns
+     * the same thing as getUncompresesdLen().
+     */
+    off_t getCompressedLen(void) const { return mCDE.mCompressedSize; }
+
+    /*
+     * Return the absolute file offset of the start of the compressed or
+     * uncompressed data.
+     */
+    off_t getFileOffset(void) const {
+        return mCDE.mLocalHeaderRelOffset +
+                LocalFileHeader::kLFHLen +
+                mLFH.mFileNameLength +
+                mLFH.mExtraFieldLength;
+    }
+
+    /*
+     * Return the data CRC.
+     */
+    unsigned long getCRC32(void) const { return mCDE.mCRC32; }
+
+    /*
+     * Return file modification time in UNIX seconds-since-epoch.
+     */
+    time_t getModWhen(void) const;
+
+    /*
+     * Return the archived file name.
+     */
+    const char* getFileName(void) const { return (const char*) mCDE.mFileName; }
+
+    /*
+     * Application-defined "mark".  Can be useful when synchronizing the
+     * contents of an archive with contents on disk.
+     */
+    bool getMarked(void) const { return mMarked; }
+    void setMarked(bool val) { mMarked = val; }
+
+    /*
+     * Some basic functions for raw data manipulation.  "LE" means
+     * Little Endian.
+     */
+    static inline unsigned short getShortLE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8);
+    }
+    static inline unsigned long getLongLE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+    }
+    static inline void putShortLE(unsigned char* buf, short val) {
+        buf[0] = (unsigned char) val;
+        buf[1] = (unsigned char) (val >> 8);
+    }
+    static inline void putLongLE(unsigned char* buf, long val) {
+        buf[0] = (unsigned char) val;
+        buf[1] = (unsigned char) (val >> 8);
+        buf[2] = (unsigned char) (val >> 16);
+        buf[3] = (unsigned char) (val >> 24);
+    }
+
+    /* defined for Zip archives */
+    enum {
+        kCompressStored     = 0,        // no compression
+        // shrunk           = 1,
+        // reduced 1        = 2,
+        // reduced 2        = 3,
+        // reduced 3        = 4,
+        // reduced 4        = 5,
+        // imploded         = 6,
+        // tokenized        = 7,
+        kCompressDeflated   = 8,        // standard deflate
+        // Deflate64        = 9,
+        // lib imploded     = 10,
+        // reserved         = 11,
+        // bzip2            = 12,
+    };
+
+    /*
+     * Deletion flag.  If set, the entry will be removed on the next
+     * call to "flush".
+     */
+    bool getDeleted(void) const { return mDeleted; }
+
+protected:
+    /*
+     * Initialize the structure from the file, which is pointing at
+     * our Central Directory entry.
+     */
+    status_t initFromCDE(FILE* fp);
+
+    /*
+     * Initialize the structure for a new file.  We need the filename
+     * and comment so that we can properly size the LFH area.  The
+     * filename is mandatory, the comment is optional.
+     */
+    void initNew(const char* fileName, const char* comment);
+
+    /*
+     * Initialize the structure with the contents of a ZipEntry from
+     * another file.
+     */
+    status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry);
+
+    /*
+     * Add some pad bytes to the LFH.  We do this by adding or resizing
+     * the "extra" field.
+     */
+    status_t addPadding(int padding);
+
+    /*
+     * Set information about the data for this entry.
+     */
+    void setDataInfo(long uncompLen, long compLen, unsigned long crc32,
+        int compressionMethod);
+
+    /*
+     * Set the modification date.
+     */
+    void setModWhen(time_t when);
+
+    /*
+     * Return the offset of the local file header.
+     */
+    off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }
+
+    /*
+     * Set the offset of the local file header, relative to the start of
+     * the current file.
+     */
+    void setLFHOffset(off_t offset) {
+        mCDE.mLocalHeaderRelOffset = (long) offset;
+    }
+
+    /* mark for deletion; used by ZipFile::remove() */
+    void setDeleted(void) { mDeleted = true; }
+
+private:
+    /* these are private and not defined */
+    ZipEntry(const ZipEntry& src);
+    ZipEntry& operator=(const ZipEntry& src);
+
+    /* returns "true" if the CDE and the LFH agree */
+    bool compareHeaders(void) const;
+    void copyCDEtoLFH(void);
+
+    bool        mDeleted;       // set if entry is pending deletion
+    bool        mMarked;        // app-defined marker
+
+    /*
+     * Every entry in the Zip archive starts off with one of these.
+     */
+    class LocalFileHeader {
+    public:
+        LocalFileHeader(void) :
+            mVersionToExtract(0),
+            mGPBitFlag(0),
+            mCompressionMethod(0),
+            mLastModFileTime(0),
+            mLastModFileDate(0),
+            mCRC32(0),
+            mCompressedSize(0),
+            mUncompressedSize(0),
+            mFileNameLength(0),
+            mExtraFieldLength(0),
+            mFileName(NULL),
+            mExtraField(NULL)
+        {}
+        virtual ~LocalFileHeader(void) {
+            delete[] mFileName;
+            delete[] mExtraField;
+        }
+
+        status_t read(FILE* fp);
+        status_t write(FILE* fp);
+
+        // unsigned long mSignature;
+        unsigned short  mVersionToExtract;
+        unsigned short  mGPBitFlag;
+        unsigned short  mCompressionMethod;
+        unsigned short  mLastModFileTime;
+        unsigned short  mLastModFileDate;
+        unsigned long   mCRC32;
+        unsigned long   mCompressedSize;
+        unsigned long   mUncompressedSize;
+        unsigned short  mFileNameLength;
+        unsigned short  mExtraFieldLength;
+        unsigned char*  mFileName;
+        unsigned char*  mExtraField;
+
+        enum {
+            kSignature      = 0x04034b50,
+            kLFHLen         = 30,       // LocalFileHdr len, excl. var fields
+        };
+
+        void dump(void) const;
+    };
+
+    /*
+     * Every entry in the Zip archive has one of these in the "central
+     * directory" at the end of the file.
+     */
+    class CentralDirEntry {
+    public:
+        CentralDirEntry(void) :
+            mVersionMadeBy(0),
+            mVersionToExtract(0),
+            mGPBitFlag(0),
+            mCompressionMethod(0),
+            mLastModFileTime(0),
+            mLastModFileDate(0),
+            mCRC32(0),
+            mCompressedSize(0),
+            mUncompressedSize(0),
+            mFileNameLength(0),
+            mExtraFieldLength(0),
+            mFileCommentLength(0),
+            mDiskNumberStart(0),
+            mInternalAttrs(0),
+            mExternalAttrs(0),
+            mLocalHeaderRelOffset(0),
+            mFileName(NULL),
+            mExtraField(NULL),
+            mFileComment(NULL)
+        {}
+        virtual ~CentralDirEntry(void) {
+            delete[] mFileName;
+            delete[] mExtraField;
+            delete[] mFileComment;
+        }
+
+        status_t read(FILE* fp);
+        status_t write(FILE* fp);
+
+        // unsigned long mSignature;
+        unsigned short  mVersionMadeBy;
+        unsigned short  mVersionToExtract;
+        unsigned short  mGPBitFlag;
+        unsigned short  mCompressionMethod;
+        unsigned short  mLastModFileTime;
+        unsigned short  mLastModFileDate;
+        unsigned long   mCRC32;
+        unsigned long   mCompressedSize;
+        unsigned long   mUncompressedSize;
+        unsigned short  mFileNameLength;
+        unsigned short  mExtraFieldLength;
+        unsigned short  mFileCommentLength;
+        unsigned short  mDiskNumberStart;
+        unsigned short  mInternalAttrs;
+        unsigned long   mExternalAttrs;
+        unsigned long   mLocalHeaderRelOffset;
+        unsigned char*  mFileName;
+        unsigned char*  mExtraField;
+        unsigned char*  mFileComment;
+
+        void dump(void) const;
+
+        enum {
+            kSignature      = 0x02014b50,
+            kCDELen         = 46,       // CentralDirEnt len, excl. var fields
+        };
+    };
+
+    enum {
+        //kDataDescriptorSignature  = 0x08074b50,   // currently unused
+        kDataDescriptorLen  = 16,           // four 32-bit fields
+
+        kDefaultVersion     = 20,           // need deflate, nothing much else
+        kDefaultMadeBy      = 0x0317,       // 03=UNIX, 17=spec v2.3
+        kUsesDataDescr      = 0x0008,       // GPBitFlag bit 3
+    };
+
+    LocalFileHeader     mLFH;
+    CentralDirEntry     mCDE;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ZIPENTRY_H
diff --git a/include/utils/ZipFile.h b/include/utils/ZipFile.h
new file mode 100644
index 0000000..44df5bb
--- /dev/null
+++ b/include/utils/ZipFile.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// General-purpose Zip archive access.  This class allows both reading and
+// writing to Zip archives, including deletion of existing entries.
+//
+#ifndef __LIBS_ZIPFILE_H
+#define __LIBS_ZIPFILE_H
+
+#include "ZipEntry.h"
+#include "Vector.h"
+#include "Errors.h"
+#include <stdio.h>
+
+namespace android {
+
+/*
+ * Manipulate a Zip archive.
+ *
+ * Some changes will not be visible in the until until "flush" is called.
+ *
+ * The correct way to update a file archive is to make all changes to a
+ * copy of the archive in a temporary file, and then unlink/rename over
+ * the original after everything completes.  Because we're only interested
+ * in using this for packaging, we don't worry about such things.  Crashing
+ * after making changes and before flush() completes could leave us with
+ * an unusable Zip archive.
+ */
+class ZipFile {
+public:
+    ZipFile(void)
+      : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false)
+      {}
+    ~ZipFile(void) {
+        if (!mReadOnly)
+            flush();
+        if (mZipFp != NULL)
+            fclose(mZipFp);
+        discardEntries();
+    }
+
+    /*
+     * Open a new or existing archive.
+     */
+    typedef enum {
+        kOpenReadOnly   = 0x01,
+        kOpenReadWrite  = 0x02,
+        kOpenCreate     = 0x04,     // create if it doesn't exist
+        kOpenTruncate   = 0x08,     // if it exists, empty it
+    };
+    status_t open(const char* zipFileName, int flags);
+
+    /*
+     * Add a file to the end of the archive.  Specify whether you want the
+     * library to try to store it compressed.
+     *
+     * If "storageName" is specified, the archive will use that instead
+     * of "fileName".
+     *
+     * If there is already an entry with the same name, the call fails.
+     * Existing entries with the same name must be removed first.
+     *
+     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+     */
+    status_t add(const char* fileName, int compressionMethod,
+        ZipEntry** ppEntry)
+    {
+        return add(fileName, fileName, compressionMethod, ppEntry);
+    }
+    status_t add(const char* fileName, const char* storageName,
+        int compressionMethod, ZipEntry** ppEntry)
+    {
+        return addCommon(fileName, NULL, 0, storageName,
+                         ZipEntry::kCompressStored,
+                         compressionMethod, ppEntry);
+    }
+
+    /*
+     * Add a file that is already compressed with gzip.
+     *
+     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+     */
+    status_t addGzip(const char* fileName, const char* storageName,
+        ZipEntry** ppEntry)
+    {
+        return addCommon(fileName, NULL, 0, storageName,
+                         ZipEntry::kCompressDeflated,
+                         ZipEntry::kCompressDeflated, ppEntry);
+    }
+
+    /*
+     * Add a file from an in-memory data buffer.
+     *
+     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+     */
+    status_t add(const void* data, size_t size, const char* storageName,
+        int compressionMethod, ZipEntry** ppEntry)
+    {
+        return addCommon(NULL, data, size, storageName,
+                         ZipEntry::kCompressStored,
+                         compressionMethod, ppEntry);
+    }
+
+    /*
+     * Add an entry by copying it from another zip file.  If "padding" is
+     * nonzero, the specified number of bytes will be added to the "extra"
+     * field in the header.
+     *
+     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+     */
+    status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
+        int padding, ZipEntry** ppEntry);
+
+    /*
+     * Mark an entry as having been removed.  It is not actually deleted
+     * from the archive or our internal data structures until flush() is
+     * called.
+     */
+    status_t remove(ZipEntry* pEntry);
+
+    /*
+     * Flush changes.  If mNeedCDRewrite is set, this writes the central dir.
+     */
+    status_t flush(void);
+
+    /*
+     * Expand the data into the buffer provided.  The buffer must hold
+     * at least <uncompressed len> bytes.  Variation expands directly
+     * to a file.
+     *
+     * Returns "false" if an error was encountered in the compressed data.
+     */
+    //bool uncompress(const ZipEntry* pEntry, void* buf) const;
+    //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;
+    void* uncompress(const ZipEntry* pEntry);
+
+    /*
+     * Get an entry, by name.  Returns NULL if not found.
+     *
+     * Does not return entries pending deletion.
+     */
+    ZipEntry* getEntryByName(const char* fileName) const;
+
+    /*
+     * Get the Nth entry in the archive.
+     *
+     * This will return an entry that is pending deletion.
+     */
+    int getNumEntries(void) const { return mEntries.size(); }
+    ZipEntry* getEntryByIndex(int idx) const;
+
+private:
+    /* these are private and not defined */
+    ZipFile(const ZipFile& src);
+    ZipFile& operator=(const ZipFile& src);
+
+    class EndOfCentralDir {
+    public:
+        EndOfCentralDir(void) :
+            mDiskNumber(0),
+            mDiskWithCentralDir(0),
+            mNumEntries(0),
+            mTotalNumEntries(0),
+            mCentralDirSize(0),
+            mCentralDirOffset(0),
+            mCommentLen(0),
+            mComment(NULL)
+            {}
+        virtual ~EndOfCentralDir(void) {
+            delete[] mComment;
+        }
+
+        status_t readBuf(const unsigned char* buf, int len);
+        status_t write(FILE* fp);
+
+        //unsigned long   mSignature;
+        unsigned short  mDiskNumber;
+        unsigned short  mDiskWithCentralDir;
+        unsigned short  mNumEntries;
+        unsigned short  mTotalNumEntries;
+        unsigned long   mCentralDirSize;
+        unsigned long   mCentralDirOffset;      // offset from first disk
+        unsigned short  mCommentLen;
+        unsigned char*  mComment;
+
+        enum {
+            kSignature      = 0x06054b50,
+            kEOCDLen        = 22,       // EndOfCentralDir len, excl. comment
+
+            kMaxCommentLen  = 65535,    // longest possible in ushort
+            kMaxEOCDSearch  = kMaxCommentLen + EndOfCentralDir::kEOCDLen,
+
+        };
+
+        void dump(void) const;
+    };
+
+
+    /* read all entries in the central dir */
+    status_t readCentralDir(void);
+
+    /* crunch deleted entries out */
+    status_t crunchArchive(void);
+
+    /* clean up mEntries */
+    void discardEntries(void);
+
+    /* common handler for all "add" functions */
+    status_t addCommon(const char* fileName, const void* data, size_t size,
+        const char* storageName, int sourceType, int compressionMethod,
+        ZipEntry** ppEntry);
+
+    /* copy all of "srcFp" into "dstFp" */
+    status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32);
+    /* copy all of "data" into "dstFp" */
+    status_t copyDataToFp(FILE* dstFp,
+        const void* data, size_t size, unsigned long* pCRC32);
+    /* copy some of "srcFp" into "dstFp" */
+    status_t copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
+        unsigned long* pCRC32);
+    /* like memmove(), but on parts of a single file */
+    status_t filemove(FILE* fp, off_t dest, off_t src, size_t n);
+    /* compress all of "srcFp" into "dstFp", using Deflate */
+    status_t compressFpToFp(FILE* dstFp, FILE* srcFp,
+        const void* data, size_t size, unsigned long* pCRC32);
+
+    /* get modification date from a file descriptor */
+    time_t getModTime(int fd);
+
+    /*
+     * We use stdio FILE*, which gives us buffering but makes dealing
+     * with files >2GB awkward.  Until we support Zip64, we're fine.
+     */
+    FILE*           mZipFp;             // Zip file pointer
+
+    /* one of these per file */
+    EndOfCentralDir mEOCD;
+
+    /* did we open this read-only? */
+    bool            mReadOnly;
+
+    /* set this when we trash the central dir */
+    bool            mNeedCDRewrite;
+
+    /*
+     * One ZipEntry per entry in the zip file.  I'm using pointers instead
+     * of objects because it's easier than making operator= work for the
+     * classes and sub-classes.
+     */
+    Vector<ZipEntry*>   mEntries;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ZIPFILE_H
diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h
new file mode 100644
index 0000000..30e0036
--- /dev/null
+++ b/include/utils/ZipFileCRO.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+//
+// C API for ead-only access to Zip archives, with minimal heap allocation.
+//
+#ifndef __LIBS_ZIPFILECRO_H
+#define __LIBS_ZIPFILECRO_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Trivial typedef to ensure that ZipFileCRO is not treated as a simple integer.
+ */
+typedef void* ZipFileCRO;
+
+/*
+ * Trivial typedef to ensure that ZipEntryCRO is not treated as a simple
+ * integer.  We use NULL to indicate an invalid value.
+ */
+typedef void* ZipEntryCRO;
+
+extern ZipFileCRO ZipFileXRO_open(const char* path);
+
+extern void ZipFileCRO_destroy(ZipFileCRO zip);
+
+extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip,
+        const char* fileName);
+
+extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
+        int* pMethod, long* pUncompLen,
+        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
+
+extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__LIBS_ZIPFILECRO_H*/
diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h
new file mode 100644
index 0000000..51c4f2f
--- /dev/null
+++ b/include/utils/ZipFileRO.h
@@ -0,0 +1,222 @@
+/*
+ * 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.
+ */
+
+//
+// Read-only access to Zip archives, with minimal heap allocation.
+//
+// This is similar to the more-complete ZipFile class, but no attempt
+// has been made to make them interchangeable.  This class operates under
+// a very different set of assumptions and constraints.
+//
+#ifndef __LIBS_ZIPFILERO_H
+#define __LIBS_ZIPFILERO_H
+
+#include "Errors.h"
+#include "FileMap.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+namespace android {
+
+/*
+ * Trivial typedef to ensure that ZipEntryRO is not treated as a simple
+ * integer.  We use NULL to indicate an invalid value.
+ */
+typedef void* ZipEntryRO;
+
+/*
+ * Open a Zip archive for reading.
+ *
+ * We want "open" and "find entry by name" to be fast operations, and we
+ * want to use as little memory as possible.  We memory-map the file,
+ * and load a hash table with pointers to the filenames (which aren't
+ * null-terminated).  The other fields are at a fixed offset from the
+ * filename, so we don't need to extract those (but we do need to byte-read
+ * and endian-swap them every time we want them).
+ *
+ * To speed comparisons when doing a lookup by name, we could make the mapping
+ * "private" (copy-on-write) and null-terminate the filenames after verifying
+ * the record structure.  However, this requires a private mapping of
+ * every page that the Central Directory touches.  Easier to tuck a copy
+ * of the string length into the hash table entry.
+ */
+class ZipFileRO {
+public:
+    ZipFileRO()
+        : mFd(-1), mFileMap(NULL), mHashTableSize(-1), mHashTable(NULL)
+        {}
+    ~ZipFileRO() {
+        free(mHashTable);
+        if (mFileMap)
+            mFileMap->release();
+        if (mFd >= 0)
+            close(mFd);
+    }
+
+    /*
+     * Open an archive.
+     */
+    status_t open(const char* zipFileName);
+
+    /*
+     * Find an entry, by name.  Returns the entry identifier, or NULL if
+     * not found.
+     *
+     * If two entries have the same name, one will be chosen at semi-random.
+     */
+    ZipEntryRO findEntryByName(const char* fileName) const;
+
+    /*
+     * Return the #of entries in the Zip archive.
+     */
+    int getNumEntries(void) const {
+        return mNumEntries;
+    }
+
+    /*
+     * Return the Nth entry.  Zip file entries are not stored in sorted
+     * order, and updated entries may appear at the end, so anyone walking
+     * the archive needs to avoid making ordering assumptions.  We take
+     * that further by returning the Nth non-empty entry in the hash table
+     * rather than the Nth entry in the archive.
+     *
+     * Valid values are [0..numEntries).
+     *
+     * [This is currently O(n).  If it needs to be fast we can allocate an
+     * additional data structure or provide an iterator interface.]
+     */
+    ZipEntryRO findEntryByIndex(int idx) const;
+
+    /*
+     * Copy the filename into the supplied buffer.  Returns 0 on success,
+     * -1 if "entry" is invalid, or the filename length if it didn't fit.  The
+     * length, and the returned string, include the null-termination.
+     */
+    int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const;
+
+    /*
+     * Get the vital stats for an entry.  Pass in NULL pointers for anything
+     * you don't need.
+     *
+     * "*pOffset" holds the Zip file offset of the entry's data.
+     *
+     * 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;
+
+    /*
+     * Create a new FileMap object that maps a subset of the archive.  For
+     * an uncompressed entry this effectively provides a pointer to the
+     * actual data, for a compressed entry this provides the input buffer
+     * for inflate().
+     */
+    FileMap* createEntryFileMap(ZipEntryRO entry) const;
+
+    /*
+     * Uncompress the data into a buffer.  Depending on the compression
+     * format, this is either an "inflate" operation or a memcpy.
+     *
+     * Use "uncompLen" from getEntryInfo() to determine the required
+     * buffer size.
+     *
+     * Returns "true" on success.
+     */
+    bool uncompressEntry(ZipEntryRO entry, void* buffer) const;
+
+    /*
+     * Uncompress the data to an open file descriptor.
+     */
+    bool uncompressEntry(ZipEntryRO entry, int fd) const;
+
+    /* Zip compression methods we support */
+    enum {
+        kCompressStored     = 0,        // no compression
+        kCompressDeflated   = 8,        // standard deflate
+    };
+
+    /*
+     * Utility function: uncompress deflated data, buffer to buffer.
+     */
+    static bool inflateBuffer(void* outBuf, const void* inBuf,
+        long uncompLen, long compLen);
+
+    /*
+     * Utility function: uncompress deflated data, buffer to fd.
+     */
+    static bool inflateBuffer(int fd, const void* inBuf,
+        long uncompLen, long compLen);
+
+    /*
+     * Some basic functions for raw data manipulation.  "LE" means
+     * Little Endian.
+     */
+    static inline unsigned short get2LE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8);
+    }
+    static inline unsigned long get4LE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+    }
+
+private:
+    /* these are private and not defined */ 
+    ZipFileRO(const ZipFileRO& src);
+    ZipFileRO& operator=(const ZipFileRO& src);
+
+    /* parse the archive, prepping internal structures */
+    bool parseZipArchive(void);
+
+    /* add a new entry to the hash table */
+    void addToHash(const char* str, int strLen, unsigned int hash);
+
+    /* compute string hash code */
+    static unsigned int computeHash(const char* str, int len);
+
+    /* convert a ZipEntryRO back to a hash table index */
+    int entryToIndex(const ZipEntryRO entry) const;
+
+    /*
+     * One entry in the hash table.
+     */
+    typedef struct HashEntry {
+        const char*     name;
+        unsigned short  nameLen;
+        //unsigned int    hash;
+    } HashEntry;
+
+    /* open Zip archive */
+    int         mFd;
+
+    /* mapped file */
+    FileMap*    mFileMap;
+
+    /* number of entries in the Zip archive */
+    int         mNumEntries;
+
+    /*
+     * We know how many entries are in the Zip archive, so we have a
+     * fixed-size hash table.  We probe for an empty slot.
+     */
+    int         mHashTableSize;
+    HashEntry*  mHashTable;
+};
+
+}; // namespace android
+
+#endif /*__LIBS_ZIPFILERO_H*/
diff --git a/include/utils/ZipUtils.h b/include/utils/ZipUtils.h
new file mode 100644
index 0000000..42c42b6
--- /dev/null
+++ b/include/utils/ZipUtils.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+//
+// Miscellaneous zip/gzip utility functions.
+//
+#ifndef __LIBS_ZIPUTILS_H
+#define __LIBS_ZIPUTILS_H
+
+#include <stdio.h>
+
+namespace android {
+
+/*
+ * Container class for utility functions, primarily for namespace reasons.
+ */
+class ZipUtils {
+public:
+    /*
+     * General utility function for uncompressing "deflate" data from a file
+     * to a buffer.
+     */
+    static bool inflateToBuffer(int fd, void* buf, long uncompressedLen,
+        long compressedLen);
+    static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen,
+        long compressedLen);
+
+    /*
+     * Someday we might want to make this generic and handle bzip2 ".bz2"
+     * files too.
+     *
+     * We could declare gzip to be a sub-class of zip that has exactly
+     * one always-compressed entry, but we currently want to treat Zip
+     * and gzip as distinct, so there's no value.
+     *
+     * The zlib library has some gzip utilities, but it has no interface
+     * for extracting the uncompressed length of the file (you do *not*
+     * want to gzseek to the end).
+     *
+     * Pass in a seeked file pointer for the gzip file.  If this is a gzip
+     * file, we set our return values appropriately and return "true" with
+     * the file seeked to the start of the compressed data.
+     */
+    static bool examineGzip(FILE* fp, int* pCompressionMethod,
+        long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32);
+
+private:
+    ZipUtils() {}
+    ~ZipUtils() {}
+};
+
+}; // namespace android
+
+#endif /*__LIBS_ZIPUTILS_H*/
diff --git a/include/utils/ashmem.h b/include/utils/ashmem.h
new file mode 100644
index 0000000..0854775
--- /dev/null
+++ b/include/utils/ashmem.h
@@ -0,0 +1,41 @@
+/* utils/ashmem.h
+ **
+ ** Copyright 2008 The Android Open Source Project
+ **
+ ** This file is dual licensed.  It may be redistributed and/or modified
+ ** under the terms of the Apache 2.0 License OR version 2 of the GNU
+ ** General Public License.
+ */
+
+#ifndef _UTILS_ASHMEM_H
+#define _UTILS_ASHMEM_H
+
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+
+#define ASHMEM_NAME_LEN		256
+
+#define ASHMEM_NAME_DEF		"dev/ashmem"
+
+/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */
+#define ASHMEM_NOT_REAPED	0
+#define ASHMEM_WAS_REAPED	1
+
+/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */
+#define ASHMEM_NOW_UNPINNED	0
+#define ASHMEM_NOW_PINNED	1
+
+#define __ASHMEMIOC		0x77
+
+#define ASHMEM_SET_NAME		_IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])
+#define ASHMEM_GET_NAME		_IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])
+#define ASHMEM_SET_SIZE		_IOW(__ASHMEMIOC, 3, size_t)
+#define ASHMEM_GET_SIZE		_IO(__ASHMEMIOC, 4)
+#define ASHMEM_SET_PROT_MASK	_IOW(__ASHMEMIOC, 5, unsigned long)
+#define ASHMEM_GET_PROT_MASK	_IO(__ASHMEMIOC, 6)
+#define ASHMEM_PIN		_IO(__ASHMEMIOC, 7)
+#define ASHMEM_UNPIN		_IO(__ASHMEMIOC, 8)
+#define ASHMEM_ISPINNED		_IO(__ASHMEMIOC, 9)
+#define ASHMEM_PURGE_ALL_CACHES	_IO(__ASHMEMIOC, 10)
+
+#endif	/* _UTILS_ASHMEM_H */
diff --git a/include/utils/executablepath.h b/include/utils/executablepath.h
new file mode 100644
index 0000000..c979432
--- /dev/null
+++ b/include/utils/executablepath.h
@@ -0,0 +1,28 @@
+/*
+ * 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_EXECUTABLEPATH_H
+#define _UTILS_EXECUTABLEPATH_H
+
+#include <limits.h>
+
+// returns the path to this executable
+#if __cplusplus
+extern "C"
+#endif
+void executablepath(char s[PATH_MAX]);
+
+#endif // _UTILS_EXECUTABLEPATH_H
diff --git a/include/utils/inet_address.h b/include/utils/inet_address.h
new file mode 100644
index 0000000..dbd8672
--- /dev/null
+++ b/include/utils/inet_address.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Internet address classes.  Modeled after Java classes.
+//
+#ifndef _RUNTIME_INET_ADDRESS_H
+#define _RUNTIME_INET_ADDRESS_H
+
+#ifdef HAVE_ANDROID_OS
+#error DO NOT USE THIS FILE IN THE DEVICE BUILD
+#endif
+
+
+namespace android {
+
+/*
+ * This class holds Internet addresses.  Perhaps more useful is its
+ * ability to look up addresses by name.
+ *
+ * Invoke one of the static factory methods to create a new object.
+ */
+class InetAddress {
+public:
+    virtual ~InetAddress(void);
+
+    // create from w.x.y.z or foo.bar.com notation
+    static InetAddress* getByName(const char* host);
+
+    // copy-construction
+    InetAddress(const InetAddress& orig);
+
+    const void* getAddress(void) const { return mAddress; }
+    int getAddressLength(void) const { return mLength; }
+    const char* getHostName(void) const { return mName; }
+
+private:
+    InetAddress(void);
+    // assignment (private)
+    InetAddress& operator=(const InetAddress& addr);
+
+    // use a void* here so we don't have to expose actual socket headers
+    void*       mAddress;   // this is really a ptr to sockaddr_in
+    int         mLength;
+    char*       mName;
+};
+
+
+/*
+ * Base class for socket addresses.
+ */
+class SocketAddress {
+public:
+    SocketAddress() {}
+    virtual ~SocketAddress() {}
+};
+
+
+/*
+ * Internet address class.  This combines an InetAddress with a port.
+ */
+class InetSocketAddress : public SocketAddress {
+public:
+    InetSocketAddress() :
+        mAddress(0), mPort(-1)
+        {}
+    ~InetSocketAddress(void) {
+        delete mAddress;
+    }
+
+    // Create an address with a host wildcard (useful for servers).
+    bool create(int port);
+    // Create an address with the specified host and port.
+    bool create(const InetAddress* addr, int port);
+    // Create an address with the specified host and port.  Does the
+    // hostname lookup.
+    bool create(const char* host, int port);
+
+    const InetAddress* getAddress(void) const { return mAddress; }
+    const int getPort(void) const { return mPort; }
+    const char* getHostName(void) const { return mAddress->getHostName(); }
+
+private:
+    InetAddress* mAddress;
+    int         mPort;
+};
+
+}; // namespace android
+
+#endif // _RUNTIME_INET_ADDRESS_H
diff --git a/include/utils/logger.h b/include/utils/logger.h
new file mode 100644
index 0000000..3a08019
--- /dev/null
+++ b/include/utils/logger.h
@@ -0,0 +1,46 @@
+/* utils/logger.h
+** 
+** Copyright 2007, The Android Open Source Project
+**
+** This file is dual licensed.  It may be redistributed and/or modified
+** under the terms of the Apache 2.0 License OR version 2 of the GNU
+** General Public License.
+*/
+
+#ifndef _UTILS_LOGGER_H
+#define _UTILS_LOGGER_H
+
+#include <stdint.h>
+
+struct logger_entry {
+    uint16_t    len;    /* length of the payload */
+    uint16_t    __pad;  /* no matter what, we get 2 bytes of padding */
+    int32_t     pid;    /* generating process's pid */
+    int32_t     tid;    /* generating process's tid */
+    int32_t     sec;    /* seconds since Epoch */
+    int32_t     nsec;   /* nanoseconds */
+    char        msg[0]; /* the entry's payload */
+};
+
+#define LOGGER_LOG_MAIN		"log/main"
+#define LOGGER_LOG_RADIO	"log/radio"
+#define LOGGER_LOG_EVENTS	"log/events"
+
+#define LOGGER_ENTRY_MAX_LEN		(4*1024)
+#define LOGGER_ENTRY_MAX_PAYLOAD	\
+	(LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
+
+#ifdef HAVE_IOCTL
+
+#include <sys/ioctl.h>
+
+#define __LOGGERIO	0xAE
+
+#define LOGGER_GET_LOG_BUF_SIZE		_IO(__LOGGERIO, 1) /* size of log */
+#define LOGGER_GET_LOG_LEN		_IO(__LOGGERIO, 2) /* used log len */
+#define LOGGER_GET_NEXT_ENTRY_LEN	_IO(__LOGGERIO, 3) /* next entry len */
+#define LOGGER_FLUSH_LOG		_IO(__LOGGERIO, 4) /* flush log */
+
+#endif // HAVE_IOCTL
+
+#endif /* _UTILS_LOGGER_H */
diff --git a/include/utils/misc.h b/include/utils/misc.h
new file mode 100644
index 0000000..62e84b4
--- /dev/null
+++ b/include/utils/misc.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Handy utility functions and portability code.
+//
+#ifndef _LIBS_UTILS_MISC_H
+#define _LIBS_UTILS_MISC_H
+
+#include <sys/time.h>
+#include "utils/Endian.h"
+
+namespace android {
+
+/* get #of elements in a static array */
+#ifndef NELEM
+# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
+#endif
+
+/*
+ * Make a copy of the string, using "new[]" instead of "malloc".  Free the
+ * string with delete[].
+ *
+ * Returns NULL if "str" is NULL.
+ */
+char* strdupNew(const char* str);
+
+/*
+ * Concatenate an argument vector into a single string.  If argc is >= 0
+ * it will be used; if it's < 0 then the last element in the arg vector
+ * must be NULL.
+ *
+ * This inserts a space between each argument.
+ *
+ * This does not automatically add double quotes around arguments with
+ * spaces in them.  This practice is necessary for Win32, because Win32's
+ * CreateProcess call is stupid.
+ *
+ * The caller should delete[] the returned string.
+ */
+char* concatArgv(int argc, const char* const argv[]);
+
+/*
+ * Count up the number of arguments in "argv".  The count does not include
+ * the final NULL entry.
+ */
+int countArgv(const char* const argv[]);
+
+/*
+ * Some utility functions for working with files.  These could be made
+ * part of a "File" class.
+ */
+typedef enum FileType {
+    kFileTypeUnknown = 0,
+    kFileTypeNonexistent,       // i.e. ENOENT
+    kFileTypeRegular,
+    kFileTypeDirectory,
+    kFileTypeCharDev,
+    kFileTypeBlockDev,
+    kFileTypeFifo,
+    kFileTypeSymlink,
+    kFileTypeSocket,
+} FileType;
+/* get the file's type; follows symlinks */
+FileType getFileType(const char* fileName);
+/* get the file's modification date; returns -1 w/errno set on failure */
+time_t getFileModDate(const char* fileName);
+
+/*
+ * Round up to the nearest power of 2.  Handy for hash tables.
+ */
+unsigned int roundUpPower2(unsigned int val);
+
+void strreverse(char* begin, char* end);
+void k_itoa(int value, char* str, int base);
+char* itoa(int val, int base);
+
+}; // namespace android
+
+#endif // _LIBS_UTILS_MISC_H
diff --git a/include/utils/ported.h b/include/utils/ported.h
new file mode 100644
index 0000000..eb3be01
--- /dev/null
+++ b/include/utils/ported.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Standard functions ported to the current platform.  Note these are NOT
+// in the "android" namespace.
+//
+#ifndef _LIBS_UTILS_PORTED_H
+#define _LIBS_UTILS_PORTED_H
+
+#include <sys/time.h>       // for timeval
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* library replacement functions */
+#if defined(NEED_GETTIMEOFDAY)
+int gettimeofday(struct timeval* tv, struct timezone* tz);
+#endif
+#if defined(NEED_USLEEP)
+void usleep(unsigned long usec);
+#endif
+#if defined(NEED_PIPE)
+int pipe(int filedes[2]);
+#endif
+#if defined(NEED_SETENV)
+int setenv(const char* name, const char* value, int overwrite);
+void unsetenv(const char* name);
+char* getenv(const char* name);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LIBS_UTILS_PORTED_H
diff --git a/include/utils/string_array.h b/include/utils/string_array.h
new file mode 100644
index 0000000..ede0644
--- /dev/null
+++ b/include/utils/string_array.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Sortable array of strings.  STL-ish, but STL-free.
+//  
+#ifndef _LIBS_UTILS_STRING_ARRAY_H
+#define _LIBS_UTILS_STRING_ARRAY_H
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace android {
+
+//
+// An expanding array of strings.  Add, get, sort, delete.
+//
+class StringArray {
+public:
+    StringArray()
+        : mMax(0), mCurrent(0), mArray(NULL)
+        {}
+    virtual ~StringArray() {
+        for (int i = 0; i < mCurrent; i++)
+            delete[] mArray[i];
+        delete[] mArray;
+    }
+
+    //
+    // Add a string.  A copy of the string is made.
+    //
+    bool push_back(const char* str) {
+        if (mCurrent >= mMax) {
+            char** tmp;
+
+            if (mMax == 0)
+                mMax = 16;      // initial storage
+            else
+                mMax *= 2;
+
+            tmp = new char*[mMax];
+            if (tmp == NULL)
+                return false;
+
+            memcpy(tmp, mArray, mCurrent * sizeof(char*));
+            delete[] mArray;
+            mArray = tmp;
+        }
+
+        int len = strlen(str);
+        mArray[mCurrent] = new char[len+1];
+        memcpy(mArray[mCurrent], str, len+1);
+        mCurrent++;
+
+        return true;
+    }
+
+    //
+    // Delete an entry.
+    //
+    void erase(int idx) {
+        if (idx < 0 || idx >= mCurrent)
+            return;
+        delete[] mArray[idx];
+        if (idx < mCurrent-1) {
+            memmove(&mArray[idx], &mArray[idx+1],
+                (mCurrent-1 - idx) * sizeof(char*));
+        }
+        mCurrent--;
+    }
+
+    //
+    // Sort the array.
+    //
+    void sort(int (*compare)(const void*, const void*)) {
+        qsort(mArray, mCurrent, sizeof(char*), compare);
+    }
+
+    //
+    // Pass this to the sort routine to do an ascending alphabetical sort.
+    //
+    static int cmpAscendingAlpha(const void* pstr1, const void* pstr2) {
+        return strcmp(*(const char**)pstr1, *(const char**)pstr2);
+    }
+
+    //
+    // Get the #of items in the array.
+    //
+    inline int size(void) const { return mCurrent; }
+
+    //
+    // Return entry N.
+    // [should use operator[] here]
+    //
+    const char* getEntry(int idx) const {
+        if (idx < 0 || idx >= mCurrent)
+            return NULL;
+        return mArray[idx];
+    }
+
+private:
+    int     mMax;
+    int     mCurrent;
+    char**  mArray;
+};
+
+}; // namespace android
+
+#endif // _LIBS_UTILS_STRING_ARRAY_H
diff --git a/include/utils/threads.h b/include/utils/threads.h
new file mode 100644
index 0000000..7dca810
--- /dev/null
+++ b/include/utils/threads.h
@@ -0,0 +1,347 @@
+/*
+ * 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 _LIBS_UTILS_THREADS_H
+#define _LIBS_UTILS_THREADS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+// ------------------------------------------------------------------
+// C API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* android_thread_id_t;
+
+typedef int (*android_thread_func_t)(void*);
+
+enum {
+    /*
+     * ***********************************************
+     * ** Keep in sync with android.os.Process.java **
+     * ***********************************************
+     * 
+     * This maps directly to the "nice" priorites we use in Android.
+     * A thread priority should be chosen inverse-proportinally to
+     * the amount of work the thread is expected to do. The more work
+     * a thread will do, the less favorable priority it should get so that 
+     * it doesn't starve the system. Threads not behaving properly might
+     * be "punished" by the kernel.
+     * Use the levels below when appropriate. Intermediate values are
+     * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.
+     */
+    ANDROID_PRIORITY_LOWEST         =  19,
+
+    /* use for background tasks */
+    ANDROID_PRIORITY_BACKGROUND     =  10,
+    
+    /* most threads run at normal priority */
+    ANDROID_PRIORITY_NORMAL         =   0,
+    
+    /* threads currently running a UI that the user is interacting with */
+    ANDROID_PRIORITY_FOREGROUND     =  -2,
+
+    /* the main UI thread has a slightly more favorable priority */
+    ANDROID_PRIORITY_DISPLAY        =  -4,
+    
+    /* ui service treads might want to run at a urgent display (uncommon) */
+    ANDROID_PRIORITY_URGENT_DISPLAY =  -8,
+    
+    /* all normal audio threads */
+    ANDROID_PRIORITY_AUDIO          = -16,
+    
+    /* service audio threads (uncommon) */
+    ANDROID_PRIORITY_URGENT_AUDIO   = -19,
+
+    /* should never be used in practice. regular process might not 
+     * be allowed to use this level */
+    ANDROID_PRIORITY_HIGHEST        = -20,
+
+    ANDROID_PRIORITY_DEFAULT        = ANDROID_PRIORITY_NORMAL,
+    ANDROID_PRIORITY_MORE_FAVORABLE = -1,
+    ANDROID_PRIORITY_LESS_FAVORABLE = +1,
+};
+
+// Create and run a new thread.
+extern int androidCreateThread(android_thread_func_t, void *);
+
+// Create thread with lots of parameters
+extern int androidCreateThreadEtc(android_thread_func_t entryFunction,
+                                  void *userData,
+                                  const char* threadName,
+                                  int32_t threadPriority,
+                                  size_t threadStackSize,
+                                  android_thread_id_t *threadId);
+
+// Get some sort of unique identifier for the current thread.
+extern android_thread_id_t androidGetThreadId();
+
+// Low-level thread creation -- never creates threads that can
+// interact with the Java VM.
+extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
+                                     void *userData,
+                                     const char* threadName,
+                                     int32_t threadPriority,
+                                     size_t threadStackSize,
+                                     android_thread_id_t *threadId);
+
+// Used by the Java Runtime to control how threads are created, so that
+// they can be proper and lovely Java threads.
+typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
+                                        void *userData,
+                                        const char* threadName,
+                                        int32_t threadPriority,
+                                        size_t threadStackSize,
+                                        android_thread_id_t *threadId);
+
+extern void androidSetCreateThreadFunc(android_create_thread_fn func);
+
+#ifdef __cplusplus
+}
+#endif
+
+// ------------------------------------------------------------------
+// C++ API
+
+#ifdef __cplusplus
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+namespace android {
+
+typedef android_thread_id_t thread_id_t;
+
+typedef android_thread_func_t thread_func_t;
+
+enum {
+    PRIORITY_LOWEST         = ANDROID_PRIORITY_LOWEST,
+    PRIORITY_BACKGROUND     = ANDROID_PRIORITY_BACKGROUND,
+    PRIORITY_NORMAL         = ANDROID_PRIORITY_NORMAL,
+    PRIORITY_FOREGROUND     = ANDROID_PRIORITY_FOREGROUND,
+    PRIORITY_DISPLAY        = ANDROID_PRIORITY_DISPLAY,
+    PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
+    PRIORITY_AUDIO          = ANDROID_PRIORITY_AUDIO,
+    PRIORITY_URGENT_AUDIO   = ANDROID_PRIORITY_URGENT_AUDIO,
+    PRIORITY_HIGHEST        = ANDROID_PRIORITY_HIGHEST,
+    PRIORITY_DEFAULT        = ANDROID_PRIORITY_DEFAULT,
+    PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
+    PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
+};
+
+// Create and run a new thread.
+inline bool createThread(thread_func_t f, void *a) {
+    return androidCreateThread(f, a) ? true : false;
+}
+
+// Create thread with lots of parameters
+inline bool createThreadEtc(thread_func_t entryFunction,
+                            void *userData,
+                            const char* threadName = "android:unnamed_thread",
+                            int32_t threadPriority = PRIORITY_DEFAULT,
+                            size_t threadStackSize = 0,
+                            thread_id_t *threadId = 0)
+{
+    return androidCreateThreadEtc(entryFunction, userData, threadName,
+        threadPriority, threadStackSize, threadId) ? true : false;
+}
+
+// Get some sort of unique identifier for the current thread.
+inline thread_id_t getThreadId() {
+    return androidGetThreadId();
+}
+
+/*
+ * 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 Mutex {
+public:
+                Mutex();
+                Mutex(const char* name);
+                ~Mutex();
+
+    // lock or unlock the mutex
+    status_t    lock();
+    void        unlock();
+
+    // lock if possible; returns 0 on success, error otherwise
+    status_t    tryLock();
+
+    // Manages the mutex automatically. It'll be locked when Autolock is
+    // constructed and released when Autolock goes out of scope.
+    class Autolock {
+    public:
+        inline Autolock(Mutex& mutex) : mpMutex(&mutex) { mutex.lock(); }
+        inline Autolock(Mutex* mutex) : mpMutex(mutex) { mutex->lock(); }
+        inline ~Autolock() { mpMutex->unlock(); }
+    private:
+        Mutex*  mpMutex;
+    };
+
+private:
+    friend class Condition;
+    
+    // A mutex cannot be copied
+                Mutex(const Mutex&);
+    Mutex&      operator = (const Mutex&);
+    void        _init();
+    
+    void*   mState;
+};
+
+/*
+ * Automatic mutex.  Declare one of these at the top of a function.
+ * When the function returns, it will go out of scope, and release the
+ * mutex.
+ */
+ 
+typedef Mutex::Autolock AutoMutex;
+
+
+/*
+ * Condition variable class.  The implementation is system-dependent.
+ *
+ * Condition variables are paired up with mutexes.  Lock the mutex,
+ * call wait(), then either re-wait() if things aren't quite what you want,
+ * or unlock the mutex and continue.  All threads calling wait() must
+ * use the same mutex for a given Condition.
+ */
+class Condition {
+public:
+    Condition();
+    ~Condition();
+    // Wait on the condition variable.  Lock the mutex before calling.
+    status_t wait(Mutex& mutex);
+    // Wait on the condition variable until the given time.  Lock the mutex
+    // before calling.
+    status_t wait(Mutex& mutex, nsecs_t abstime);
+    // same with relative timeout
+    status_t waitRelative(Mutex& mutex, nsecs_t reltime);
+    // Signal the condition variable, allowing one thread to continue.
+    void signal();
+    // Signal the condition variable, allowing all threads to continue.
+    void broadcast();
+
+private:
+    void*   mState;
+};
+
+
+/*
+ * Read/write lock.  The resource can have multiple readers or one writer,
+ * but can't be read and written at the same time.
+ *
+ * The same thread should not call a lock function while it already has
+ * a lock.  (Should be okay for multiple readers.)
+ */
+class ReadWriteLock {
+public:
+    ReadWriteLock()
+        : mNumReaders(0), mNumWriters(0)
+        {}
+    ~ReadWriteLock() {}
+
+    void lockForRead();
+    bool tryLockForRead();
+    void unlockForRead();
+
+    void lockForWrite();
+    bool tryLockForWrite();
+    void unlockForWrite();
+
+private:
+    int         mNumReaders;
+    int         mNumWriters;
+
+    Mutex       mLock;
+    Condition   mReadWaiter;
+    Condition   mWriteWaiter;
+#if defined(PRINT_RENDER_TIMES)
+    DurationTimer mDebugTimer;
+#endif
+};
+
+
+/*
+ * This is our spiffy thread object!
+ */
+
+class Thread : virtual public RefBase
+{
+public:
+    // Create a Thread object, but doesn't create or start the associated
+    // thread. See the run() method.
+                        Thread(bool canCallJava = true);
+    virtual             ~Thread();
+
+    // Start the thread in threadLoop() which needs to be implemented.
+    virtual status_t    run(    const char* name = 0,
+                                int32_t priority = PRIORITY_DEFAULT,
+                                size_t stack = 0);
+    
+    // Ask this object's thread to exit. This function is asynchronous, when the
+    // function returns the thread might still be running. Of course, this
+    // function can be called from a different thread.
+    virtual void        requestExit();
+
+    // Good place to do one-time initializations
+    virtual status_t    readyToRun();
+    
+    // Call requestExit() and wait until this object's thread exits.
+    // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
+    // this function from this object's thread. Will return WOULD_BLOCK in
+    // that case.
+            status_t    requestExitAndWait();
+
+protected:
+    // exitPending() returns true if requestExit() has been called.
+            bool        exitPending() const;
+    
+private:
+    // Derived class must implemtent threadLoop(). The thread starts its life
+    // here. There are two ways of using the Thread object:
+    // 1) loop: if threadLoop() returns true, it will be called again if
+    //          requestExit() wasn't called.
+    // 2) once: if threadLoop() returns false, the thread will exit upon return.
+    virtual bool        threadLoop() = 0;
+
+private:
+    Thread& operator=(const Thread&);
+    static  int             _threadLoop(void* user);
+    const   bool            mCanCallJava;
+            thread_id_t     mThread;
+            Mutex           mLock;
+            Condition       mThreadExitedCondition;
+            status_t        mStatus;
+    volatile bool           mExitPending;
+    volatile bool           mRunning;
+            sp<Thread>      mHoldSelf;
+};
+
+
+}; // namespace android
+
+#endif  // __cplusplus
+
+#endif // _LIBS_UTILS_THREADS_H
diff --git a/libs/audioflinger/Android.mk b/libs/audioflinger/Android.mk
new file mode 100644
index 0000000..a9cb303
--- /dev/null
+++ b/libs/audioflinger/Android.mk
@@ -0,0 +1,53 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioHardwareGeneric.cpp \
+    AudioHardwareStub.cpp \
+    AudioDumpInterface.cpp \
+    AudioHardwareInterface.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    libmedia \
+    libhardware
+
+ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
+  LOCAL_CFLAGS += -DGENERIC_AUDIO
+endif
+
+LOCAL_MODULE:= libaudiointerface
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=               \
+    AudioFlinger.cpp            \
+    AudioMixer.cpp.arm          \
+    AudioResampler.cpp.arm      \
+    AudioResamplerSinc.cpp.arm  \
+    AudioResamplerCubic.cpp.arm
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    libmedia \
+    libhardware
+
+ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
+  LOCAL_STATIC_LIBRARIES += libaudiointerface
+else
+  LOCAL_SHARED_LIBRARIES += libaudio
+endif
+
+LOCAL_MODULE:= libaudioflinger
+
+ifeq ($(TARGET_ARCH),arm)  # not simulator
+  LOCAL_CFLAGS += -DWITH_BLUETOOTH
+  LOCAL_C_INCLUDES += $(call include-path-for, bluez-libs)
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/audioflinger/AudioBufferProvider.h b/libs/audioflinger/AudioBufferProvider.h
new file mode 100644
index 0000000..1a467c7
--- /dev/null
+++ b/libs/audioflinger/AudioBufferProvider.h
@@ -0,0 +1,47 @@
+/*
+ * 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 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
new file mode 100644
index 0000000..5ff2f18
--- /dev/null
+++ b/libs/audioflinger/AudioDumpInterface.cpp
@@ -0,0 +1,94 @@
+/* //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"
+
+#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)
+{
+    if(hw == 0) {
+        LOGE("Dump construct hw = 0");
+    }
+    mFinalInterface = hw;
+    mStreamOut = 0;
+}
+
+
+status_t AudioDumpInterface::standby()
+{
+    if(mStreamOut)  mStreamOut->Close();
+    return mFinalInterface->standby();
+}
+
+
+AudioStreamOut* AudioDumpInterface::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate)
+{
+    AudioStreamOut* outFinal = mFinalInterface->openOutputStream(format, channelCount, sampleRate);
+
+    if(outFinal) {
+        mStreamOut =  new AudioStreamOutDump(outFinal);
+        return mStreamOut;
+    } else {
+        LOGE("Dump outFinal=0");
+        return 0;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+AudioStreamOutDump::AudioStreamOutDump( AudioStreamOut* finalStream)
+{
+    mFinalStream = finalStream;
+    mOutFile = 0;
+}
+
+ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
+{
+    ssize_t ret;
+    
+    ret = mFinalStream->write(buffer, bytes);
+    if(!mOutFile) {
+        mOutFile = fopen(FLINGER_DUMP_NAME, "ab");
+    }
+    if (mOutFile) {
+        fwrite(buffer, bytes, 1, mOutFile);
+    }
+    return ret;
+}
+
+void AudioStreamOutDump::Close(void)
+{
+    if(mOutFile) {
+        fclose(mOutFile);
+        mOutFile = 0;
+    }
+}
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
new file mode 100644
index 0000000..732b97d
--- /dev/null
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -0,0 +1,101 @@
+/* //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 <hardware/AudioHardwareInterface.h>
+
+namespace android {
+
+#define FLINGER_DUMP_NAME "/tmp/FlingerOut.pcm" // name of file used for dump
+
+class AudioStreamOutDump : public AudioStreamOut {
+public:
+                        AudioStreamOutDump( AudioStreamOut* FinalStream);
+                        virtual ssize_t     write(const void* buffer, size_t bytes);
+                        
+    virtual uint32_t    sampleRate() const { return mFinalStream->sampleRate(); }
+    virtual size_t      bufferSize() const { return mFinalStream->bufferSize(); }
+    virtual int         channelCount() const { return mFinalStream->channelCount(); }
+    virtual int         format() const { return mFinalStream->format(); }
+    virtual status_t    setVolume(float volume)
+                            { return mFinalStream->setVolume(volume); }
+    virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalStream->dump(fd, args); }
+    void                Close(void);
+
+private:
+    AudioStreamOut  *mFinalStream;
+    FILE            *mOutFile;     // output file
+};
+
+
+class AudioDumpInterface : public  AudioHardwareInterface
+{
+
+public:
+                        AudioDumpInterface(AudioHardwareInterface* hw);
+    virtual status_t    standby();
+    virtual AudioStreamOut* openOutputStream(
+                                int format=0,
+                                int channelCount=0,
+                                uint32_t sampleRate=0);
+
+    virtual             ~AudioDumpInterface()
+                            {delete mFinalInterface;}
+    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);}
+
+    virtual status_t    setRouting(int mode, uint32_t routes)
+                            {return mFinalInterface->setRouting(mode, routes);}
+    virtual status_t    getRouting(int mode, uint32_t* routes)
+                            {return mFinalInterface->getRouting(mode, routes);}
+    virtual status_t    getMode(int* mode)
+                            {return mFinalInterface->getMode(mode);}
+    
+    // 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    setParameter(const char* key, const char* value)
+                            {return mFinalInterface->setParameter(key, value);}
+
+    virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate)
+                            {return mFinalInterface->openInputStream( format, channelCount, sampleRate);}
+
+    virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
+
+protected:
+    virtual status_t    doRouting() {return 0;}
+    
+    AudioHardwareInterface  *mFinalInterface;
+    AudioStreamOutDump      *mStreamOut;
+    
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_DUMP_INTERFACE_H
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
new file mode 100644
index 0000000..fb21629
--- /dev/null
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -0,0 +1,1450 @@
+/* //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 <utils/IServiceManager.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/IPCThreadState.h>
+#include <utils/String16.h>
+#include <utils/threads.h>
+
+#include <media/AudioTrack.h>
+#include <media/AudioRecord.h>
+
+#include <private/media/AudioTrackShared.h>
+
+#include <hardware/AudioHardwareInterface.h>
+
+#include "AudioMixer.h"
+#include "AudioFlinger.h"
+
+namespace android {
+
+static const nsecs_t kStandbyTimeInNsecs = seconds(3);
+static const unsigned long kBufferRecoveryInUsecs = 2000;
+static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
+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;
+
+#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(), Thread(false),
+        mMasterVolume(0), mMasterMute(true),
+        mAudioMixer(0), mAudioHardware(0), mOutput(0), mAudioRecordThread(0),
+        mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0),
+        mMixBuffer(0), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0),
+        mStandby(false), mInWrite(false)
+{
+    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
+        mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
+        mOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT);
+        mHardwareStatus = AUDIO_HW_IDLE;
+        if (mOutput) {
+            mSampleRate = mOutput->sampleRate();
+            mChannelCount = mOutput->channelCount();
+            mFormat = mOutput->format();
+            mMixBufferSize = mOutput->bufferSize();
+            mFrameCount = mMixBufferSize / mChannelCount / sizeof(int16_t);
+            mMixBuffer = new int16_t[mFrameCount * mChannelCount];
+            memset(mMixBuffer, 0, mMixBufferSize);
+            mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
+            // FIXME - this should come from settings
+            setMasterVolume(1.0f);
+            setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
+            setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
+            setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
+            setMode(AudioSystem::MODE_NORMAL);
+            mMasterMute = false;
+        } else {
+            LOGE("Failed to initialize output stream");
+        }
+    } else {
+        LOGE("Couldn't even initialize the stubbed audio hardware!");
+    }
+}
+
+AudioFlinger::~AudioFlinger()
+{
+    delete mOutput;
+    delete mAudioHardware;
+    delete [] mMixBuffer;
+    delete mAudioMixer;
+    mAudioRecordThread.clear();
+}
+
+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::dumpTracks(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    result.append("Tracks:\n");
+    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) {
+        wp<Track> wTrack = mTracks[i];
+        if (wTrack != 0) {
+            sp<Track> track = wTrack.promote();
+            if (track != 0) {
+                track->dump(buffer, SIZE);
+                result.append(buffer);
+            }
+        }
+    }
+
+    result.append("Active Tracks:\n");
+    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 = mTracks[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::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    
+    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", audioMixer().trackNames());
+    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, "standby: %d\n", mStandby);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "Hardware status: %d\n", mHardwareStatus);
+    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;
+}
+
+status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
+{
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        dumpPermissionDenial(fd, args);
+    } else {
+        AutoMutex lock(&mLock);
+
+        dumpClients(fd, args);
+        dumpTracks(fd, args);
+        dumpInternals(fd, args);
+        if (mAudioHardware) {
+            mAudioHardware->dumpState(fd, args);
+        }
+    }
+    return NO_ERROR;
+}
+
+// Thread virtuals
+bool AudioFlinger::threadLoop()
+{
+    nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
+    unsigned long sleepTime = kBufferRecoveryInUsecs;
+    const size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
+    int16_t* curBuf = mMixBuffer;
+    Vector< sp<Track> > tracksToRemove;
+    size_t enabledTracks;
+    nsecs_t standbyTime = systemTime();
+
+    do {
+        enabledTracks = 0;
+        { // scope for the lock
+            Mutex::Autolock _l(mLock);
+            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
+
+            // put audio hardware into standby after short delay
+            if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
+                // wait until we have something to do...
+                LOGV("Audio hardware entering standby\n");
+                mHardwareStatus = AUDIO_HW_STANDBY;
+                if (!mStandby) {
+                    mAudioHardware->standby();
+                    mStandby = true;
+                }
+                mHardwareStatus = AUDIO_HW_IDLE;
+                // we're about to wait, flush the binder command buffer
+                IPCThreadState::self()->flushCommands();
+                mWaitWorkCV.wait(mLock);
+                LOGV("Audio hardware exiting standby\n");
+                standbyTime = systemTime() + kStandbyTimeInNsecs;
+                continue;
+            }
+
+            // find out which tracks need to be processed
+            size_t count = activeTracks.size();
+            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();
+                uint32_t u = cblk->user;
+                uint32_t s = cblk->server;
+
+                // The first time a track is added we wait
+                // for all its buffers to be filled before processing it
+                audioMixer().setActiveTrack(track->name());
+                if ((u > s) && (track->isReady(u, s) || track->isStopped()) &&
+                        !track->isPaused())
+                {
+                    //LOGD("u=%08x, s=%08x [OK]", u, s);
+
+                    // compute volume for this track
+                    int16_t left, right;
+                    if (track->isMuted() || mMasterMute || track->isPausing()) {
+                        left = right = 0;
+                        if (track->isPausing()) {
+                            LOGV("paused(%d)", track->name());
+                            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 = 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
+                    AudioMixer& mixer(audioMixer());
+                    mixer.setBufferProvider(track);
+                    mixer.enable(AudioMixer::MIXING);
+
+                    int param;
+                    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 {
+                            param = AudioMixer::VOLUME;
+                        }
+                    } else {
+                        param = AudioMixer::RAMP_VOLUME;
+                    }
+                    mixer.setParameter(param, AudioMixer::VOLUME0, left);
+                    mixer.setParameter(param, AudioMixer::VOLUME1, right);
+                    mixer.setParameter(
+                        AudioMixer::TRACK,
+                        AudioMixer::FORMAT, track->format());
+                    mixer.setParameter(
+                        AudioMixer::TRACK,
+                        AudioMixer::CHANNEL_COUNT, track->channelCount());
+                    mixer.setParameter(
+                        AudioMixer::RESAMPLE,
+                        AudioMixer::SAMPLE_RATE,
+                        int(cblk->sampleRate));
+
+                    // reset retry count
+                    track->mRetryCount = kMaxTrackRetries;
+                    enabledTracks++;
+                } else {
+                    //LOGD("u=%08x, s=%08x [NOT READY]", u, s);
+                    if (track->isStopped()) {
+                        track->mFillingUpStatus = Track::FS_FILLING;
+                        track->mFlags = 0;    
+                    }
+                    if (track->isTerminated() || track->isStopped() || track->isPaused()) {
+                        // We have consumed all the buffers of this track.
+                        // Remove it from the list of active tracks.
+                        LOGV("remove(%d) from active list", track->name());
+                        tracksToRemove.add(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());
+                            tracksToRemove.add(track);
+                        }
+                    }
+                    // LOGV("disable(%d)", track->name());
+                    audioMixer().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[i];
+                    mActiveTracks.remove(track);
+                    if (track->isTerminated()) {
+                        mTracks.remove(track);
+                        audioMixer().deleteTrackName(track->mName);
+                    }
+                }
+            }
+        }
+
+        if (LIKELY(enabledTracks)) {
+            // mix buffers...
+            audioMixer().process(curBuf);
+
+            // output audio to hardware
+            mLastWriteTime = systemTime();
+            mInWrite = true;
+            mOutput->write(curBuf, mixBufferSize);
+            mNumWrites++;
+            mInWrite = false;
+            mStandby = false;
+            nsecs_t temp = systemTime();
+            standbyTime = temp + kStandbyTimeInNsecs;
+            nsecs_t delta = temp - mLastWriteTime;
+            if (delta > maxPeriod) {
+                LOGW("write blocked for %llu msecs", ns2ms(delta));
+                mNumDelayedWrites++;
+            }
+            sleepTime = kBufferRecoveryInUsecs;
+        } else {
+            // There was nothing to mix this round, which means all
+            // active tracks were late. Sleep a little bit to give
+            // them another chance. If we're too late, the audio
+            // hardware will zero-fill for us.
+            LOGV("no buffers - usleep(%lu)", sleepTime);
+            usleep(sleepTime);
+            if (sleepTime < kMaxBufferRecoveryInUsecs) {
+                sleepTime += kBufferRecoveryInUsecs;
+            }
+        }
+
+        // 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();
+    } while (true);
+
+    return false;
+}
+
+status_t AudioFlinger::readyToRun()
+{
+    if (mSampleRate == 0) {
+        LOGE("No working audio driver found.");
+        return NO_INIT;
+    }
+    LOGI("AudioFlinger's main thread ready to run.");
+    return NO_ERROR;
+}
+
+void AudioFlinger::onFirstRef()
+{
+    run("AudioFlinger", ANDROID_PRIORITY_URGENT_AUDIO);
+}
+
+// IAudioFlinger interface
+sp<IAudioTrack> AudioFlinger::createTrack(
+        pid_t pid,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int bufferCount,
+        uint32_t flags)
+{
+    if (streamType >= AudioTrack::NUM_STREAM_TYPES) {
+        LOGE("invalid stream type");
+        return NULL;
+    }
+
+    if (sampleRate > MAX_SAMPLE_RATE) {
+        LOGE("Sample rate out of range: %d", sampleRate);
+        return NULL;
+    }
+
+    sp<Track> track;
+    sp<TrackHandle> trackHandle;
+    Mutex::Autolock _l(mLock);
+
+    if (mSampleRate == 0) {
+        LOGE("Audio driver not initialized.");
+        return trackHandle;
+    }
+
+    sp<Client> client;
+    wp<Client> wclient = mClients.valueFor(pid);
+
+    if (wclient != NULL) {
+        client = wclient.promote();
+    } else {
+        client = new Client(this, pid);
+        mClients.add(pid, client);
+    }
+
+    // FIXME: Buffer size should be based on sample rate for consistent latency
+    track = new Track(this, client, streamType, sampleRate, format,
+            channelCount, bufferCount, channelCount == 1 ? mMixBufferSize>>1 : mMixBufferSize);
+    mTracks.add(track);
+    trackHandle = new TrackHandle(track);
+    return trackHandle;
+}
+
+uint32_t AudioFlinger::sampleRate() const
+{
+    return mSampleRate;
+}
+
+int AudioFlinger::channelCount() const
+{
+    return mChannelCount;
+}
+
+int AudioFlinger::format() const
+{
+    return mFormat;
+}
+
+size_t AudioFlinger::frameCount() const
+{
+    return mFrameCount;
+}
+
+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) {
+        mMasterVolume = 1.0f;
+    }
+    else {
+        mMasterVolume = value;
+    }
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+    if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
+        LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
+        return BAD_VALUE;
+    }
+
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_HW_GET_ROUTING;
+    uint32_t r;
+    uint32_t err = mAudioHardware->getRouting(mode, &r);
+    if (err == NO_ERROR) {
+        r = (r & ~mask) | (routes & mask);
+        mHardwareStatus = AUDIO_HW_SET_ROUTING;
+        err = mAudioHardware->setRouting(mode, r);
+    }
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return err;
+}
+
+uint32_t AudioFlinger::getRouting(int mode) const
+{
+    uint32_t routes = 0;
+    if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
+        mHardwareStatus = AUDIO_HW_GET_ROUTING;
+        mAudioHardware->getRouting(mode, &routes);
+        mHardwareStatus = AUDIO_HW_IDLE;
+    } else {
+        LOGW("Illegal value: getRouting(%d)", mode);
+    }
+    return routes;
+}
+
+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);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return ret;
+}
+
+int AudioFlinger::getMode() const
+{
+    int mode = AudioSystem::MODE_INVALID;
+    mHardwareStatus = AUDIO_HW_SET_MODE;
+    mAudioHardware->getMode(&mode);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return mode;
+}
+
+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;
+    return NO_ERROR;
+}
+
+float AudioFlinger::masterVolume() const
+{
+    return mMasterVolume;
+}
+
+bool AudioFlinger::masterMute() const
+{
+    return mMasterMute;
+}
+
+status_t AudioFlinger::setStreamVolume(int stream, float value)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+    
+    mStreamTypes[stream].volume = value;
+    status_t ret = NO_ERROR;
+    if (stream == AudioTrack::VOICE_CALL) {
+        AutoMutex lock(mHardwareLock);
+        mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
+        ret = mAudioHardware->setVoiceVolume(value);
+        mHardwareStatus = AUDIO_HW_IDLE;
+    }
+    return ret;
+}
+
+status_t AudioFlinger::setStreamMute(int stream, bool muted)
+{
+    // check calling permissions
+    if (!settingsAllowed()) {
+        return PERMISSION_DENIED;
+    }
+
+    if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
+        return BAD_VALUE;
+    }
+    mStreamTypes[stream].mute = muted;
+    return NO_ERROR;
+}
+
+float AudioFlinger::streamVolume(int stream) const
+{
+    if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
+        return 0.0f;
+    }
+    return mStreamTypes[stream].volume;
+}
+
+bool AudioFlinger::streamMute(int stream) const
+{
+    if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
+        return true;
+    }
+    return mStreamTypes[stream].mute;
+}
+
+bool AudioFlinger::isMusicActive() const
+{
+    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->mStreamType == AudioTrack::MUSIC)
+            return true;
+    }
+    return false;
+}
+
+status_t AudioFlinger::setParameter(const char* key, const char* value)
+{
+    status_t result;
+    AutoMutex lock(mHardwareLock);
+    mHardwareStatus = AUDIO_SET_PARAMETER;
+    result = mAudioHardware->setParameter(key, value);
+    mHardwareStatus = AUDIO_HW_IDLE;
+    return result;
+}
+
+void AudioFlinger::removeClient(pid_t pid)
+{
+    Mutex::Autolock _l(mLock);
+    mClients.removeItem(pid);
+}
+
+status_t AudioFlinger::addTrack(const sp<Track>& track)
+{
+    Mutex::Autolock _l(mLock);
+
+    // here the track could be either new, or restarted
+    // in both cases "unstop" the track
+    if (track->isPaused()) {
+        track->mState = TrackBase::RESUMING;
+        LOGV("PAUSED => RESUMING (%d)", track->name());
+    } else {
+        track->mState = TrackBase::ACTIVE;
+        LOGV("? => ACTIVE (%d)", track->name());
+    }
+    // set retry count for buffer fill
+    track->mRetryCount = kMaxTrackStartupRetries;
+    LOGV("mWaitWorkCV.broadcast");
+    mWaitWorkCV.broadcast();
+
+    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;
+        mActiveTracks.add(track);
+        return NO_ERROR;
+    }
+    return ALREADY_EXISTS;
+}
+
+void AudioFlinger::removeTrack(wp<Track> track, int name)
+{
+    Mutex::Autolock _l(mLock);
+    sp<Track> t = track.promote();
+    if (t!=NULL && (t->mState <= TrackBase::STOPPED)) {
+        remove_track_l(track, name);
+    }
+}
+
+void AudioFlinger::remove_track_l(wp<Track> track, int name)
+{
+    sp<Track> t = track.promote();
+    if (t!=NULL) {
+        t->reset();
+    }
+    audioMixer().deleteTrackName(name);
+    mActiveTracks.remove(track);
+    mWaitWorkCV.broadcast();
+}
+
+void AudioFlinger::destroyTrack(const sp<Track>& track)
+{
+    // NOTE: We're acquiring a strong reference on the track before
+    // acquiring the lock, this is to make sure removing it from
+    // mTracks won't cause the destructor to be called while the lock is
+    // held (note that technically, 'track' could be a reference to an item
+    // in mTracks, which is why we need to do this).
+    sp<Track> keep(track);
+    Mutex::Autolock _l(mLock);
+    track->mState = TrackBase::TERMINATED;
+    if (mActiveTracks.indexOf(track) < 0) {
+        LOGV("remove track (%d) and delete from mixer", track->name());
+        mTracks.remove(track);
+        audioMixer().deleteTrackName(keep->name());
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
+    :   RefBase(),
+        mAudioFlinger(audioFlinger),
+        mMemoryDealer(new MemoryDealer(1024*1024)),
+        mPid(pid)
+{
+    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
+}
+
+AudioFlinger::Client::~Client()
+{
+    mAudioFlinger->removeClient(mPid);
+}
+
+const sp<MemoryDealer>& AudioFlinger::Client::heap() const
+{
+    return mMemoryDealer;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::TrackBase::TrackBase(
+            const sp<AudioFlinger>& audioFlinger,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int bufferCount,
+            int bufferSize)
+    :   RefBase(),
+        mAudioFlinger(audioFlinger),
+        mClient(client),
+        mStreamType(streamType),
+        mFormat(format),
+        mChannelCount(channelCount),
+        mBufferCount(bufferCount),
+        mFlags(0),
+        mBufferSize(bufferSize),
+        mState(IDLE),
+        mClientTid(-1)
+{
+    mName = audioFlinger->audioMixer().getTrackName();
+    if (mName < 0) {
+        LOGE("no more track names availlable");
+        return;
+    }
+
+    // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
+    size_t size = sizeof(audio_track_cblk_t) + bufferCount * bufferSize;
+    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->size = bufferSize;
+            mCblk->sampleRate = sampleRate;
+            mBuffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+            memset(mBuffers, 0, bufferCount * bufferSize);
+        }
+    } else {
+        LOGE("not enough memory for AudioTrack size=%u", size);
+        client->heap()->dump("AudioTrack");
+        return;
+    }
+}
+
+AudioFlinger::TrackBase::~TrackBase()
+{
+    mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
+    mCblkMemory.clear();            // and free the shared memory
+    mClient.clear();
+}
+
+void AudioFlinger::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    buffer->raw = 0;
+    buffer->frameCount = 0;
+    step();
+}
+
+bool AudioFlinger::TrackBase::step() {
+    bool result;
+    audio_track_cblk_t* cblk = this->cblk();
+    
+    result = cblk->stepServer(bufferCount()); 
+    if (!result) {
+        LOGV("stepServer failed acquiring cblk mutex");
+        mFlags |= STEPSERVER_FAILED;
+    }
+    return result;
+}
+
+void AudioFlinger::TrackBase::reset() {
+    audio_track_cblk_t* cblk = this->cblk();
+
+    cblk->user = 0;
+    cblk->server = 0;
+    mFlags = 0;    
+}
+
+sp<IMemory> AudioFlinger::TrackBase::getCblk() const
+{
+    return mCblkMemory;
+}
+
+int AudioFlinger::TrackBase::sampleRate() const {
+    return mCblk->sampleRate;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::Track::Track(
+            const sp<AudioFlinger>& audioFlinger,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int bufferCount,
+            int bufferSize)
+    :   TrackBase(audioFlinger, client, streamType, sampleRate, format, channelCount, bufferCount, bufferSize)
+{
+    mVolume[0] = 1.0f;
+    mVolume[1] = 1.0f;
+    mMute = false;
+}
+
+AudioFlinger::Track::~Track()
+{
+    wp<Track> weak(this); // never create a strong ref from the dtor
+    mState = TERMINATED;
+    mAudioFlinger->removeTrack(weak, mName);
+}
+
+void AudioFlinger::Track::destroy()
+{
+    mAudioFlinger->destroyTrack(this);
+}
+
+void AudioFlinger::Track::dump(char* buffer, size_t size)
+{
+    snprintf(buffer, size, "  %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
+            mName - AudioMixer::TRACK0,
+            mClient->pid(),
+            mStreamType,
+            mFormat,
+            mChannelCount,
+            mBufferCount,
+            mState,
+            mMute,
+            mFillingUpStatus,
+            mCblk->sampleRate,
+            mCblk->volume[0],
+            mCblk->volume[1],
+            mCblk->server,
+            mCblk->user);
+}
+
+status_t AudioFlinger::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+     audio_track_cblk_t* cblk = this->cblk();
+     uint32_t u = cblk->user;
+     uint32_t s = cblk->server;
+     
+     // 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;
+     }
+
+     if (LIKELY(u > s)) {
+         int index = s & audio_track_cblk_t::BUFFER_MASK;
+         buffer->raw = getBuffer(index);
+         buffer->frameCount = mAudioFlinger->frameCount();
+         return NO_ERROR;
+     }
+getNextBuffer_exit:
+     buffer->raw = 0;
+     buffer->frameCount = 0;
+     return NOT_ENOUGH_DATA;
+}
+
+bool AudioFlinger::Track::isReady(uint32_t u, int32_t s) const {
+    if (mFillingUpStatus != FS_FILLING) return true;
+    const uint32_t u_seq = u & audio_track_cblk_t::SEQUENCE_MASK;
+    const uint32_t u_buf = u & audio_track_cblk_t::BUFFER_MASK;
+    const uint32_t s_seq = s & audio_track_cblk_t::SEQUENCE_MASK;
+    const uint32_t s_buf = s & audio_track_cblk_t::BUFFER_MASK;
+    if (u_seq > s_seq && u_buf == s_buf) {
+        mFillingUpStatus = FS_FILLED;
+        return true;
+    }
+    return false;
+}
+
+status_t AudioFlinger::Track::start()
+{
+    LOGV("start(%d)", mName);
+    mAudioFlinger->addTrack(this);
+    return NO_ERROR;
+}
+
+void AudioFlinger::Track::stop()
+{
+    LOGV("stop(%d)", mName);
+    Mutex::Autolock _l(mAudioFlinger->mLock);
+    if (mState > STOPPED) {
+        mState = STOPPED;
+        // If the track is not active (PAUSED and buffers full), flush buffers  
+        if (mAudioFlinger->mActiveTracks.indexOf(this) < 0) {
+            reset();
+        }
+        LOGV("(> STOPPED) => STOPPED (%d)", mName);
+    }
+}
+
+void AudioFlinger::Track::pause()
+{
+    LOGV("pause(%d)", mName);
+    Mutex::Autolock _l(mAudioFlinger->mLock);
+    if (mState == ACTIVE || mState == RESUMING) {
+        mState = PAUSING;
+        LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
+    }
+}
+
+void AudioFlinger::Track::flush()
+{
+    LOGV("flush(%d)", mName);
+    Mutex::Autolock _l(mAudioFlinger->mLock);
+    if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
+        return;
+    }
+    // No point remaining in PAUSED state after a flush => go to
+    // STOPPED state
+    mState = STOPPED;
+
+    // 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();
+}
+
+void AudioFlinger::Track::reset()
+{
+    TrackBase::reset();
+    mFillingUpStatus = FS_FILLING;
+}
+
+void AudioFlinger::Track::mute(bool muted)
+{
+    mMute = muted;
+}
+
+void AudioFlinger::Track::setVolume(float left, float right)
+{
+    mVolume[0] = left;
+    mVolume[1] = right;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::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<AudioFlinger::AudioRecordThread> AudioFlinger::audioRecordThread()
+{
+    Mutex::Autolock _l(mLock);
+    return mAudioRecordThread;
+}
+
+void AudioFlinger::endRecord()
+{
+    Mutex::Autolock _l(mLock);
+    mAudioRecordThread.clear();
+}
+
+sp<IAudioRecord> AudioFlinger::openRecord(
+        pid_t pid,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int bufferCount,
+        uint32_t flags)
+{
+    sp<AudioRecordThread> thread;
+    sp<RecordTrack> recordTrack;
+    sp<RecordHandle> recordHandle;
+    sp<Client> client;
+    wp<Client> wclient;
+    AudioStreamIn* input = 0;
+
+    // check calling permissions
+    if (!recordingAllowed()) {
+        goto Exit;
+    }
+
+    if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) {
+        LOGE("invalid stream type");
+        goto Exit;
+    }
+
+    if (sampleRate > MAX_SAMPLE_RATE) {
+        LOGE("Sample rate out of range");
+        goto Exit;
+    }
+
+    if (mSampleRate == 0) {
+        LOGE("Audio driver not initialized");
+        goto Exit;
+    }
+
+    // Create audio thread - take mutex to prevent race condition
+    {
+        Mutex::Autolock _l(mLock);
+        if (mAudioRecordThread != 0) {
+            LOGE("Record channel already open");
+            goto Exit;
+        }
+        thread = new AudioRecordThread(this);
+        mAudioRecordThread = thread;
+    }
+    // It's safe to release the mutex here since the client doesn't get a
+    // handle until we return from this call
+
+    // open driver, initialize h/w
+    input = mAudioHardware->openInputStream(
+            AudioSystem::PCM_16_BIT, channelCount, sampleRate);
+    if (!input) {
+        LOGE("Error opening input stream");
+        mAudioRecordThread.clear();
+        goto Exit;
+    }
+
+    // add client to list
+    {
+        Mutex::Autolock _l(mLock);
+        wclient = mClients.valueFor(pid);
+        if (wclient != NULL) {
+            client = wclient.promote();
+        } else {
+            client = new Client(this, pid);
+            mClients.add(pid, client);
+        }
+    }
+
+    // create new record track and pass to record thread
+    recordTrack = new RecordTrack(this, client, streamType, sampleRate,
+            format, channelCount, bufferCount, input->bufferSize());
+
+    // spin up record thread
+    thread->open(recordTrack, input);
+    thread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);
+
+    // return to handle to client
+    recordHandle = new RecordHandle(recordTrack);
+
+Exit:
+    return recordHandle;
+}
+
+status_t AudioFlinger::startRecord() {
+    sp<AudioRecordThread> t = audioRecordThread();
+    if (t == 0) return NO_INIT;
+    return t->start();
+}
+
+void AudioFlinger::stopRecord() {
+    sp<AudioRecordThread> t = audioRecordThread();
+    if (t != 0) t->stop();
+}
+
+void AudioFlinger::exitRecord()
+{
+    sp<AudioRecordThread> t = audioRecordThread();
+    if (t != 0) t->exit();
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::RecordTrack::RecordTrack(
+            const sp<AudioFlinger>& audioFlinger,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int bufferCount,
+            int bufferSize)
+    :   TrackBase(audioFlinger, client, streamType, sampleRate, format,
+            channelCount, bufferCount, bufferSize),
+            mOverflow(false)
+{
+}
+
+AudioFlinger::RecordTrack::~RecordTrack()
+{
+    mAudioFlinger->audioMixer().deleteTrackName(mName);
+    mAudioFlinger->exitRecord();
+}
+
+status_t AudioFlinger::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+     audio_track_cblk_t* cblk = this->cblk();
+     const uint32_t u_seq = cblk->user & audio_track_cblk_t::SEQUENCE_MASK;
+     const uint32_t u_buf = cblk->user & audio_track_cblk_t::BUFFER_MASK;
+     const uint32_t s_seq = cblk->server & audio_track_cblk_t::SEQUENCE_MASK;
+     const uint32_t s_buf = cblk->server & audio_track_cblk_t::BUFFER_MASK;
+     
+     // 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;
+     }
+
+     if (LIKELY(s_seq == u_seq || s_buf != u_buf)) {
+         buffer->raw = getBuffer(s_buf);
+         buffer->frameCount = mAudioFlinger->frameCount();
+         return NO_ERROR;
+     }
+
+getNextBuffer_exit:     
+     buffer->raw = 0;
+     buffer->frameCount = 0;
+     return NOT_ENOUGH_DATA;
+}
+
+status_t AudioFlinger::RecordTrack::start()
+{
+    return mAudioFlinger->startRecord();
+}
+
+void AudioFlinger::RecordTrack::stop()
+{
+    mAudioFlinger->stopRecord();
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::RecordTrack>& recordTrack)
+    : BnAudioRecord(),
+    mRecordTrack(recordTrack)
+{
+}
+
+AudioFlinger::RecordHandle::~RecordHandle() {}
+
+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::AudioRecordThread::AudioRecordThread(const sp<AudioFlinger>& audioFlinger) :
+    mAudioFlinger(audioFlinger),
+    mRecordTrack(0),
+    mInput(0),
+    mActive(false)
+{
+}
+
+AudioFlinger::AudioRecordThread::~AudioRecordThread()
+{
+}
+
+bool AudioFlinger::AudioRecordThread::threadLoop()
+{
+    LOGV("AudioRecordThread: start record loop");
+
+    // start recording
+    while (!exitPending()) {
+        if (!mActive) {
+            mLock.lock();
+            if (!mActive && !exitPending()) {
+                LOGV("AudioRecordThread: loop stopping");
+                mWaitWorkCV.wait(mLock);
+                LOGV("AudioRecordThread: loop starting");
+            }
+            mLock.unlock();
+        } else {
+            // promote strong ref so track isn't deleted while we access it
+            sp<RecordTrack> t = mRecordTrack.promote();
+
+            // if we lose the weak reference, client is gone.
+            if (t == 0) {
+                LOGV("AudioRecordThread: client deleted track");
+                break;
+            }
+
+            if (LIKELY(t->getNextBuffer(&mBuffer) == NO_ERROR)) {
+                if (mInput->read(mBuffer.raw, t->mBufferSize) < 0) {
+                    LOGE("Error reading audio input");
+                    sleep(1);
+                }
+                t->releaseBuffer(&mBuffer);
+            }
+
+            // client isn't retrieving buffers fast enough
+            else {
+                if (!t->setOverflow())
+                    LOGW("AudioRecordThread: buffer overflow");
+            }
+        }
+    };
+
+    // close hardware
+    close();
+
+    // delete this object - no more data references after this call
+    mAudioFlinger->endRecord();
+    return false;
+}
+
+status_t AudioFlinger::AudioRecordThread::open(const sp<RecordTrack>& recordTrack, AudioStreamIn *input) {
+    LOGV("AudioRecordThread::open");
+    // check for record channel already open
+    AutoMutex lock(&mLock);
+    if (mRecordTrack != NULL) {
+        LOGE("Record channel already open");
+        return ALREADY_EXISTS;
+    }
+    mRecordTrack = recordTrack;
+    mInput = input;
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::AudioRecordThread::start()
+{
+    LOGV("AudioRecordThread::start");
+    AutoMutex lock(&mLock);
+    if (mActive) return -EBUSY;
+
+    sp<RecordTrack> t = mRecordTrack.promote();
+    if (t == 0) return UNKNOWN_ERROR;
+
+    // signal thread to start
+    LOGV("Signal record thread");
+    mActive = true;
+    mWaitWorkCV.signal();
+    return NO_ERROR;
+}
+
+void AudioFlinger::AudioRecordThread::stop() {
+    LOGV("AudioRecordThread::stop");
+    AutoMutex lock(&mLock);
+    if (mActive) {
+        mActive = false;
+        mWaitWorkCV.signal();
+    }
+}
+
+void AudioFlinger::AudioRecordThread::exit()
+{
+    LOGV("AudioRecordThread::exit");
+    AutoMutex lock(&mLock);
+    requestExit();
+    mWaitWorkCV.signal();
+}
+
+
+status_t AudioFlinger::AudioRecordThread::close()
+{
+    LOGV("AudioRecordThread::close");
+    AutoMutex lock(&mLock);
+    if (!mInput) return NO_INIT;
+    delete mInput;
+    mInput = 0;
+    return NO_ERROR;
+}
+
+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
new file mode 100644
index 0000000..8c02617
--- /dev/null
+++ b/libs/audioflinger/AudioFlinger.h
@@ -0,0 +1,490 @@
+/* //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 <media/IAudioFlinger.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 <utils/MemoryDealer.h>
+#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
+
+#include <hardware/AudioHardwareInterface.h>
+
+#include "AudioBufferProvider.h"
+
+namespace android {
+
+class audio_track_cblk_t;
+class AudioMixer;
+class AudioBuffer;
+
+// ----------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ----------------------------------------------------------------------------
+
+class AudioFlinger : public BnAudioFlinger, protected Thread
+{
+public:
+    static void instantiate();
+
+    virtual     status_t    dump(int fd, const Vector<String16>& args);
+
+    // Thread virtuals
+    virtual     bool        threadLoop();
+    virtual     status_t    readyToRun();
+    virtual     void        onFirstRef();
+
+    // IAudioFlinger interface
+    virtual sp<IAudioTrack> createTrack(
+                                pid_t pid,
+                                int streamType,
+                                uint32_t sampleRate,
+                                int format,
+                                int channelCount,
+                                int bufferCount,
+                                uint32_t flags);
+
+    virtual     uint32_t    sampleRate() const;
+    virtual     int         channelCount() const;
+    virtual     int         format() const;
+    virtual     size_t      frameCount() 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;
+
+    virtual     status_t    setRouting(int mode, uint32_t routes, uint32_t mask);
+    virtual     uint32_t    getRouting(int mode) const;
+
+    virtual     status_t    setMode(int mode);
+    virtual     int         getMode() const;
+
+    virtual     status_t    setMicMute(bool state);
+    virtual     bool        getMicMute() const;
+
+    virtual     bool        isMusicActive() const;
+
+    virtual     status_t    setParameter(const char* key, const char* value);
+
+    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 streamType,
+                                uint32_t sampleRate,
+                                int format,
+                                int channelCount,
+                                int bufferCount,
+                                uint32_t flags);
+
+    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 dumpTracks(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; }
+    private:
+                            Client(const Client&);
+                            Client& operator = (const Client&);
+        sp<AudioFlinger>    mAudioFlinger;
+        sp<MemoryDealer>    mMemoryDealer;
+        pid_t               mPid;
+    };
+
+
+    // --- Track ---
+    class TrackHandle;
+    class RecordHandle;
+    class AudioRecordThread;
+
+    // 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 
+        };
+        
+                            TrackBase(  const sp<AudioFlinger>& audioFlinger,
+                                    const sp<Client>& client,
+                                    int streamType,
+                                    uint32_t sampleRate,
+                                    int format,
+                                    int channelCount,
+                                    int bufferCount,
+                                    int bufferSize);
+                            ~TrackBase();
+
+        virtual status_t    start() = 0;
+        virtual void        stop() = 0;
+                sp<IMemory> getCblk() const;
+
+    protected:
+        friend class AudioFlinger;
+        friend class RecordHandle;
+
+                            TrackBase(const TrackBase&);
+                            TrackBase& operator = (const TrackBase&);
+
+        virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+        virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
+        audio_track_cblk_t* cblk() const {
+            return mCblk;
+        }
+
+        int type() const {
+            return mStreamType;
+        }
+
+        int format() const {
+            return mFormat;
+        }
+
+        int channelCount() const {
+            return mChannelCount;
+        }
+
+        int bufferCount() const {
+            return mBufferCount;
+        }
+
+        int sampleRate() const;
+
+        void* getBuffer(int n) const {
+            return (char*)mBuffers + n * mBufferSize;
+        }
+
+        int name() const {
+            return mName;
+        }
+
+        bool isStopped() const {
+            return mState == STOPPED;
+        }
+
+        bool isTerminated() const {
+            return mState == TERMINATED;
+        }
+
+        bool step();
+        void reset();
+
+        sp<AudioFlinger>    mAudioFlinger;
+        sp<Client>          mClient;
+        sp<IMemory>         mCblkMemory;
+        audio_track_cblk_t* mCblk;
+        int                 mStreamType;
+        uint8_t             mFormat;
+        uint8_t             mChannelCount;
+        uint8_t             mBufferCount;
+        uint8_t             mFlags;
+        void*               mBuffers;
+        size_t              mBufferSize;
+        int                 mName;
+        // we don't really need a lock for these
+        int                 mState;
+        int                 mClientTid;
+    };
+
+    // playback track
+    class Track : public TrackBase {
+    public:
+                            Track(  const sp<AudioFlinger>& audioFlinger,
+                                    const sp<Client>& client,
+                                    int streamType,
+                                    uint32_t sampleRate,
+                                    int format,
+                                    int channelCount,
+                                    int bufferCount,
+                                    int bufferSize);
+                            ~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);
+
+    private:
+        friend class AudioFlinger;
+        friend class TrackHandle;
+
+                            Track(const Track&);
+                            Track& operator = (const Track&);
+
+        virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+        bool isMuted() const {
+            return mMute;
+        }
+
+        bool isPausing() const {
+            return mState == PAUSING;
+        }
+
+        bool isPaused() const {
+            return mState == PAUSED;
+        }
+
+        bool isReady(uint32_t u, int32_t s) const;
+
+        void setPaused() { mState = PAUSED; }
+        void reset();
+
+        // 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;
+    };  // end of Track
+
+    friend class AudioBuffer;
+
+    class TrackHandle : public android::BnAudioTrack {
+    public:
+                            TrackHandle(const sp<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<Track> mTrack;
+    };
+
+    struct  stream_type_t {
+        stream_type_t()
+            :   volume(1.0f),
+                mute(false)
+        {
+        }
+        float       volume;
+        bool        mute;
+    };
+
+    friend class Client;
+    friend class Track;
+
+
+                void        removeClient(pid_t pid);
+
+                status_t    addTrack(const sp<Track>& track);
+                void        removeTrack(wp<Track> track, int name);
+                void        remove_track_l(wp<Track> track, int name);
+                void        destroyTrack(const sp<Track>& track);
+
+                AudioMixer& audioMixer() {
+                    return *mAudioMixer;
+                }
+
+    // record track
+    class RecordTrack : public TrackBase {
+    public:
+                            RecordTrack(  const sp<AudioFlinger>& audioFlinger,
+                                    const sp<Client>& client,
+                                    int streamType,
+                                    uint32_t sampleRate,
+                                    int format,
+                                    int channelCount,
+                                    int bufferCount,
+                                    int bufferSize);
+                            ~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; }
+
+    private:
+        friend class AudioFlinger;
+        friend class RecordHandle;
+        friend class AudioRecordThread;
+
+                            RecordTrack(const Track&);
+                            RecordTrack& operator = (const Track&);
+
+        virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+        bool                mOverflow;
+    };
+
+    class RecordHandle : public android::BnAudioRecord {
+    public:
+        RecordHandle(const sp<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<RecordTrack> mRecordTrack;
+    };
+
+    // record thread
+    class AudioRecordThread : public Thread
+    {
+    public:
+        AudioRecordThread(const sp<AudioFlinger>& audioFlinger);
+        virtual             ~AudioRecordThread();
+        virtual bool        threadLoop();
+        virtual status_t    readyToRun() { return NO_ERROR; }
+        virtual void        onFirstRef() {}
+
+                status_t    open(const sp<RecordTrack>& recordTrack, AudioStreamIn *input);
+                status_t    start();
+                void        stop();
+                status_t    close();
+                void        exit();
+                
+                bool        isOpen() { return bool(mRecordTrack != NULL); }
+
+    private:
+                AudioRecordThread();
+                sp<AudioFlinger>                    mAudioFlinger;
+                wp<RecordTrack>                     mRecordTrack;
+                AudioStreamIn*                      mInput;
+                Mutex                               mLock;
+                Condition                           mWaitWorkCV;
+                AudioBufferProvider::Buffer         mBuffer;
+                volatile bool                       mActive;
+    };
+
+    friend class AudioRecordThread;
+
+                sp<AudioRecordThread> audioRecordThread();
+                void        endRecord();
+                status_t    startRecord();
+                void        stopRecord();
+                void        exitRecord();
+                
+                AudioHardwareInterface* audioHardware() { return mAudioHardware; }
+
+    mutable     Mutex                                       mHardwareLock;
+    mutable     Mutex                                       mLock;
+    mutable     Condition                                   mWaitWorkCV;
+                DefaultKeyedVector< pid_t, wp<Client> >     mClients;
+                SortedVector< wp<Track> >                   mActiveTracks;
+                SortedVector< sp<Track> >                   mTracks;
+                float                               mMasterVolume;
+                uint32_t                            mMasterRouting;
+                bool                                mMasterMute;
+                stream_type_t                       mStreamTypes[AudioTrack::NUM_STREAM_TYPES];
+
+                AudioMixer*                         mAudioMixer;
+                AudioHardwareInterface*             mAudioHardware;
+                AudioStreamOut*                     mOutput;
+                sp<AudioRecordThread>               mAudioRecordThread;
+                uint32_t                            mSampleRate;
+                size_t                              mFrameCount;
+                int                                 mChannelCount;
+                int                                 mFormat;
+                int                                 mMixBufferSize;
+                int16_t*                            mMixBuffer;
+    mutable     int                                 mHardwareStatus;
+                nsecs_t                             mLastWriteTime;
+                int                                 mNumWrites;
+                int                                 mNumDelayedWrites;
+                bool                                mStandby;
+                bool                                mInWrite;
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
new file mode 100644
index 0000000..b1e5b7f
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -0,0 +1,293 @@
+/*
+**
+** 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"
+
+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);
+    delete mOutput;
+    delete mInput;
+}
+
+status_t AudioHardwareGeneric::initCheck()
+{
+    if (mFd >= 0) {
+        if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
+            return NO_ERROR;
+    }
+    return NO_INIT;
+}
+
+status_t AudioHardwareGeneric::standby()
+{
+    // Implement: audio hardware to standby mode
+    return NO_ERROR;
+}
+
+AudioStreamOut* AudioHardwareGeneric::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate)
+{
+    AutoMutex lock(mLock);
+
+    // only one output stream allowed
+    if (mOutput) return 0;
+
+    // create new output stream
+    AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
+    if (out->set(this, mFd, format, channelCount, sampleRate) == NO_ERROR) {
+        mOutput = out;
+    } else {
+        delete out;
+    }
+    return mOutput;
+}
+
+void AudioHardwareGeneric::closeOutputStream(AudioStreamOutGeneric* out) {
+    if (out == mOutput) mOutput = 0;
+}
+
+AudioStreamIn* AudioHardwareGeneric::openInputStream(
+        int format, int channelCount, uint32_t sampleRate)
+{
+    AutoMutex lock(mLock);
+
+    // only one input stream allowed
+    if (mInput) return 0;
+
+    // create new output stream
+    AudioStreamInGeneric* in = new AudioStreamInGeneric();
+    if (in->set(this, mFd, format, channelCount, sampleRate) == NO_ERROR) {
+        mInput = in;
+    } else {
+        delete in;
+    }
+    return mInput;
+}
+
+void AudioHardwareGeneric::closeInputStream(AudioStreamInGeneric* in) {
+    if (in == 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,
+        int format,
+        int channels,
+        uint32_t rate)
+{
+    // fix up defaults
+    if (format == 0) format = AudioSystem::PCM_16_BIT;
+    if (channels == 0) channels = channelCount();
+    if (rate == 0) rate = sampleRate();
+
+    // check values
+    if ((format != AudioSystem::PCM_16_BIT) ||
+            (channels != channelCount()) ||
+            (rate != sampleRate()))
+        return BAD_VALUE;
+
+    mAudioHardware = hw;
+    mFd = fd;
+    return NO_ERROR;
+}
+
+AudioStreamOutGeneric::~AudioStreamOutGeneric()
+{
+    if (mAudioHardware)
+        mAudioHardware->closeOutputStream(this);
+}
+
+ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
+{
+    Mutex::Autolock _l(mLock);
+    return ssize_t(::write(mFd, buffer, bytes));
+}
+
+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, "\tchannel count: %d\n", channelCount());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    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;
+}
+
+// ----------------------------------------------------------------------------
+
+// record functions
+status_t AudioStreamInGeneric::set(
+        AudioHardwareGeneric *hw,
+        int fd,
+        int format,
+        int channels,
+        uint32_t rate)
+{
+    // FIXME: remove logging
+    LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, format, channels, rate);
+    // check values
+    if ((format != AudioSystem::PCM_16_BIT) ||
+            (channels != channelCount()) ||
+            (rate != sampleRate())) {
+        LOGE("Error opening input channel");
+        return BAD_VALUE;
+    }
+
+    mAudioHardware = hw;
+    mFd = fd;
+    return NO_ERROR;
+}
+
+AudioStreamInGeneric::~AudioStreamInGeneric()
+{
+    // FIXME: remove logging
+    LOGD("AudioStreamInGeneric destructor");
+    if (mAudioHardware)
+        mAudioHardware->closeInputStream(this);
+}
+
+ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
+{
+    // FIXME: remove logging
+    LOGD("AudioStreamInGeneric::read(%p, %d) from fd %d", buffer, bytes, mFd);
+    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, "\tchannel count: %d\n", channelCount());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    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;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
new file mode 100644
index 0000000..10cc45d
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -0,0 +1,135 @@
+/*
+**
+** 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/AudioHardwareInterface.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,
+            int format,
+            int channelCount,
+            uint32_t sampleRate);
+
+    virtual uint32_t    sampleRate() const { return 44100; }
+    virtual size_t      bufferSize() const { return 4096; }
+    virtual int         channelCount() const { return 2; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual status_t    setVolume(float volume) { return INVALID_OPERATION; }
+    virtual ssize_t     write(const void* buffer, size_t bytes);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+
+private:
+    AudioHardwareGeneric *mAudioHardware;
+    Mutex   mLock;
+    int     mFd;
+};
+
+class AudioStreamInGeneric : public AudioStreamIn {
+public:
+                        AudioStreamInGeneric() : mAudioHardware(0), mFd(-1) {}
+    virtual             ~AudioStreamInGeneric();
+
+    virtual status_t    set(
+            AudioHardwareGeneric *hw,
+            int mFd,
+            int format,
+            int channelCount,
+            uint32_t sampleRate);
+
+    uint32_t    sampleRate() const { return 8000; }
+    virtual size_t      bufferSize() const { return 320; }
+    virtual int         channelCount() const { return 1; }
+    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);
+
+private:
+    AudioHardwareGeneric *mAudioHardware;
+    Mutex   mLock;
+    int     mFd;
+};
+
+
+class AudioHardwareGeneric : public  AudioHardwareInterface
+{
+public:
+                        AudioHardwareGeneric();
+    virtual             ~AudioHardwareGeneric();
+    virtual status_t    initCheck();
+    virtual status_t    standby();
+    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);
+
+    virtual status_t    setParameter(const char* key, const char* value)
+            { return NO_ERROR; }
+
+    // create I/O streams
+    virtual AudioStreamOut* openOutputStream(
+            int format=0,
+            int channelCount=0,
+            uint32_t sampleRate=0);
+
+    virtual AudioStreamIn* openInputStream(
+            int format,
+            int channelCount,
+            uint32_t sampleRate);
+
+            void            closeOutputStream(AudioStreamOutGeneric* out);
+            void            closeInputStream(AudioStreamInGeneric* in);
+protected:
+    virtual status_t        doRouting() { return NO_ERROR; }
+    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
new file mode 100644
index 0000000..7387b3d
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareInterface.cpp
@@ -0,0 +1,240 @@
+/*
+**
+** 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_TAG "AudioHardwareInterface"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include "AudioHardwareStub.h"
+#include "AudioHardwareGeneric.h"
+
+// #define DUMP_FLINGER_OUT        // if defined allows recording samples in a file
+#ifdef DUMP_FLINGER_OUT
+#include "AudioDumpInterface.h"
+#endif
+
+
+// change to 1 to log routing calls
+#define LOG_ROUTING_CALLS 0
+
+namespace android {
+
+#if LOG_ROUTING_CALLS
+static const char* routingModeStrings[] =
+{
+    "OUT OF RANGE",
+    "INVALID",
+    "CURRENT",
+    "NORMAL",
+    "RINGTONE",
+    "IN_CALL"
+};
+
+static const char* routeStrings[] =
+{
+    "EARPIECE ",
+    "SPEAKER ",
+    "BLUETOOTH ",
+    "HEADSET "
+};
+static const char* routeNone = "NONE";
+
+static const char* displayMode(int mode)
+{
+    if ((mode < -2) || (mode > 2))
+        return routingModeStrings[0];
+    return routingModeStrings[mode+3];
+}
+
+static const char* displayRoutes(uint32_t routes)
+{
+    static char routeStr[80];
+    if (routes == 0)
+        return routeNone;
+    routeStr[0] = 0;
+    int bitMask = 1;
+    for (int i = 0; i < 4; ++i, bitMask <<= 1) {
+        if (routes & bitMask) {
+            strcat(routeStr, routeStrings[i]);
+        }
+    }
+    routeStr[strlen(routeStr)-1] = 0;
+    return routeStr;
+}
+#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 DUMP_FLINGER_OUT
+    // 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 DUMP_FLINGER_OUT and setting environement
+    // "audioflinger.dump = 1". The output file is "tmp/FlingerOut.pcm". Pause are not recorded
+    // in the file.
+    
+    // read dump mode
+    property_get("audioflinger.dump", value, "0");
+    switch(value[0]) {
+    case '1':
+        LOGV("Dump mode");
+        hw = new AudioDumpInterface(hw);    // replace interface
+        return hw;
+        break;
+    case '0':
+    default:
+        LOGV("No Dump mode");
+        return hw;
+        break;
+    }
+#endif
+    return hw;
+}
+
+AudioStreamOut::~AudioStreamOut()
+{
+}
+
+AudioStreamIn::~AudioStreamIn() {}
+
+AudioHardwareInterface::AudioHardwareInterface()
+{
+    // force a routing update on initialization
+    memset(&mRoutes, 0, sizeof(mRoutes));
+    mMode = 0;
+}
+
+// generics for audio routing - the real work is done in doRouting
+status_t AudioHardwareInterface::setRouting(int mode, uint32_t routes)
+{
+#if LOG_ROUTING_CALLS
+    LOGD("setRouting: mode=%s, routes=[%s]", displayMode(mode), displayRoutes(routes));
+#endif
+    if (mode == AudioSystem::MODE_CURRENT)
+        mode = mMode;
+    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
+        return BAD_VALUE;
+    uint32_t old = mRoutes[mode];
+    mRoutes[mode] = routes;
+    if ((mode != mMode) || (old == routes))
+        return NO_ERROR;
+#if LOG_ROUTING_CALLS
+    const char* oldRouteStr = strdup(displayRoutes(old));
+    LOGD("doRouting: mode=%s, old route=[%s], new route=[%s]",
+           displayMode(mode), oldRouteStr, displayRoutes(routes));
+    delete oldRouteStr;
+#endif
+    return doRouting();
+}
+
+status_t AudioHardwareInterface::getRouting(int mode, uint32_t* routes)
+{
+    if (mode == AudioSystem::MODE_CURRENT)
+        mode = mMode;
+    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
+        return BAD_VALUE;
+    *routes = mRoutes[mode];
+#if LOG_ROUTING_CALLS
+    LOGD("getRouting: mode=%s, routes=[%s]",
+           displayMode(mode), displayRoutes(*routes));
+#endif
+    return NO_ERROR;
+}
+
+status_t AudioHardwareInterface::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 NO_ERROR;
+#if LOG_ROUTING_CALLS
+    LOGD("doRouting: old mode=%s, new mode=%s route=[%s]",
+            displayMode(mMode), displayMode(mode), displayRoutes(mRoutes[mode]));
+#endif
+    mMode = mode;
+    return doRouting();
+}
+
+status_t AudioHardwareInterface::getMode(int* mode)
+{
+    // Implement: set audio routing
+    *mode = mMode;
+    return NO_ERROR;
+}
+
+status_t AudioHardwareInterface::setParameter(const char* key, const char* value)
+{
+    // default implementation is to ignore
+    return NO_ERROR;
+}
+
+status_t AudioHardwareInterface::dumpState(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, SIZE, "AudioHardwareInterface::dumpState\n");
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
+    result.append(buffer);
+    for (int i = 0, n = AudioSystem::NUM_MODES; i < n; ++i) {
+        snprintf(buffer, SIZE, "\tmRoutes[%d]: %d\n", i, mRoutes[i]);
+        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
new file mode 100644
index 0000000..0046db8
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -0,0 +1,175 @@
+/* //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"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+AudioHardwareStub::AudioHardwareStub() : mMicMute(false)
+{
+}
+
+AudioHardwareStub::~AudioHardwareStub()
+{
+}
+
+status_t AudioHardwareStub::initCheck()
+{
+    return NO_ERROR;
+}
+
+status_t AudioHardwareStub::standby()
+{
+    return NO_ERROR;
+}
+
+AudioStreamOut* AudioHardwareStub::openOutputStream(
+        int format, int channelCount, uint32_t sampleRate)
+{
+    AudioStreamOutStub* out = new AudioStreamOutStub();
+    if (out->set(format, channelCount, sampleRate) == NO_ERROR)
+        return out;
+    delete out;
+    return 0;
+}
+
+AudioStreamIn* AudioHardwareStub::openInputStream(
+        int format, int channelCount, uint32_t sampleRate)
+{
+    AudioStreamInStub* in = new AudioStreamInStub();
+    if (in->set(format, channelCount, sampleRate) == NO_ERROR)
+        return in;
+    delete in;
+    return 0;
+}
+
+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 format, int channels, uint32_t rate)
+{
+    // fix up defaults
+    if (format == 0) format = AudioSystem::PCM_16_BIT;
+    if (channels == 0) channels = channelCount();
+    if (rate == 0) rate = sampleRate();
+    
+    if ((format == AudioSystem::PCM_16_BIT) &&
+            (channels == channelCount()) &&
+            (rate == sampleRate()))
+        return NO_ERROR;
+    return BAD_VALUE;
+}
+
+ssize_t AudioStreamOutStub::write(const void* buffer, size_t bytes)
+{
+    // fake timing for audio output
+    usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / sampleRate());
+    return bytes;
+}
+
+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, "\tchannel count: %d\n", channelCount());
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR; 
+}
+
+// ----------------------------------------------------------------------------
+
+status_t AudioStreamInStub::set(int format, int channels, uint32_t rate)
+{
+    if ((format == AudioSystem::PCM_16_BIT) &&
+            (channels == channelCount()) &&
+            (rate == sampleRate()))
+        return NO_ERROR;
+    return BAD_VALUE;
+}
+
+ssize_t AudioStreamInStub::read(void* buffer, ssize_t bytes)
+{
+    // fake timing for audio input
+    usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / 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, "\tchannel count: %d\n", channelCount());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "\tformat: %d\n", format());
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
new file mode 100644
index 0000000..1a61552
--- /dev/null
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -0,0 +1,95 @@
+/* //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/AudioHardwareInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioStreamOutStub : public AudioStreamOut {
+public:
+    virtual status_t    set(int format, int channelCount, uint32_t sampleRate);
+    virtual uint32_t    sampleRate() const { return 44100; }
+    virtual size_t      bufferSize() const { return 4096; }
+    virtual int         channelCount() const { return 2; }
+    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
+    virtual status_t    setVolume(float volume) { return NO_ERROR; }
+    virtual ssize_t     write(const void* buffer, size_t bytes);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
+};
+
+class AudioStreamInStub : public AudioStreamIn {
+public:
+    virtual status_t    set(int format, int channelCount, uint32_t sampleRate);
+    virtual uint32_t    sampleRate() const { return 8000; }
+    virtual size_t      bufferSize() const { return 320; }
+    virtual int         channelCount() const { return 1; }
+    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);
+};
+
+class AudioHardwareStub : public  AudioHardwareInterface
+{
+public:
+                        AudioHardwareStub();
+    virtual             ~AudioHardwareStub();
+    virtual status_t    initCheck();
+    virtual status_t    standby();
+    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; }
+
+    virtual status_t    setParameter(const char* key, const char* value)
+            { return NO_ERROR; }
+
+    // create I/O streams
+    virtual AudioStreamOut* openOutputStream(
+                                int format=0,
+                                int channelCount=0,
+                                uint32_t sampleRate=0);
+
+    virtual AudioStreamIn* openInputStream(
+                                int format,
+                                int channelCount,
+                                uint32_t sampleRate);
+
+protected:
+    virtual status_t    doRouting() { return NO_ERROR; }
+    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
new file mode 100644
index 0000000..9f1b17f
--- /dev/null
+++ b/libs/audioflinger/AudioMixer.cpp
@@ -0,0 +1,857 @@
+/* //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"
+
+#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]>>16) >= volume[i])) ||
+            ((volumeInc[i]<0) && ((prevVolume[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;
+}
+
+inline 
+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];
+        t.bufferProvider->getNextBuffer(&t.buffer);
+        if (t.buffer.raw) {
+            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.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)
+            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];
+            (t.hook)(&t, outTemp, BLOCKSIZE, state->resampleTemp);
+        }
+
+        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 {
+            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) {
+                (t.hook)(&t, outTemp, numFrames, state->resampleTemp);
+                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);
+    t.bufferProvider->getNextBuffer(&b);
+    int16_t const *in = t.buffer.i16;
+
+    // in == NULL can happen if the track was flushed just after having
+    // been enabled for mixing.
+    if (in == NULL) {
+        memset(output, 0, state->frameCount*MAX_NUM_CHANNELS*sizeof(int16_t));
+        return;
+    }
+    
+    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;
+    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 (--numFrames);
+    } 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 (--numFrames);
+    }
+
+    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);
+    t0.bufferProvider->getNextBuffer(&b0);
+
+    en &= ~(1<<i);
+    i = 31 - __builtin_clz(en);
+    const track_t& t1 = state->tracks[i];
+    AudioBufferProvider::Buffer& b1(t1.buffer);
+    t1.bufferProvider->getNextBuffer(&b1);
+
+    int16_t const *in0;
+    const int16_t vl0 = t0.volume[0];
+    const int16_t vr0 = t0.volume[1];
+    int16_t const *in1;
+    const int16_t vl1 = t1.volume[0];
+    const int16_t vr1 = t1.volume[1];
+    size_t numFrames = state->frameCount;
+    int32_t* out = static_cast<int32_t*>(output);
+
+    // t0/1.buffer.i16 == NULL can happen if the track was flushed just after having
+    // been enabled for mixing.
+    if (t0.buffer.i16 != NULL) {
+        in0 = t0.buffer.i16;
+        if (t1.buffer.i16 != NULL) {
+            in1 = t1.buffer.i16;
+        } else {
+            in1 = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
+            memset((void *)in1, 0, state->frameCount*MAX_NUM_CHANNELS*sizeof(int16_t));
+        }
+    } else {
+        in0 = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
+        memset((void *)in0, 0, state->frameCount*MAX_NUM_CHANNELS*sizeof(int16_t));
+        if (t1.buffer.i16 != NULL) {
+            in1 = t1.buffer.i16;
+        } else {
+            in1 = in0;
+        }
+    }
+    
+    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 (--numFrames);
+
+    
+    if (t0.buffer.i16 != NULL) {
+        t0.bufferProvider->releaseBuffer(&b0);
+        if (t1.buffer.i16 != NULL) {
+            t1.bufferProvider->releaseBuffer(&b1);
+        } else {
+            delete [] in1;
+        }
+    } else {
+        delete [] in0;
+        if (t1.buffer.i16 != NULL) {
+            t1.bufferProvider->releaseBuffer(&b1);
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/audioflinger/AudioMixer.h b/libs/audioflinger/AudioMixer.h
new file mode 100644
index 0000000..9ca109f
--- /dev/null
+++ b/libs/audioflinger/AudioMixer.h
@@ -0,0 +1,192 @@
+/* //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; }
+
+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    reserved;
+
+        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 ditherAndClamp(int32_t* out, int32_t const *sums, size_t c);
+
+    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/AudioResampler.cpp b/libs/audioflinger/AudioResampler.cpp
new file mode 100644
index 0000000..c93ead3
--- /dev/null
+++ b/libs/audioflinger/AudioResampler.cpp
@@ -0,0 +1,297 @@
+/*
+ * 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 <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 {
+// ----------------------------------------------------------------------------
+
+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);
+    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:
+        resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate);
+        break;
+    case MED_QUALITY:
+        resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
+        break;
+    case HIGH_QUALITY:
+        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.raw = NULL;
+
+    // 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;
+
+    // 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
+        if (mBuffer.raw == NULL) {
+            provider->getNextBuffer(&mBuffer);
+            if (mBuffer.raw == NULL)
+                break;
+            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
+        }
+        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");
+        while (outputIndex < outputSampleCount) {
+            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);
+            if (inputIndex >= mBuffer.frameCount)
+                break;
+        }
+        // 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", inputIndex);
+
+            mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
+            mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
+            provider->releaseBuffer(&mBuffer);
+
+            // verify that the releaseBuffer NULLS the buffer pointer 
+            // LOG_ASSERT(mBuffer.raw == NULL);
+        }
+    }
+
+    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+    // 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;
+
+    // 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
+        if (mBuffer.raw == NULL) {
+            provider->getNextBuffer(&mBuffer);
+            if (mBuffer.raw == NULL)
+                break;
+            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
+        }
+        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");
+        while (outputIndex < outputSampleCount) {
+            int32_t sample = Interp(in[inputIndex-1], in[inputIndex],
+                    phaseFraction);
+            out[outputIndex++] += vl * sample;
+            out[outputIndex++] += vr * sample;
+            Advance(&inputIndex, &phaseFraction, phaseIncrement);
+            if (inputIndex >= mBuffer.frameCount)
+                break;
+        }
+        // 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", inputIndex);
+
+            mX0L = mBuffer.i16[mBuffer.frameCount-1];
+            provider->releaseBuffer(&mBuffer);
+
+            // verify that the releaseBuffer NULLS the buffer pointer 
+            // LOG_ASSERT(mBuffer.raw == NULL);
+        }
+    }
+
+    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
+
+    // save state
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+// ----------------------------------------------------------------------------
+}
+; // namespace android
+
diff --git a/libs/audioflinger/AudioResampler.h b/libs/audioflinger/AudioResampler.h
new file mode 100644
index 0000000..39656c0
--- /dev/null
+++ b/libs/audioflinger/AudioResampler.h
@@ -0,0 +1,93 @@
+/*
+ * 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
new file mode 100644
index 0000000..4f437bf
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerCubic.cpp
@@ -0,0 +1,178 @@
+/*
+ * 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;
+    
+    // fetch first buffer
+    if (mBuffer.raw == NULL) {
+        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);
+                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;
+    
+    // fetch first buffer
+    if (mBuffer.raw == NULL) {
+        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);
+                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
new file mode 100644
index 0000000..b72b62a
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerCubic.h
@@ -0,0 +1,68 @@
+/*
+ * 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
new file mode 100644
index 0000000..e710d16
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerSinc.cpp
@@ -0,0 +1,320 @@
+/*
+ * 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 * int32_t(v))>>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) * int32_t(v))>>16);
+    } else {
+        return a + ((int16_t(inRL>>16) * int32_t(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;
+
+    AudioBufferProvider::Buffer& buffer(mBuffer);
+    while (outputIndex < outputSampleCount) {
+        // buffer is empty, fetch a new one
+        if (buffer.raw == NULL) {
+            provider->getNextBuffer(&buffer);
+            if (buffer.raw == NULL)
+                break;
+    		const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+        	if (phaseIndex) {
+        		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++] = mulRL(1, l, vRL);
+    		out[outputIndex++] = mulRL(0, r, vRL);
+
+        	phaseFraction += phaseIncrement;
+    		const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
+        	if (phaseIndex) {
+        		inputIndex += phaseIndex;
+        		if (inputIndex >= frameCount)
+        			break;
+        		read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
+        	}
+        }
+
+        // if done with buffer, save samples
+        if (inputIndex >= frameCount) {
+            inputIndex -= frameCount;
+            provider->releaseBuffer(&buffer);
+        }
+    }
+
+    mImpulse = impulse;
+    mInputIndex = inputIndex;
+    mPhaseFraction = phaseFraction;
+}
+
+template<int CHANNELS>
+void AudioResamplerSinc::read(
+		int16_t*& impulse, uint32_t& phaseFraction,
+		int16_t const* in, size_t inputIndex)
+{
+	// read new samples into the ring buffer
+	while (phaseFraction >> kNumPhaseBits) {
+		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;
+	
+	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
new file mode 100644
index 0000000..89b9577
--- /dev/null
+++ b/libs/audioflinger/AudioResamplerSinc.h
@@ -0,0 +1,87 @@
+/*
+ * 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;
+    static const int cShift = kNumPhaseBits - coefsBits;
+    static const uint32_t cMask  = ((1<<coefsBits)-1) << cShift;
+
+    // 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;
+    static const uint32_t pMask  = ((1<<pLerpBits)-1) << pShift;
+
+    // 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/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
new file mode 100644
index 0000000..7741456
--- /dev/null
+++ b/libs/surfaceflinger/Android.mk
@@ -0,0 +1,47 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    clz.cpp.arm \
+    DisplayHardware/DisplayHardware.cpp \
+    DisplayHardware/DisplayHardwareBase.cpp \
+    GPUHardware/GPUHardware.cpp \
+    BootAnimation.cpp \
+    BlurFilter.cpp.arm \
+    CPUGauge.cpp \
+    Layer.cpp \
+    LayerBase.cpp \
+    LayerBuffer.cpp \
+    LayerBlur.cpp \
+    LayerBitmap.cpp \
+    LayerDim.cpp \
+    LayerScreenshot.cpp \
+    RFBServer.cpp \
+    SurfaceFlinger.cpp \
+    Tokenizer.cpp \
+    Transform.cpp \
+    VRamHeap.cpp
+
+
+# need "-lrt" on Linux simulator to pick up clock_gettime
+ifeq ($(TARGET_SIMULATOR),true)
+	ifeq ($(HOST_OS),linux)
+		LOCAL_LDLIBS += -lrt
+	endif
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+	libutils \
+	libcutils \
+	libui \
+	libcorecg \
+	libsgl \
+	libpixelflinger \
+	libGLES_CM
+
+LOCAL_C_INCLUDES := \
+	$(call include-path-for, corecg graphics)
+
+LOCAL_MODULE:= libsurfaceflinger
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/surfaceflinger/Barrier.h b/libs/surfaceflinger/Barrier.h
new file mode 100644
index 0000000..e2bcf6a
--- /dev/null
+++ b/libs/surfaceflinger/Barrier.h
@@ -0,0 +1,59 @@
+/*
+ * 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/BlurFilter.cpp b/libs/surfaceflinger/BlurFilter.cpp
new file mode 100644
index 0000000..5dc0ba0
--- /dev/null
+++ b/libs/surfaceflinger/BlurFilter.cpp
@@ -0,0 +1,326 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 <stdint.h>
+#include <utils/Errors.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "clz.h"
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+namespace android {
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
+    return v;
+}
+inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
+    return v;
+}
+#else
+inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
+    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+}
+inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
+    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+}
+#endif
+
+const int BLUR_DITHER_BITS = 6;  // dither weights stored on 6 bits
+const int BLUR_DITHER_ORDER_SHIFT= 3;
+const int BLUR_DITHER_ORDER      = (1<<BLUR_DITHER_ORDER_SHIFT);
+const int BLUR_DITHER_SIZE       = BLUR_DITHER_ORDER * BLUR_DITHER_ORDER;
+const int BLUR_DITHER_MASK       = BLUR_DITHER_ORDER-1;
+
+static const uint8_t gDitherMatrix[BLUR_DITHER_SIZE] = {
+     0, 32,  8, 40,  2, 34, 10, 42,
+    48, 16, 56, 24, 50, 18, 58, 26,
+    12, 44,  4, 36, 14, 46,  6, 38,
+    60, 28, 52, 20, 62, 30, 54, 22,
+     3, 35, 11, 43,  1, 33,  9, 41,
+    51, 19, 59, 27, 49, 17, 57, 25,
+    15, 47,  7, 39, 13, 45,  5, 37,
+    63, 31, 55, 23, 61, 29, 53, 21
+};
+
+
+template <int FACTOR = 0>
+struct BlurColor565
+{
+    typedef uint16_t type;
+    int r, g, b;    
+    inline BlurColor565() { }
+    inline BlurColor565(uint16_t v) {
+        r = v >> 11;
+        g = (v >> 5) & 0x3E;
+        b = v & 0x1F;
+    }
+    inline void clear() { r=g=b=0; }
+    inline uint16_t to(int shift, int last, int dither) const {
+        int R = r;
+        int G = g;
+        int B = b;
+        if  (UNLIKELY(last)) {
+            if (FACTOR>0) {
+                int L = (R+G+B)>>1;
+                R += (((L>>1) - R) * FACTOR) >> 8;
+                G += (((L   ) - G) * FACTOR) >> 8;
+                B += (((L>>1) - B) * FACTOR) >> 8;
+            }
+            R += (dither << shift) >> BLUR_DITHER_BITS;
+            G += (dither << shift) >> BLUR_DITHER_BITS;
+            B += (dither << shift) >> BLUR_DITHER_BITS;
+        }
+        R >>= shift;
+        G >>= shift;
+        B >>= shift;
+        return (R<<11) | (G<<5) | B;
+    }    
+    inline BlurColor565& operator += (const BlurColor565& rhs) {
+        r += rhs.r;
+        g += rhs.g;
+        b += rhs.b;
+        return *this;
+    }
+    inline BlurColor565& operator -= (const BlurColor565& rhs) {
+        r -= rhs.r;
+        g -= rhs.g;
+        b -= rhs.b;
+        return *this;
+    }
+};
+
+struct BlurGray565
+{
+    typedef uint16_t type;
+    int l;    
+    inline BlurGray565() { }
+    inline BlurGray565(uint16_t v) {
+        int r = v >> 11;
+        int g = (v >> 5) & 0x3F;
+        int b = v & 0x1F;
+        l = (r + g + b + 1)>>1;
+    }
+    inline void clear() { l=0; }
+    inline uint16_t to(int shift, int last, int dither) const {
+        int L = l;
+        if  (UNLIKELY(last)) {
+            L += (dither << shift) >> BLUR_DITHER_BITS;
+        }
+        L >>= shift;
+        return ((L>>1)<<11) | (L<<5) | (L>>1);
+    }
+    inline BlurGray565& operator += (const BlurGray565& rhs) {
+        l += rhs.l;
+        return *this;
+    }
+    inline BlurGray565& operator -= (const BlurGray565& rhs) {
+        l -= rhs.l;
+        return *this;
+    }
+};
+
+struct BlurGray8888
+{
+    typedef uint32_t type;
+    int l, a;    
+    inline BlurGray8888() { }
+    inline BlurGray8888(uint32_t v) {
+        v = BLUR_RGBA_TO_HOST(v);
+        int r = v & 0xFF;
+        int g = (v >>  8) & 0xFF;
+        int b = (v >> 16) & 0xFF;
+        a = v >> 24;
+        l = r + g + g + b;
+    }    
+    inline void clear() { l=a=0; }
+    inline uint32_t to(int shift, int last, int dither) const {
+        int L = l;
+        int A = a;
+        if  (UNLIKELY(last)) {
+            L += (dither << (shift+2)) >> BLUR_DITHER_BITS;
+            A += (dither << shift) >> BLUR_DITHER_BITS;
+        }
+        L >>= (shift+2);
+        A >>= shift;
+        return BLUR_HOST_TO_RGBA((A<<24) | (L<<16) | (L<<8) | L);
+    }
+    inline BlurGray8888& operator += (const BlurGray8888& rhs) {
+        l += rhs.l;
+        a += rhs.a;
+        return *this;
+    }
+    inline BlurGray8888& operator -= (const BlurGray8888& rhs) {
+        l -= rhs.l;
+        a -= rhs.a;
+        return *this;
+    }
+};
+
+
+template<typename PIXEL>
+static status_t blurFilter(
+        GGLSurface const* dst,
+        GGLSurface const* src,
+        int kernelSizeUser,
+        int repeat)
+{
+    typedef typename PIXEL::type TYPE;
+
+    const int shift             = 31 - clz(kernelSizeUser);
+    const int areaShift         = shift*2;
+    const int kernelSize        = 1<<shift;
+    const int kernelHalfSize    = kernelSize/2;
+    const int mask              = kernelSize-1;
+    const int w                 = src->width;
+    const int h                 = src->height;
+    const uint8_t* ditherMatrix = gDitherMatrix;
+
+    // we need a temporary buffer to store one line of blurred columns
+    // as well as kernelSize lines of source pixels organized as a ring buffer.
+    void* const temporary_buffer = malloc(
+            (w + kernelSize) * sizeof(PIXEL) +
+            (src->stride * kernelSize) * sizeof(TYPE));
+    if (!temporary_buffer)
+        return NO_MEMORY;
+
+    PIXEL* const sums = (PIXEL*)temporary_buffer;
+    TYPE* const scratch = (TYPE*)(sums + w + kernelSize);
+
+    // Apply the blur 'repeat' times, this is used to approximate
+    // gaussian blurs. 3 times gives good results.
+    for (int k=0 ; k<repeat ; k++) {
+
+        // Clear the columns sums for this round
+        memset(sums, 0, (w + kernelSize) * sizeof(PIXEL));
+        TYPE* head;
+        TYPE pixel;
+        PIXEL current;
+
+        // Since we're going to override the source data we need
+        // to copy it in a temporary buffer. Only kernelSize lines are
+        // required. But since we start in the center of the kernel,
+        // we only copy half of the data, and fill the rest with zeros
+        // (assuming black/transparent pixels).
+        memcpy( scratch + src->stride*kernelHalfSize,
+                src->data,
+                src->stride*kernelHalfSize*sizeof(TYPE));
+
+        // sum half of each column, because we assume the first half is
+        // zeros (black/transparent).
+        for (int y=0 ; y<kernelHalfSize ; y++) {
+            head = (TYPE*)src->data + y*src->stride;
+            for (int x=0 ; x<w ; x++)
+                sums[x] += PIXEL( *head++ );
+        }
+
+        for (int y=0 ; y<h ; y++) {
+            TYPE* fb = (TYPE*)dst->data + y*dst->stride;
+
+            // compute the dither matrix line
+            uint8_t const * ditherY = ditherMatrix
+                    + (y & BLUR_DITHER_MASK)*BLUR_DITHER_ORDER;
+
+            // Horizontal blur pass on the columns sums
+            int count, dither, x=0;
+            PIXEL const * out= sums;
+            PIXEL const * in = sums;
+            current.clear();
+
+            count = kernelHalfSize;
+            do {
+                current += *in;
+                in++;
+            } while (--count);
+            
+            count = kernelHalfSize;
+            do {
+                current += *in;
+                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
+                *fb++ = current.to(areaShift, k==repeat-1, dither);
+                in++;
+            } while (--count);
+
+            count = w-kernelSize;
+            do {
+                current += *in;
+                current -= *out;
+                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
+                *fb++ = current.to(areaShift, k==repeat-1, dither);
+                in++, out++;
+            } while (--count);
+
+            count = kernelHalfSize;
+            do {
+                current -= *out;
+                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
+                *fb++ = current.to(areaShift, k==repeat-1, dither);
+                out++;
+            } while (--count);
+
+            // vertical blur pass, subtract the oldest line from each columns
+            // and add a new line. Subtract or add zeros at the top
+            // and bottom edges.
+            TYPE* const tail = scratch + (y & mask) * src->stride;
+            if (y >= kernelHalfSize) {
+                for (int x=0 ; x<w ; x++)
+                    sums[x] -= PIXEL( tail[x] );
+            }
+            if (y < h-kernelSize) {
+                memcpy( tail,
+                        (TYPE*)src->data + (y+kernelHalfSize)*src->stride,
+                        src->stride*sizeof(TYPE));
+                for (int x=0 ; x<w ; x++)
+                    sums[x] += PIXEL( tail[x] );
+            }
+        }
+
+        // The subsequent passes are always done in-place.
+        src = dst;
+    }
+    
+    free(temporary_buffer);
+
+    return NO_ERROR;
+}
+
+template status_t blurFilter< BlurColor565<0x80> >(
+        GGLSurface const* dst,
+        GGLSurface const* src,
+        int kernelSizeUser,
+        int repeat);
+
+status_t blurFilter(
+        GGLSurface const* image,
+        int kernelSizeUser,
+        int repeat)
+{
+    return blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat);
+}
+
+} // namespace android
+
+//err = blur< BlurColor565<0x80> >(dst, src, kernelSizeUser, repeat);
+//err = blur<BlurGray565>(dst, src, kernelSizeUser, repeat);
+//err = blur<BlurGray8888>(dst, src, kernelSizeUser, repeat);
diff --git a/libs/surfaceflinger/BlurFilter.h b/libs/surfaceflinger/BlurFilter.h
new file mode 100644
index 0000000..294db43
--- /dev/null
+++ b/libs/surfaceflinger/BlurFilter.h
@@ -0,0 +1,35 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_BLUR_FILTER_H
+#define ANDROID_BLUR_FILTER_H
+
+#include <stdint.h>
+#include <utils/Errors.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+namespace android {
+
+status_t blurFilter(
+        GGLSurface const* image,
+        int kernelSizeUser,
+        int repeat);
+
+} // namespace android
+
+#endif // ANDROID_BLUR_FILTER_H
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
new file mode 100644
index 0000000..e9e34c3
--- /dev/null
+++ b/libs/surfaceflinger/BootAnimation.cpp
@@ -0,0 +1,424 @@
+/*
+ * 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 "BootAnimation"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <math.h>
+#include <fcntl.h>
+#include <utils/misc.h>
+
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/AssetManager.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/DisplayInfo.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+#include <ui/EGLNativeWindowSurface.h>
+
+#include <graphics/SkBitmap.h>
+#include <graphics/SkImageDecoder.h>
+
+#include <GLES/egl.h>
+
+#include "BootAnimation.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+BootAnimation::BootAnimation(const sp<ISurfaceComposer>& composer)
+:   Thread(false)
+{
+    mSession = SurfaceComposerClient::clientForConnection(
+            composer->createConnection()->asBinder());
+}
+
+BootAnimation::~BootAnimation()
+{
+}
+
+void BootAnimation::onFirstRef()
+{
+    run("BootAnimation", PRIORITY_DISPLAY);
+}
+
+const sp<SurfaceComposerClient>& BootAnimation::session() const 
+{
+    return mSession;
+}
+
+status_t BootAnimation::initTexture(
+        Texture* texture, AssetManager& assets, const char* name)
+{
+    Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
+    if (!asset) return NO_INIT;
+    SkBitmap bitmap;
+    SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
+            &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
+    asset->close();
+    delete asset;
+
+    // ensure we can call getPixels(). No need to call unlock, since the
+    // bitmap will go out of scope when we return from this method.
+    bitmap.lockPixels();
+
+    const int w = bitmap.width();
+    const int h = bitmap.height();    
+    const void* p = bitmap.getPixels();
+    
+    GLint crop[4] = { 0, h, w, -h };
+    texture->w = w;
+    texture->h = h;
+
+    glGenTextures(1, &texture->name);
+    glBindTexture(GL_TEXTURE_2D, texture->name);
+    
+    switch(bitmap.getConfig()) {
+        case SkBitmap::kA8_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0,
+                    GL_ALPHA, GL_UNSIGNED_BYTE, p);
+            break;
+        case SkBitmap::kARGB_4444_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0,
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, p);
+            break;
+        case SkBitmap::kARGB_8888_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0,
+                    GL_RGBA, GL_UNSIGNED_BYTE, p);
+            break;
+        case SkBitmap::kRGB_565_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
+            break;
+        default:
+            break;
+    }
+
+    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    return NO_ERROR;
+}
+
+status_t BootAnimation::readyToRun()
+{
+    mAssets.addDefaultAssets();
+
+    DisplayInfo dinfo;
+    status_t status = session()->getDisplayInfo(0, &dinfo);
+    if (status)
+        return -1;
+
+    // create the native surface
+    sp<Surface> s = session()->createSurface(getpid(), 0, 
+            dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
+    session()->openTransaction();
+    s->setLayer(0x40000000);
+    session()->closeTransaction();
+
+    // initialize opengl and egl
+    const EGLint attribs[] = {
+            EGL_RED_SIZE,       5,
+            EGL_GREEN_SIZE,     6,
+            EGL_BLUE_SIZE,      5,
+            EGL_DEPTH_SIZE,     0,
+            EGL_NONE
+    };
+    EGLint w, h, dummy;
+    EGLint numConfigs;
+    EGLConfig config;
+    EGLSurface surface;
+    EGLContext context;
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(display, NULL, NULL);
+    eglChooseConfig(display, attribs, &config, 1, &numConfigs);
+
+    surface = eglCreateWindowSurface(
+            display, config, new EGLNativeWindowSurface(s), NULL);
+    
+    context = eglCreateContext(display, config, NULL, NULL);
+    eglQuerySurface(display, surface, EGL_WIDTH, &w);
+    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
+    eglMakeCurrent(display, surface, surface, context);
+    mDisplay = display;
+    mContext = context;
+    mSurface = surface;
+    mWidth = w;
+    mHeight= h;
+    mFlingerSurface = s;
+
+    // initialize GL
+    glShadeModel(GL_FLAT);
+    glEnable(GL_DITHER);
+    glEnable(GL_TEXTURE_2D);
+    glEnable(GL_SCISSOR_TEST);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    return NO_ERROR;
+}
+
+void BootAnimation::requestExit()
+{
+    mBarrier.open();
+    Thread::requestExit();
+}
+
+bool BootAnimation::threadLoop()
+{
+    bool r = android();
+    eglMakeCurrent(mDisplay, 0, 0, 0);
+    eglDestroyContext(mDisplay, mContext);    
+    eglDestroySurface(mDisplay, mSurface);
+    eglTerminate(mDisplay);
+    return r;
+}
+
+
+bool BootAnimation::android()
+{
+    initTexture(&mAndroid[0], mAssets, "images/android_320x480.png");
+    initTexture(&mAndroid[1], mAssets, "images/boot_robot.png");
+    initTexture(&mAndroid[2], mAssets, "images/boot_robot_glow.png");
+
+    // erase screen
+    glDisable(GL_SCISSOR_TEST);
+    glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
+
+    // clear screen
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(mDisplay, mSurface);
+
+    // wait ~1s
+    usleep(800000);
+
+    // fade in
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    const int steps = 8;
+    for (int i=1 ; i<steps ; i++) {
+        float fade = i / float(steps);
+        glColor4f(1, 1, 1, fade*fade);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
+        eglSwapBuffers(mDisplay, mSurface);
+    }
+
+    // draw last frame
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glDisable(GL_BLEND);
+    glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
+    eglSwapBuffers(mDisplay, mSurface);
+    
+    
+    // update rect for the robot
+    const int x = mWidth - mAndroid[1].w - 33;
+    const int y = (mHeight - mAndroid[1].h)/2 - 1;
+    const Rect updateRect(x, y, x+mAndroid[1].w, y+mAndroid[1].h);
+
+    // draw and update only what we need
+    eglSwapRectangleANDROID(mDisplay, mSurface,
+            updateRect.left, updateRect.top, 
+            updateRect.width(), updateRect.height());
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(updateRect.left, mHeight-updateRect.bottom,
+            updateRect.width(), updateRect.height()); 
+
+    const nsecs_t startTime = systemTime();
+    do
+    {
+        // glow speed and shape
+        nsecs_t time = systemTime() - startTime;
+        float t = ((4.0f/(360.0f*us2ns(16667))) * time);
+        t = t - floorf(t);
+        const float fade = 0.5f + 0.5f*sinf(t * 2*M_PI);
+
+        // fade the glow in and out
+        glDisable(GL_BLEND);
+        glBindTexture(GL_TEXTURE_2D, mAndroid[2].name);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+        glColor4f(fade, fade, fade, fade);
+        glDrawTexiOES(updateRect.left, mHeight-updateRect.bottom, 0,
+                updateRect.width(), updateRect.height());
+
+        // draw the robot
+        glEnable(GL_BLEND);
+        glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        glDrawTexiOES(updateRect.left, mHeight-updateRect.bottom, 0,
+                updateRect.width(), updateRect.height());
+
+        // make sure sleep a lot to not take too much CPU away from 
+        // the boot process. With this "glow" animation there is no
+        // visible difference. 
+        usleep(16667*4);
+
+        eglSwapBuffers(mDisplay, mSurface);
+    } while (!exitPending());
+    
+    
+    glDeleteTextures(1, &mAndroid[0].name);
+    glDeleteTextures(1, &mAndroid[1].name);
+    glDeleteTextures(1, &mAndroid[2].name);
+    return false;
+}
+
+
+bool BootAnimation::cylon()
+{
+    // initialize the textures...
+    initTexture(&mLeftTrail,  mAssets, "images/cylon_left.png");
+    initTexture(&mRightTrail, mAssets, "images/cylon_right.png");
+    initTexture(&mBrightSpot, mAssets, "images/cylon_dot.png");
+
+    int w = mWidth;
+    int h = mHeight;
+
+    const Point c(w/2 , h/2);
+    const GLint amplitude = 60;
+    const int scx = c.x - amplitude - mBrightSpot.w/2;
+    const int scy = c.y - mBrightSpot.h/2;
+    const int scw = amplitude*2 + mBrightSpot.w;
+    const int sch = mBrightSpot.h;
+    const Rect updateRect(scx, h-scy-sch, scx+scw, h-scy);
+
+    // erase screen
+    glDisable(GL_SCISSOR_TEST);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapBuffers(mDisplay, mSurface);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapRectangleANDROID(mDisplay, mSurface,
+            updateRect.left, updateRect.top, 
+            updateRect.width(), updateRect.height());
+
+    glEnable(GL_SCISSOR_TEST);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+
+    // clear the screen to white
+    Point p;
+    float t = 0;
+    float alpha = 1.0f;
+    const nsecs_t startTime = systemTime();
+    nsecs_t fadeTime = 0;
+    
+    do
+    {
+        // Set scissor in interesting area
+        glScissor(scx, scy, scw, sch); 
+
+        // erase screen
+        glClear(GL_COLOR_BUFFER_BIT);
+
+
+        // compute wave
+        const float a = (t * 2*M_PI) - M_PI/2;
+        const float sn = sinf(a);
+        const float cs = cosf(a);
+        GLint x = GLint(amplitude * sn);
+        float derivative = cs;
+
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+        if (derivative > 0) {
+            // vanishing trail...
+            p.x = (-amplitude + c.x) - mBrightSpot.w/2;
+            p.y = c.y-mLeftTrail.h/2;
+            float fade = 2.0f*(0.5f-t);
+            //fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
+
+            // trail...
+            p.x = (x + c.x) - (mRightTrail.w + mBrightSpot.w/2) + 16;
+            p.y = c.y-mRightTrail.h/2;
+            fade = t<0.25f ? t*4.0f : 1.0f;
+            fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
+        } else { 
+            // vanishing trail..
+            p.x = (amplitude + c.x) - (mRightTrail.w + mBrightSpot.w/2) + 16;
+            p.y = c.y-mRightTrail.h/2;
+            float fade = 2.0f*(0.5f-(t-0.5f));
+            //fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
+
+            // trail...
+            p.x = (x + c.x) - mBrightSpot.w/2;
+            p.y = c.y-mLeftTrail.h/2;
+            fade = t<0.5f+0.25f ? (t-0.5f)*4.0f : 1.0f;
+            fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
+        }
+
+        const Point p( x + c.x-mBrightSpot.w/2, c.y-mBrightSpot.h/2 );
+        glBindTexture(GL_TEXTURE_2D, mBrightSpot.name);
+        glColor4f(1,0.5,0.5,1);
+        glDrawTexiOES(p.x, p.y, 0, mBrightSpot.w, mBrightSpot.h);
+
+        // update animation
+        nsecs_t time = systemTime() - startTime;
+        t = ((4.0f/(360.0f*us2ns(16667))) * time);
+        t = t - floorf(t);
+
+        eglSwapBuffers(mDisplay, mSurface);
+
+        if (exitPending()) {
+            if (fadeTime == 0) {
+                fadeTime = time;
+            }
+            time -= fadeTime;
+            alpha = 1.0f - ((float(time) * 6.0f) / float(s2ns(1)));
+
+            session()->openTransaction();
+            mFlingerSurface->setAlpha(alpha*alpha);
+            session()->closeTransaction();
+        }
+    } while (alpha > 0);
+
+    // cleanup
+    glFinish();
+    glDeleteTextures(1, &mLeftTrail.name);
+    glDeleteTextures(1, &mRightTrail.name);
+    glDeleteTextures(1, &mBrightSpot.name);
+    return false;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h
new file mode 100644
index 0000000..a4a6d49
--- /dev/null
+++ b/libs/surfaceflinger/BootAnimation.h
@@ -0,0 +1,84 @@
+/*
+ * 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_BOOTANIMATION_H
+#define ANDROID_BOOTANIMATION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+#include <utils/AssetManager.h>
+
+#include <ui/ISurfaceComposer.h>
+#include <ui/SurfaceComposerClient.h>
+
+#include <GLES/egl.h>
+
+#include "Barrier.h"
+
+class SkBitmap;
+
+namespace android {
+
+class AssetManager;
+
+// ---------------------------------------------------------------------------
+
+class BootAnimation : public Thread
+{
+public:
+                BootAnimation(const sp<ISurfaceComposer>& composer);
+    virtual     ~BootAnimation();
+
+    const sp<SurfaceComposerClient>& session() const;
+    virtual void        requestExit();
+
+private:
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+    struct Texture {
+        GLint   w;
+        GLint   h;
+        GLuint  name;
+    };
+
+    status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
+    bool android();
+    bool cylon();
+
+    sp<SurfaceComposerClient>       mSession;
+    AssetManager mAssets;
+    Texture mLeftTrail;
+    Texture mRightTrail;
+    Texture mBrightSpot;
+    Texture mAndroid[3];
+    int     mWidth;
+    int     mHeight;
+    EGLDisplay  mDisplay;
+    EGLDisplay  mContext;
+    EGLDisplay  mSurface;
+    sp<Surface> mFlingerSurface;
+    Barrier mBarrier;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_BOOTANIMATION_H
diff --git a/libs/surfaceflinger/CPUGauge.cpp b/libs/surfaceflinger/CPUGauge.cpp
new file mode 100644
index 0000000..74a9270
--- /dev/null
+++ b/libs/surfaceflinger/CPUGauge.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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 "CPUGauge"
+
+#include <stdint.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <math.h>
+
+#include <utils/threads.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/DisplayInfo.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "CPUGauge.h"
+
+namespace android {
+
+CPUGauge::CPUGauge( const sp<ISurfaceComposer>& composer,
+                    nsecs_t interval,
+                    int clock,
+                    int refclock)
+    :   Thread(false), 
+        mInterval(interval), mClock(clock), mRefClock(refclock),
+        mReferenceTime(0),
+        mReferenceWorkingTime(0), mCpuUsage(0),
+        mRefIdleTime(0), mIdleTime(0)
+{
+    mFd = fopen("/proc/stat", "r");
+    setvbuf(mFd, NULL, _IONBF, 0);
+
+    mSession = SurfaceComposerClient::clientForConnection(
+        composer->createConnection()->asBinder());
+}
+
+CPUGauge::~CPUGauge()
+{
+    fclose(mFd);
+}
+
+const sp<SurfaceComposerClient>& CPUGauge::session() const 
+{
+    return mSession;
+}
+
+void CPUGauge::onFirstRef()
+{
+    run("CPU Gauge");
+}
+
+status_t CPUGauge::readyToRun()
+{
+    LOGI("Starting CPU gauge...");
+    return NO_ERROR;
+}
+
+bool CPUGauge::threadLoop()
+{
+    DisplayInfo dinfo;
+    session()->getDisplayInfo(0, &dinfo);
+    sp<Surface> s(session()->createSurface(getpid(), 0, dinfo.w, 4, PIXEL_FORMAT_OPAQUE));
+    session()->openTransaction();
+    s->setLayer(INT_MAX);
+    session()->closeTransaction();
+    
+    static const GGLfixed colors[4][4] = {
+            { 0x00000, 0x10000, 0x00000, 0x10000 },
+            { 0x10000, 0x10000, 0x00000, 0x10000 },
+            { 0x10000, 0x00000, 0x00000, 0x10000 },
+            { 0x00000, 0x00000, 0x00000, 0x10000 },
+        };
+
+    GGLContext* gl;
+    gglInit(&gl);
+    gl->activeTexture(gl, 0);
+    gl->disable(gl, GGL_TEXTURE_2D);
+    gl->disable(gl, GGL_BLEND);
+
+    const int w = dinfo.w;
+
+    while(!exitPending())
+    {
+        mLock.lock();
+            const float cpuUsage = this->cpuUsage();
+            const float totalCpuUsage = 1.0f - idle();
+        mLock.unlock();
+
+        Surface::SurfaceInfo info;
+        s->lock(&info);
+            GGLSurface fb;
+                fb.version = sizeof(GGLSurface);
+                fb.width   = info.w;
+                fb.height  = info.h;
+                fb.stride  = info.w;
+                fb.format  = info.format;
+                fb.data = (GGLubyte*)info.bits;
+
+            gl->colorBuffer(gl, &fb);
+            gl->color4xv(gl, colors[3]);
+            gl->recti(gl, 0, 0, w, 4);
+            gl->color4xv(gl, colors[2]); // red
+            gl->recti(gl, 0, 0, int(totalCpuUsage*w), 2);
+            gl->color4xv(gl, colors[0]); // green
+            gl->recti(gl, 0, 2, int(cpuUsage*w), 4);
+        
+        s->unlockAndPost(); 
+
+        usleep(ns2us(mInterval));
+    }
+
+    gglUninit(gl);
+    return false;
+}
+
+void CPUGauge::sample()
+{
+    if (mLock.tryLock() == NO_ERROR) {
+        const nsecs_t now = systemTime(mRefClock);
+        const nsecs_t referenceTime = now-mReferenceTime;
+        if (referenceTime >= mInterval) {
+            const float reftime = 1.0f / referenceTime;
+            const nsecs_t nowWorkingTime = systemTime(mClock);
+            
+            char buf[256];
+            fgets(buf, 256, mFd);
+            rewind(mFd);
+            char *str = buf+5;
+            char const * const usermode = strsep(&str, " ");  (void)usermode;
+            char const * const usernice = strsep(&str, " ");  (void)usernice;
+            char const * const systemmode = strsep(&str, " ");(void)systemmode;
+            char const * const idle = strsep(&str, " ");
+            const nsecs_t nowIdleTime = atoi(idle) * 10000000LL;
+            mIdleTime = float(nowIdleTime - mRefIdleTime) * reftime;
+            mRefIdleTime = nowIdleTime;
+            
+            const nsecs_t workingTime = nowWorkingTime - mReferenceWorkingTime;
+            const float newCpuUsage = float(workingTime) * reftime;
+            if (mCpuUsage != newCpuUsage) {        
+                mCpuUsage = newCpuUsage;
+                mReferenceWorkingTime = nowWorkingTime;
+                mReferenceTime = now;
+            }
+        }
+        mLock.unlock();
+    }
+}
+
+
+}; // namespace android
diff --git a/libs/surfaceflinger/CPUGauge.h b/libs/surfaceflinger/CPUGauge.h
new file mode 100644
index 0000000..5bb53c0
--- /dev/null
+++ b/libs/surfaceflinger/CPUGauge.h
@@ -0,0 +1,74 @@
+/*
+ * 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_CPUGAUGE_H
+#define ANDROID_CPUGAUGE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Timers.h>
+
+#include <ui/SurfaceComposerClient.h>
+
+namespace android {
+
+class CPUGauge : public Thread
+{
+public:
+    CPUGauge(   const sp<ISurfaceComposer>& composer,
+                nsecs_t interval=s2ns(1),
+                int clock=SYSTEM_TIME_THREAD,
+                int refclock=SYSTEM_TIME_MONOTONIC);
+                
+    ~CPUGauge();
+
+    const sp<SurfaceComposerClient>& session() const;
+
+    void sample();
+ 
+    inline float cpuUsage() const { return mCpuUsage; }
+    inline float idle() const { return mIdleTime; }
+
+private:
+    virtual void        onFirstRef();
+    virtual status_t    readyToRun();
+    virtual bool        threadLoop();
+
+    Mutex mLock;
+
+    sp<SurfaceComposerClient> mSession;
+
+    const nsecs_t mInterval;
+    const int mClock;
+    const int mRefClock;
+
+    nsecs_t mReferenceTime;
+    nsecs_t mReferenceWorkingTime;
+    float mCpuUsage;
+    nsecs_t mRefIdleTime;
+    float mIdleTime;
+    FILE*   mFd;
+};
+
+
+}; // namespace android
+
+#endif // ANDROID_CPUGAUGE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
new file mode 100644
index 0000000..5dd9446
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -0,0 +1,335 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <GLES/egl.h>
+
+#include <utils/Log.h>
+
+#include <ui/EGLDisplaySurface.h>
+
+#include "DisplayHardware/DisplayHardware.h"
+#include "ui/BlitHardware.h"
+
+using namespace android;
+
+static __attribute__((noinline))
+const char *egl_strerror(EGLint err)
+{
+    switch (err){
+        case EGL_SUCCESS:           return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
+        case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
+        case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
+        case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
+        case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
+        case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
+        default: return "UNKNOWN";
+    }
+}
+
+static __attribute__((noinline))
+void checkGLErrors()
+{
+    GLenum error = glGetError();
+    if (error != GL_NO_ERROR)
+        LOGE("GL error 0x%04x", int(error));
+}
+
+static __attribute__((noinline))
+void checkEGLErrors(const char* token)
+{
+    EGLint error = eglGetError();
+    // GLESonGL seems to be returning 0 when there is no errors?
+    if (error && error != EGL_SUCCESS)
+        LOGE("%s error 0x%04x (%s)",
+                token, int(error), egl_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::getRefreshRate() const    { return mRefreshRate; }
+
+int DisplayHardware::getWidth() const {
+    return mWidth;
+}
+int DisplayHardware::getHeight() const {
+    return mHeight;
+}
+PixelFormat DisplayHardware::getFormat() const {
+    return mFormat;
+}
+
+void DisplayHardware::init(uint32_t dpy)
+{
+    // initialize EGL
+    const EGLint attribs[] = {
+            EGL_RED_SIZE,       5,
+            EGL_GREEN_SIZE,     6,
+            EGL_BLUE_SIZE,      5,
+            EGL_DEPTH_SIZE,     0,
+            EGL_NONE
+    };
+    EGLint w, h, dummy;
+    EGLint numConfigs, n;
+    EGLConfig config;
+    EGLSurface surface;
+    EGLContext context;
+    mFlags = 0;
+
+    // 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);
+    eglChooseConfig(display, attribs, &config, 1, &n);
+
+    /*
+     * Gather EGL extensions
+     */
+
+    const char* const egl_extensions = eglQueryString(
+            display, EGL_EXTENSIONS);
+    
+    const char* egl_extensions_config = egl_extensions;
+    
+    if (strstr(egl_extensions, "EGL_ANDROID_query_string_config")) {
+        egl_extensions_config = eglQueryStringConfigANDROID(
+                display, config, 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("ext/config: %s", egl_extensions_config);
+    LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
+
+    if (strstr(egl_extensions_config, "EGL_ANDROID_swap_rectangle")) {
+        mFlags |= SWAP_RECTANGLE_EXTENSION;
+        // TODO: get the real "update_on_demand" behavior
+        mFlags |= UPDATE_ON_DEMAND;
+    }
+    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
+        if (dummy == EGL_SLOW_CONFIG)
+            mFlags |= SLOW_CONFIG;
+    }
+
+    /*
+     * Create our main surface
+     */
+
+    mDisplaySurface = new EGLDisplaySurface();
+
+    surface = eglCreateWindowSurface(display, config, mDisplaySurface.get(), NULL);
+    //checkEGLErrors("eglCreateDisplaySurfaceANDROID");
+
+    if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
+        if (dummy == EGL_BUFFER_PRESERVED) {
+            mFlags |= BUFFER_PRESERVED;
+            if (strstr(egl_extensions_config, "EGL_ANDROID_copy_front_to_back")) {
+                mFlags |= COPY_BACK_EXTENSION;
+            }
+        }
+    }
+    
+    GLint value = EGL_UNKNOWN;
+    eglQuerySurface(display, surface, EGL_HORIZONTAL_RESOLUTION, &value);
+    if (value == EGL_UNKNOWN) {
+        mDpiX = 160.0f;
+    } else {
+        mDpiX = 25.4f * float(value)/EGL_DISPLAY_SCALING;
+    }
+    value = EGL_UNKNOWN;
+    eglQuerySurface(display, surface, EGL_VERTICAL_RESOLUTION, &value);
+    if (value == EGL_UNKNOWN) {
+        mDpiY = 160.0f;
+    } else {
+        mDpiY = 25.4f * float(value)/EGL_DISPLAY_SCALING;
+    }
+    mRefreshRate = 60.f;    // TODO: get the real refresh rate 
+
+    /*
+     * Create our OpenGL ES context
+     */
+    
+    context = eglCreateContext(display, config, NULL, NULL);
+    //checkEGLErrors("eglCreateContext");
+    
+    eglQuerySurface(display, surface, EGL_WIDTH, &mWidth);
+    eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
+    
+    
+    /*
+     * Gather OpenGL ES extensions
+     */
+
+    eglMakeCurrent(display, surface, surface, context);
+    const char* const  gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
+    LOGI("OpenGL informations:");
+    LOGI("vendor    : %s", glGetString(GL_VENDOR));
+    LOGI("renderer  : %s", glGetString(GL_RENDERER));
+    LOGI("version   : %s", glGetString(GL_VERSION));
+    LOGI("extensions: %s", gl_extensions);
+
+    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;
+    }
+    if (strstr(gl_extensions, "GL_ANDROID_direct_texture")) {
+        mFlags |= DIRECT_TEXTURE;
+    }
+
+    // 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  = GGL_PIXEL_FORMAT_RGB_565;
+
+    mBlitEngine = copybit_init();
+}
+
+/*
+ * 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);
+    copybit_term(mBlitEngine);
+}
+
+void DisplayHardware::releaseScreen() const
+{
+    DisplayHardwareBase::releaseScreen();
+}
+
+void DisplayHardware::acquireScreen() const
+{
+    DisplayHardwareBase::acquireScreen();
+}
+
+void DisplayHardware::getDisplaySurface(copybit_image_t* img) const
+{
+    img->w      = mDisplaySurface->stride;
+    img->h      = mDisplaySurface->height;
+    img->format = mDisplaySurface->format;
+    img->offset = mDisplaySurface->offset;
+    img->base   = (void*)mDisplaySurface->base;
+    img->fd     = mDisplaySurface->fd;
+}
+
+void DisplayHardware::getDisplaySurface(GGLSurface* fb) const
+{
+    fb->version= sizeof(GGLSurface);
+    fb->width  = mDisplaySurface->width;
+    fb->height = mDisplaySurface->height;
+    fb->stride = mDisplaySurface->stride;
+    fb->format = mDisplaySurface->format;
+    fb->data   = (GGLubyte*)mDisplaySurface->base + mDisplaySurface->offset;
+}
+
+uint32_t DisplayHardware::getPageFlipCount() const {
+    return mDisplaySurface->getPageFlipCount();
+}
+
+/*
+ * "Flip" the front and back buffers.
+ */
+
+void DisplayHardware::flip(const Region& dirty) const
+{
+    checkGLErrors();
+
+    EGLDisplay dpy = mDisplay;
+    EGLSurface surface = mSurface;
+
+    Region newDirty(dirty);
+    newDirty.andSelf(Rect(mWidth, mHeight));
+
+    if (mFlags & BUFFER_PRESERVED) {
+        const Region copyback(mDirty.subtract(newDirty));
+        mDirty = newDirty;
+        mDisplaySurface->copyFrontToBack(copyback);
+    } 
+
+    if (mFlags & SWAP_RECTANGLE_EXTENSION) {
+        const Rect& b(newDirty.bounds());
+        eglSwapRectangleANDROID(
+                dpy, surface,
+                b.left, b.top, b.width(), b.height());
+    }
+
+    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
new file mode 100644
index 0000000..299e236
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -0,0 +1,105 @@
+/*
+ * 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/egl.h>
+
+#include "DisplayHardware/DisplayHardwareBase.h"
+
+struct copybit_image_t;
+struct copybit_t;
+
+namespace android {
+
+class EGLDisplaySurface;
+
+class DisplayHardware : public DisplayHardwareBase
+{
+public:
+    enum {
+        COPY_BACK_EXTENSION     = 0x00000001,
+        DIRECT_TEXTURE          = 0x00000002,
+        SWAP_RECTANGLE_EXTENSION= 0x00000004,
+        COPY_BITS_EXTENSION     = 0x00000008,
+        NPOT_EXTENSION          = 0x00000100,
+        DRAW_TEXTURE_EXTENSION  = 0x00000200,
+        BUFFER_PRESERVED        = 0x00010000,
+        UPDATE_ON_DEMAND        = 0x00020000,   // video driver feature
+        SLOW_CONFIG             = 0x00040000,   // software
+    };
+
+    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;
+    int         getWidth() const;
+    int         getHeight() const;
+    PixelFormat getFormat() const;
+    uint32_t    getFlags() const;
+    void        makeCurrent() const;
+
+    uint32_t getPageFlipCount() const;
+    void getDisplaySurface(copybit_image_t* img) const;
+    void getDisplaySurface(GGLSurface* fb) const;
+    EGLDisplay getEGLDisplay() const { return mDisplay; }
+    copybit_t* getBlitEngine() const { return mBlitEngine; }
+    
+    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;
+    int             mWidth;
+    int             mHeight;
+    PixelFormat     mFormat;
+    uint32_t        mFlags;
+    mutable Region  mDirty;
+    sp<EGLDisplaySurface> mDisplaySurface;
+    copybit_t*      mBlitEngine;
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_HARDWARE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
new file mode 100644
index 0000000..90f6287
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
@@ -0,0 +1,395 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+#include <linux/unistd.h>
+
+#include <utils/Log.h>
+
+#include "DisplayHardware/DisplayHardwareBase.h"
+#include "SurfaceFlinger.h"
+
+// ----------------------------------------------------------------------------
+// the sim build doesn't have gettid
+
+#ifndef HAVE_GETTID
+# define gettid getpid
+#endif
+
+// ----------------------------------------------------------------------------
+namespace android {
+
+static char const * const kSleepFileName = "/sys/android_power/wait_for_fb_sleep";
+static char const * const kWakeFileName = "/sys/android_power/wait_for_fb_wake";
+
+// This dir exists if the framebuffer console is present, either built into
+// the kernel or loaded as a module.
+static char const * const kFbconSysDir = "/sys/class/graphics/fbcon";
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase(
+        const sp<SurfaceFlinger>& flinger)
+    : Thread(false), mFlinger(flinger) {
+}
+
+DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() {
+}
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayEventThread::DisplayEventThread(
+        const sp<SurfaceFlinger>& flinger)
+    : DisplayEventThreadBase(flinger)
+{
+}
+
+DisplayHardwareBase::DisplayEventThread::~DisplayEventThread()
+{
+}
+
+bool DisplayHardwareBase::DisplayEventThread::threadLoop()
+{
+    int err = 0;
+    char buf;
+    int fd;
+
+    fd = open(kSleepFileName, O_RDONLY, 0);
+    do {
+      err = read(fd, &buf, 1);
+    } while (err < 0 && errno == EINTR);
+    close(fd);
+    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
+    if (err >= 0) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        LOGD("About to give-up screen, flinger = %p", flinger.get());
+        if (flinger != 0) {
+            mBarrier.close();
+            flinger->screenReleased(0);
+            mBarrier.wait();
+        }
+    }
+    fd = open(kWakeFileName, O_RDONLY, 0);
+    do {
+      err = read(fd, &buf, 1);
+    } while (err < 0 && errno == EINTR);
+    close(fd);
+    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
+    if (err >= 0) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        LOGD("Screen about to return, flinger = %p", flinger.get());
+        if (flinger != 0)
+            flinger->screenAcquired(0);
+    }
+    return true;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const
+{
+    mBarrier.open();
+    return NO_ERROR;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::readyToRun()
+{
+    if (access(kSleepFileName, R_OK) || access(kWakeFileName, R_OK)) {
+        LOGE("Couldn't open %s or %s", kSleepFileName, kWakeFileName);
+        return NO_INIT;
+    }
+    return NO_ERROR;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::initCheck() const
+{
+    return (access(kSleepFileName, R_OK) == 0 &&
+            access(kWakeFileName, R_OK) == 0 &&
+            access(kFbconSysDir, F_OK) != 0) ? NO_ERROR : NO_INIT;
+}
+
+// ----------------------------------------------------------------------------
+
+pid_t DisplayHardwareBase::ConsoleManagerThread::sSignalCatcherPid = 0;
+
+DisplayHardwareBase::ConsoleManagerThread::ConsoleManagerThread(
+        const sp<SurfaceFlinger>& flinger)
+    : DisplayEventThreadBase(flinger), consoleFd(-1)
+{   
+    sSignalCatcherPid = 0;
+
+    // create a new console
+    char const * const ttydev = "/dev/tty0";
+    int fd = open(ttydev, O_RDWR | O_SYNC);
+    if (fd<0) {
+        LOGE("Can't open %s", ttydev);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // to make sure that we are in text mode
+    int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
+    if (res<0) {
+        LOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
+                fd, res, strerror(errno));
+    }
+    
+    // get the current console
+    struct vt_stat vs;
+    res = ioctl(fd, VT_GETSTATE, &vs);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
+                fd, res, strerror(errno));
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // switch to console 7 (which is what X normaly uses)
+    int vtnum = 7;
+    do {
+        res = ioctl(fd, VT_ACTIVATE, (void*)vtnum);
+    } while(res < 0 && errno == EINTR);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for %d",
+                fd, errno, strerror(errno), vtnum);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    do {
+        res = ioctl(fd, VT_WAITACTIVE, (void*)vtnum);
+    } while(res < 0 && errno == EINTR);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for %d",
+                fd, res, errno, strerror(errno), vtnum);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // open the new console
+    close(fd);
+    fd = open(ttydev, O_RDWR | O_SYNC);
+    if (fd<0) {
+        LOGE("Can't open new console %s", ttydev);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    /* disable console line buffer, echo, ... */
+    struct termios ttyarg;
+    ioctl(fd, TCGETS , &ttyarg);
+    ttyarg.c_iflag = 0;
+    ttyarg.c_lflag = 0;
+    ioctl(fd, TCSETS , &ttyarg);
+
+    // set up signals so we're notified when the console changes
+    // we can't use SIGUSR1 because it's used by the java-vm
+    vm.mode = VT_PROCESS;
+    vm.waitv = 0;
+    vm.relsig = SIGUSR2;
+    vm.acqsig = SIGUNUSED;
+    vm.frsig = 0;
+
+    struct sigaction act;
+    sigemptyset(&act.sa_mask);
+    act.sa_handler = sigHandler;
+    act.sa_flags = 0;
+    sigaction(vm.relsig, &act, NULL);
+
+    sigemptyset(&act.sa_mask);
+    act.sa_handler = sigHandler;
+    act.sa_flags = 0;
+    sigaction(vm.acqsig, &act, NULL);
+
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, vm.relsig);
+    sigaddset(&mask, vm.acqsig);
+    sigprocmask(SIG_BLOCK, &mask, NULL);
+
+    // switch to graphic mode
+    res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
+    LOGW_IF(res<0,
+            "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);
+
+    this->prev_vt_num = vs.v_active;
+    this->vt_num = vtnum;
+    this->consoleFd = fd;
+}
+
+DisplayHardwareBase::ConsoleManagerThread::~ConsoleManagerThread()
+{   
+    if (this->consoleFd >= 0) {
+        int fd = this->consoleFd;
+        int prev_vt_num = this->prev_vt_num;
+        int res;
+        ioctl(fd, KDSETMODE, (void*)KD_TEXT);
+        do {
+            res = ioctl(fd, VT_ACTIVATE, (void*)prev_vt_num);
+        } while(res < 0 && errno == EINTR);
+        do {
+            res = ioctl(fd, VT_WAITACTIVE, (void*)prev_vt_num);
+        } while(res < 0 && errno == EINTR);
+        close(fd);    
+        char const * const ttydev = "/dev/tty0";
+        fd = open(ttydev, O_RDWR | O_SYNC);
+        ioctl(fd, VT_DISALLOCATE, 0);
+        close(fd);
+    }
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::readyToRun()
+{
+    if (this->consoleFd >= 0) {
+        sSignalCatcherPid = gettid();
+        
+        sigset_t mask;
+        sigemptyset(&mask);
+        sigaddset(&mask, vm.relsig);
+        sigaddset(&mask, vm.acqsig);
+        sigprocmask(SIG_BLOCK, &mask, NULL);
+
+        int res = ioctl(this->consoleFd, VT_SETMODE, &vm);
+        if (res<0) {
+            LOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
+                    this->consoleFd, errno, strerror(errno));
+        }
+        return NO_ERROR;
+    }
+    return this->consoleFd;
+}
+
+void DisplayHardwareBase::ConsoleManagerThread::requestExit()
+{
+    Thread::requestExit();
+    if (sSignalCatcherPid != 0) {
+        // wake the thread up
+        kill(sSignalCatcherPid, SIGINT);
+        // wait for it...
+    }
+}
+
+void DisplayHardwareBase::ConsoleManagerThread::sigHandler(int sig)
+{
+    // resend the signal to our signal catcher thread
+    LOGW("received signal %d in thread %d, resending to %d",
+            sig, gettid(), sSignalCatcherPid);
+
+    // we absolutely need the delays below because without them
+    // our main thread never gets a chance to handle the signal.
+    usleep(10000);
+    kill(sSignalCatcherPid, sig);
+    usleep(10000);
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::releaseScreen() const
+{
+    int fd = this->consoleFd;
+    int err = ioctl(fd, VT_RELDISP, (void*)1);
+    LOGE_IF(err<0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)",
+        fd, errno, strerror(errno));
+    return (err<0) ? (-errno) : status_t(NO_ERROR);
+}
+
+bool DisplayHardwareBase::ConsoleManagerThread::threadLoop()
+{
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, vm.relsig);
+    sigaddset(&mask, vm.acqsig);
+
+    int sig = 0;
+    sigwait(&mask, &sig);
+
+    if (sig == vm.relsig) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        //LOGD("About to give-up screen, flinger = %p", flinger.get());
+        if (flinger != 0)
+            flinger->screenReleased(0);
+    } else if (sig == vm.acqsig) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        //LOGD("Screen about to return, flinger = %p", flinger.get());
+        if (flinger != 0) 
+            flinger->screenAcquired(0);
+    }
+    
+    return true;
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::initCheck() const
+{
+    return consoleFd >= 0 ? NO_ERROR : NO_INIT;
+}
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
+        uint32_t displayIndex) 
+    : mCanDraw(true)
+{
+    mDisplayEventThread = new DisplayEventThread(flinger);
+    if (mDisplayEventThread->initCheck() != NO_ERROR) {
+        // fall-back on the console
+        mDisplayEventThread = new ConsoleManagerThread(flinger);
+    }
+}
+
+DisplayHardwareBase::~DisplayHardwareBase()
+{
+    // request exit
+    mDisplayEventThread->requestExitAndWait();
+}
+
+
+bool DisplayHardwareBase::canDraw() const
+{
+    return mCanDraw;
+}
+
+void DisplayHardwareBase::releaseScreen() const
+{
+    status_t err = mDisplayEventThread->releaseScreen();
+    if (err >= 0) {
+        //LOGD("screen given-up");
+        mCanDraw = false;
+    }
+}
+
+void DisplayHardwareBase::acquireScreen() const
+{
+    status_t err = mDisplayEventThread->acquireScreen();
+    if (err >= 0) {
+        //LOGD("screen returned");
+        mCanDraw = true;
+    }
+}
+
+}; // namespace android
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
new file mode 100644
index 0000000..8369bb8
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_DISPLAY_HARDWARE_BASE_H
+#define ANDROID_DISPLAY_HARDWARE_BASE_H
+
+#include <stdint.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include "Barrier.h"
+
+namespace android {
+
+class SurfaceFlinger; 
+
+class DisplayHardwareBase
+{
+public:
+                DisplayHardwareBase(
+                        const sp<SurfaceFlinger>& flinger,
+                        uint32_t displayIndex);
+
+                ~DisplayHardwareBase();
+
+    // console managment
+    void releaseScreen() const;
+    void acquireScreen() const;
+    bool canDraw() const;
+
+private:
+    class DisplayEventThreadBase : public Thread {
+    protected:
+        wp<SurfaceFlinger> mFlinger;
+    public:
+        DisplayEventThreadBase(const sp<SurfaceFlinger>& flinger);
+        virtual ~DisplayEventThreadBase();
+        virtual void onFirstRef() {
+            run("DisplayEventThread", PRIORITY_URGENT_DISPLAY);
+        }
+        virtual status_t acquireScreen() const { return NO_ERROR; };
+        virtual status_t releaseScreen() const { return NO_ERROR; };
+        virtual status_t initCheck() const = 0;
+    };
+
+    class DisplayEventThread : public DisplayEventThreadBase 
+    {
+        mutable Barrier mBarrier;
+    public:
+                DisplayEventThread(const sp<SurfaceFlinger>& flinger);
+        virtual ~DisplayEventThread();
+        virtual bool threadLoop();
+        virtual status_t readyToRun();
+        virtual status_t releaseScreen() const;
+        virtual status_t initCheck() const;
+    };
+
+    class ConsoleManagerThread : public DisplayEventThreadBase 
+    {
+        int consoleFd;
+        int vt_num;
+        int prev_vt_num;
+        vt_mode vm;
+        static void sigHandler(int sig);
+        static pid_t sSignalCatcherPid;
+    public:
+                ConsoleManagerThread(const sp<SurfaceFlinger>& flinger);
+        virtual ~ConsoleManagerThread();
+        virtual bool threadLoop();
+        virtual status_t readyToRun();
+        virtual void requestExit();
+        virtual status_t releaseScreen() const;
+        virtual status_t initCheck() const;
+    };
+
+    sp<DisplayEventThreadBase>  mDisplayEventThread;
+    mutable int                 mCanDraw;
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_HARDWARE_BASE_H
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.cpp b/libs/surfaceflinger/GPUHardware/GPUHardware.cpp
new file mode 100644
index 0000000..b24a0f2
--- /dev/null
+++ b/libs/surfaceflinger/GPUHardware/GPUHardware.cpp
@@ -0,0 +1,557 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+#include <utils/IPCThreadState.h>
+#include <utils/StopWatch.h>
+
+#include <ui/ISurfaceComposer.h>
+
+#include "VRamHeap.h"
+#include "GPUHardware.h"
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+#include "GPUHardware/GPUHardware.h"
+
+/* 
+ * This file manages the GPU if there is one. The intent is that this code
+ * needs to be different for every devce. Currently there is no abstraction,
+ * but in the long term, this code needs to be refactored so that API and
+ * implementation are separated.
+ * 
+ * In this particular implementation, the GPU, its memory and register are
+ * managed here. Clients (such as OpenGL ES) request the GPU when then need
+ * it and are given a revokable heap containing the registers on memory. 
+ * 
+ */
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+// size reserved for GPU surfaces
+// 1200 KB fits exactly:
+//  - two 320*480 16-bits double-buffered surfaces
+//  - one 320*480 32-bits double-buffered surface
+//  - one 320*240 16-bits double-bufferd, 4x anti-aliased surface
+static const int GPU_RESERVED_SIZE  = 1200 * 1024;
+
+static const int GPUR_SIZE          = 1 * 1024 * 1024;
+
+// ---------------------------------------------------------------------------
+
+/* 
+ * GPUHandle is a special IMemory given to the client. It represents their
+ * handle to the GPU. Once they give it up, they loose GPU access, or if
+ * they explicitely revoke their acces through the binder code 1000.
+ * In both cases, this triggers a callback to revoke()
+ * first, and then actually powers down the chip.
+ * 
+ * In the case of a misbehaving app, GPUHardware can ask for an immediate
+ * release of the GPU to the target process which should answer by calling
+ * code 1000 on GPUHandle. If it doesn't in a timely manner, the GPU will
+ * be revoked from under their feet.
+ * 
+ * We should never hold a strong reference on GPUHandle. In practice this
+ * shouldn't be a big issue though because clients should use code 1000 and
+ * not rely on the dtor being called.
+ * 
+ */
+
+class GPUHandle : public BnMemory
+{
+public:
+            GPUHandle(const sp<GPUHardware>& gpu, const sp<IMemoryHeap>& heap)
+                : mGPU(gpu), mClientHeap(heap) {
+            }
+    virtual ~GPUHandle();
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+    virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+    void setOwner(int owner) { mOwner = owner; }
+private:
+    void revokeNotification();
+    wp<GPUHardware> mGPU;
+    sp<IMemoryHeap> mClientHeap;
+    int mOwner;
+};
+
+GPUHandle::~GPUHandle() { 
+    //LOGD("GPUHandle %p released, revoking GPU", this);
+    revokeNotification(); 
+}
+
+void GPUHandle::revokeNotification()  {
+    sp<GPUHardware> hw(mGPU.promote());
+    if (hw != 0) {
+        hw->revoke(mOwner);
+    }
+}
+sp<IMemoryHeap> GPUHandle::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (offset) *offset = 0;
+    if (size)   *size = mClientHeap !=0 ? mClientHeap->virtualSize() : 0;
+    return mClientHeap;
+}
+status_t GPUHandle::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    status_t err = BnMemory::onTransact(code, data, reply, flags);
+    if (err == UNKNOWN_TRANSACTION && code == 1000) {
+        int callingPid = IPCThreadState::self()->getCallingPid();
+        //LOGD("pid %d voluntarily revoking gpu", callingPid);
+        if (callingPid == mOwner) {
+            revokeNotification();
+            // we've revoked the GPU, don't do it again later when we
+            // are destroyed.
+            mGPU.clear();
+        } else {
+            LOGW("%d revoking someone else's gpu? (owner=%d)",
+                    callingPid, mOwner);            
+        }
+        err = NO_ERROR;
+    }
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+
+class MemoryHeapRegs : public MemoryHeapPmem 
+{
+public:
+            MemoryHeapRegs(const wp<GPUHardware>& gpu, const sp<MemoryHeapBase>& heap);
+    virtual ~MemoryHeapRegs();
+    sp<IMemory> mapMemory(size_t offset, size_t size);
+    virtual void revoke();
+private:
+    wp<GPUHardware> mGPU;
+};
+
+MemoryHeapRegs::MemoryHeapRegs(const wp<GPUHardware>& gpu, const sp<MemoryHeapBase>& heap)
+    :  MemoryHeapPmem(heap), mGPU(gpu)
+{
+#if HAVE_ANDROID_OS
+    if (heapID()>0) {
+        /* this is where the GPU is powered on and the registers are mapped
+         * in the client */
+        //LOGD("ioctl(HW3D_GRANT_GPU)");
+        int err = ioctl(heapID(), HW3D_GRANT_GPU, base());
+        if (err) {
+            // it can happen if the master heap has been closed already
+            // in which case the GPU already is revoked (app crash for
+            // instance).
+            //LOGW("HW3D_GRANT_GPU failed (%s), mFD=%d, base=%p",
+            //        strerror(errno), heapID(), base());
+        }
+    }
+#endif
+}
+
+MemoryHeapRegs::~MemoryHeapRegs() 
+{
+}
+
+sp<IMemory> MemoryHeapRegs::mapMemory(size_t offset, size_t size)
+{
+    sp<GPUHandle> memory;
+    sp<GPUHardware> gpu = mGPU.promote();
+    if (heapID()>0 && gpu!=0) 
+        memory = new GPUHandle(gpu, this);
+    return memory;
+}
+
+void MemoryHeapRegs::revoke() 
+{
+    MemoryHeapPmem::revoke();
+#if HAVE_ANDROID_OS
+    if (heapID() > 0) {
+        //LOGD("ioctl(HW3D_REVOKE_GPU)");
+        int err = ioctl(heapID(), HW3D_REVOKE_GPU, base());
+        LOGE_IF(err, "HW3D_REVOKE_GPU failed (%s), mFD=%d, base=%p",
+                strerror(errno), heapID(), base());
+    }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
+class GPURegisterHeap : public PMemHeapInterface
+{
+public:
+    GPURegisterHeap(const sp<GPUHardware>& gpu)
+        : PMemHeapInterface("/dev/hw3d", GPUR_SIZE), mGPU(gpu)
+    {
+    }
+    virtual ~GPURegisterHeap() {
+    }
+    virtual sp<MemoryHeapPmem> createClientHeap() {
+        sp<MemoryHeapBase> parentHeap(this);
+        return new MemoryHeapRegs(mGPU, parentHeap);
+    }
+private:
+    wp<GPUHardware> mGPU;
+};
+
+/*****************************************************************************/
+
+GPUHardware::GPUHardware()
+    : mOwner(NO_OWNER)
+{
+}
+
+GPUHardware::~GPUHardware()
+{
+}
+
+sp<MemoryDealer> GPUHardware::request(int pid)
+{
+    sp<MemoryDealer> dealer;
+
+    LOGD("pid %d requesting gpu surface (current owner = %d)", pid, mOwner);
+
+    const int self_pid = getpid();
+    if (pid == self_pid) {
+        // can't use GPU from surfaceflinger's process
+        return dealer;
+    }
+
+    Mutex::Autolock _l(mLock);
+    
+    if (mOwner != pid) {
+        // someone already has the gpu.
+        takeBackGPULocked();
+
+        // releaseLocked() should be a no-op most of the time
+        releaseLocked();
+
+        requestLocked(); 
+    }
+
+    dealer = mAllocator;
+    mOwner = pid;
+    if (dealer == 0) {
+        mOwner = SURFACE_FAILED;
+    }
+    
+    LOGD_IF(dealer!=0, "gpu surface granted to pid %d", mOwner);
+    return dealer;
+}
+
+status_t GPUHardware::request(const sp<IGPUCallback>& callback,
+        ISurfaceComposer::gpu_info_t* gpu)
+{
+    sp<IMemory> gpuHandle;
+    IPCThreadState* ipc = IPCThreadState::self();
+    const int pid = ipc->getCallingPid();
+    const int self_pid = getpid();
+
+    LOGD("pid %d requesting gpu core (owner = %d)", pid, mOwner);
+
+    if (pid == self_pid) {
+        // can't use GPU from surfaceflinger's process
+        return PERMISSION_DENIED;
+    }
+
+    Mutex::Autolock _l(mLock);
+    if (mOwner != pid) {
+        // someone already has the gpu.
+        takeBackGPULocked();
+
+        // releaseLocked() should be a no-op most of the time
+        releaseLocked();
+
+        requestLocked(); 
+    }
+
+    if (mHeapR.isValid()) {
+        gpu->count = 2;
+        gpu->regions[0].region = mHeap0.map(true);
+        gpu->regions[0].reserved = mHeap0.reserved;
+        gpu->regions[1].region = mHeap1.map(true);
+        gpu->regions[1].reserved = mHeap1.reserved;
+        gpu->regs = mHeapR.map();
+        if (gpu->regs != 0) {
+            static_cast< GPUHandle* >(gpu->regs.get())->setOwner(pid);
+        }
+        mCallback = callback;
+        mOwner = pid;
+        //LOGD("gpu core granted to pid %d, handle base=%p",
+        //        mOwner, gpu->regs->pointer());
+    } else {
+        LOGW("couldn't grant gpu core to pid %d", pid);
+    }
+
+    return NO_ERROR;
+}
+
+void GPUHardware::revoke(int pid)
+{
+    Mutex::Autolock _l(mLock);
+    if (mOwner > 0) {
+        if (pid != mOwner) {
+            LOGW("GPU owned by %d, revoke from %d", mOwner, pid);
+            return;
+        }
+        //LOGD("revoke pid=%d, owner=%d", pid, mOwner);
+        // mOwner could be <0 if the same process acquired the GPU
+        // several times without releasing it first.
+        mCondition.signal();
+        releaseLocked(true);
+    }
+}
+
+status_t GPUHardware::friendlyRevoke()
+{
+    Mutex::Autolock _l(mLock);
+    takeBackGPULocked();
+    //LOGD("friendlyRevoke owner=%d", mOwner);
+    releaseLocked(true);
+    return NO_ERROR;
+}
+
+void GPUHardware::takeBackGPULocked()
+{
+    sp<IGPUCallback> callback = mCallback;
+    mCallback.clear();
+    if (callback != 0) {
+        callback->gpuLost(); // one-way
+        mCondition.waitRelative(mLock, ms2ns(250));
+    }
+}
+
+void GPUHardware::requestLocked()
+{
+    if (mAllocator == 0) {
+        GPUPart* part = 0;
+        sp<PMemHeap> surfaceHeap;
+        if (mHeap1.promote() == false) {
+            //LOGD("requestLocked: (1) creating new heap");
+            mHeap1.set(new PMemHeap("/dev/pmem_gpu1", 0, GPU_RESERVED_SIZE));
+        }
+        if (mHeap1.isValid()) {
+            //LOGD("requestLocked: (1) heap is valid");
+            // NOTE: if GPU1 is available we use it for our surfaces
+            // this could be device specific, so we should do something more
+            // generic
+            surfaceHeap = static_cast< PMemHeap* >( mHeap1.getHeap().get() );
+            part = &mHeap1;
+            if (mHeap0.promote() == false) {
+                //LOGD("requestLocked: (0) creating new heap");
+                mHeap0.set(new PMemHeap("/dev/pmem_gpu0"));
+            }
+        } else {
+            //LOGD("requestLocked: (1) heap is not valid");
+            // No GPU1, use GPU0 only
+            if (mHeap0.promote() == false) {
+                //LOGD("requestLocked: (0) creating new heap");
+                mHeap0.set(new PMemHeap("/dev/pmem_gpu0", 0, GPU_RESERVED_SIZE));
+            }
+            if (mHeap0.isValid()) {
+                //LOGD("requestLocked: (0) heap is valid");
+                surfaceHeap = static_cast< PMemHeap* >( mHeap0.getHeap().get() );
+                part = &mHeap0;
+            }
+        }
+        
+        if (mHeap0.isValid() || mHeap1.isValid()) {
+            if (mHeapR.promote() == false) {
+                //LOGD("requestLocked: (R) creating new register heap");
+                mHeapR.set(new GPURegisterHeap(this));
+            }
+        } else {
+            // we got nothing...
+            mHeap0.clear();
+            mHeap1.clear();
+        }
+
+        if (mHeapR.isValid() == false) {
+            //LOGD("requestLocked: (R) register heap not valid!!!");
+            // damn, couldn't get the gpu registers!
+            mHeap0.clear();
+            mHeap1.clear();
+            surfaceHeap.clear();
+            part = NULL;
+        }
+
+        if (surfaceHeap != 0 && part && part->getClientHeap()!=0) {
+            part->reserved = GPU_RESERVED_SIZE;
+            part->surface = true;
+            mAllocatorDebug = static_cast<SimpleBestFitAllocator*>(
+                    surfaceHeap->getAllocator().get());
+            mAllocator = new MemoryDealer(
+                    part->getClientHeap(),
+                    surfaceHeap->getAllocator());
+        }
+    }
+}
+
+void GPUHardware::releaseLocked(bool dispose)
+{
+    /* 
+     * if dispose is set, we will force the destruction of the heap,
+     * so it is given back to other systems, such as camera.
+     * Otherwise, we'll keep a weak pointer to it, this way we might be able
+     * to reuse it later if it's still around. 
+     */
+    //LOGD("revoking gpu from pid %d", mOwner);
+    mOwner = NO_OWNER;
+    mAllocator.clear();
+    mCallback.clear();
+
+    /* if we're asked for a full revoke, dispose only of the heap
+     * we're not using for surface (as we might need it while drawing) */
+    mHeap0.release(mHeap0.surface ? false : dispose);
+    mHeap1.release(mHeap1.surface ? false : dispose);
+    mHeapR.release(false);
+}
+
+// ----------------------------------------------------------------------------
+// for debugging / testing ...
+
+sp<SimpleBestFitAllocator> GPUHardware::getAllocator() const {
+    Mutex::Autolock _l(mLock);
+    sp<SimpleBestFitAllocator> allocator = mAllocatorDebug.promote();
+    return allocator;
+}
+
+void GPUHardware::unconditionalRevoke()
+{
+    Mutex::Autolock _l(mLock);
+    releaseLocked();
+}
+
+// ---------------------------------------------------------------------------
+
+
+GPUHardware::GPUPart::GPUPart()
+    : surface(false), reserved(0)
+{
+}
+
+GPUHardware::GPUPart::~GPUPart() {
+}
+    
+const sp<PMemHeapInterface>& GPUHardware::GPUPart::getHeap() const {
+    return mHeap;
+}
+
+const sp<MemoryHeapPmem>& GPUHardware::GPUPart::getClientHeap() const {
+    return mClientHeap;
+}
+
+bool GPUHardware::GPUPart::isValid() const {
+    return ((mHeap!=0) && (mHeap->base() != MAP_FAILED));
+}
+
+void GPUHardware::GPUPart::clear() 
+{
+    mHeap.clear();
+    mHeapWeak.clear();
+    mClientHeap.clear();
+    surface = false;
+}
+
+void GPUHardware::GPUPart::set(const sp<PMemHeapInterface>& heap) 
+{
+    mHeapWeak.clear();
+    if (heap!=0 && heap->base() == MAP_FAILED) {
+        mHeap.clear();
+        mClientHeap.clear();
+    } else { 
+        mHeap = heap;
+        mClientHeap = mHeap->createClientHeap();
+    }
+}
+
+bool GPUHardware::GPUPart::promote() 
+{
+    //LOGD("mHeapWeak=%p, mHeap=%p", mHeapWeak.unsafe_get(), mHeap.get());
+    if (mHeap == 0) {
+        mHeap = mHeapWeak.promote();
+    }
+    if (mHeap != 0) {
+        if (mClientHeap != 0) {
+            mClientHeap->revoke();
+        }
+        mClientHeap = mHeap->createClientHeap();
+    }  else {
+        surface = false;
+    }
+    return mHeap != 0;
+}
+
+sp<IMemory> GPUHardware::GPUPart::map(bool clear) 
+{
+    sp<IMemory> memory;
+    if (mClientHeap != NULL) {
+        memory = mClientHeap->mapMemory(0, mHeap->virtualSize());
+        if (clear && memory!=0) {
+            //StopWatch sw("memset");
+            memset(memory->pointer(), 0, memory->size());
+        }
+    }
+    return memory;
+}
+
+void GPUHardware::GPUPart::release(bool dispose)
+{
+    if (mClientHeap != 0) {
+        mClientHeap->revoke();
+        mClientHeap.clear();
+    }
+    if (dispose) {
+        if (mHeapWeak!=0 && mHeap==0) {
+            mHeap = mHeapWeak.promote();
+        }
+        if (mHeap != 0) {
+            mHeap->dispose();
+            mHeapWeak.clear();
+            mHeap.clear();
+        } else {
+            surface = false;
+        }
+    } else {
+        if (mHeap != 0) {
+            mHeapWeak = mHeap;
+            mHeap.clear();
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.h b/libs/surfaceflinger/GPUHardware/GPUHardware.h
new file mode 100644
index 0000000..9a78b99
--- /dev/null
+++ b/libs/surfaceflinger/GPUHardware/GPUHardware.h
@@ -0,0 +1,116 @@
+/*
+ * 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_GPU_HARDWARE_H
+#define ANDROID_GPU_HARDWARE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class GPUHardwareInterface : public RefBase
+{
+public:
+    virtual void                revoke(int pid) = 0;
+    virtual sp<MemoryDealer>    request(int pid) = 0;
+    virtual status_t            request(const sp<IGPUCallback>& callback,
+            ISurfaceComposer::gpu_info_t* gpu) = 0;
+
+    virtual status_t            friendlyRevoke() = 0;
+    virtual void                unconditionalRevoke() = 0;
+    
+    // used for debugging only...
+    virtual sp<SimpleBestFitAllocator> getAllocator() const  = 0;
+    virtual pid_t getOwner() const = 0;
+};
+
+// ---------------------------------------------------------------------------
+
+class IMemory;
+class MemoryHeapPmem;
+class PMemHeap;
+
+class GPUHardware : public GPUHardwareInterface
+{
+public:
+            GPUHardware();
+    virtual ~GPUHardware();
+    
+    virtual void                revoke(int pid);
+    virtual sp<MemoryDealer>    request(int pid);
+    virtual status_t            request(const sp<IGPUCallback>& callback,
+            ISurfaceComposer::gpu_info_t* gpu);
+
+    virtual status_t            friendlyRevoke();
+    virtual void                unconditionalRevoke();
+    
+    // used for debugging only...
+    virtual sp<SimpleBestFitAllocator> getAllocator() const;
+    virtual pid_t getOwner() const { return mOwner; }
+    
+private:
+    enum {
+        NO_OWNER        = -1,
+        SURFACE_FAILED  = -2
+    };
+    
+    void requestLocked();
+    void releaseLocked(bool dispose = false);
+    void takeBackGPULocked();
+    
+    class GPUPart
+    {
+    public:
+        bool surface;
+        size_t reserved;
+        GPUPart();
+        ~GPUPart();
+        const sp<PMemHeapInterface>& getHeap() const;
+        const sp<MemoryHeapPmem>& getClientHeap() const;
+        bool isValid() const;
+        void clear();
+        void set(const sp<PMemHeapInterface>& heap);
+        bool promote();
+        sp<IMemory> map(bool clear = false);
+        void release(bool dispose);
+    private:
+        sp<PMemHeapInterface>   mHeap;
+        wp<PMemHeapInterface>   mHeapWeak;
+        sp<MemoryHeapPmem>      mClientHeap;
+    };
+    
+    mutable Mutex   mLock;
+    GPUPart         mHeap0; // SMI
+    GPUPart         mHeap1; // EBI1
+    GPUPart         mHeapR;
+    sp<MemoryDealer> mAllocator;
+    pid_t            mOwner;
+    sp<IGPUCallback> mCallback;
+    wp<SimpleBestFitAllocator> mAllocatorDebug;
+    
+    Condition       mCondition;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GPU_HARDWARE_H
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
new file mode 100644
index 0000000..4f6bae1
--- /dev/null
+++ b/libs/surfaceflinger/Layer.cpp
@@ -0,0 +1,565 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/properties.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/StopWatch.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/EGLDisplaySurface.h>
+
+#include "clz.h"
+#include "Layer.h"
+#include "LayerBitmap.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+#define DEBUG_RESIZE    0
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
+const char* const Layer::typeID = "Layer";
+
+// ---------------------------------------------------------------------------
+
+Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i)
+    :   LayerBaseClient(flinger, display, c, i),
+        mSecure(false),
+        mFrontBufferIndex(1),
+        mNeedsBlending(true),
+        mResizeTransactionDone(false),
+        mTextureName(-1U), mTextureWidth(0), mTextureHeight(0)
+{
+    // no OpenGL operation is possible here, since we might not be
+    // in the OpenGL thread.
+}
+
+Layer::~Layer()
+{
+    client->free(clientIndex());
+    // this should always be called from the OpenGL thread
+    if (mTextureName != -1U) {
+        //glDeleteTextures(1, &mTextureName);
+        deletedTextures.add(mTextureName);
+    }
+}
+
+void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerBase::initStates(w,h,flags);
+
+    if (flags & ISurfaceComposer::eDestroyBackbuffer)
+        lcblk->flags |= eNoCopyBack;
+}
+
+sp<LayerBaseClient::Surface> Layer::getSurface() const
+{
+    return mSurface;
+}
+
+status_t Layer::setBuffers( Client* client,
+                            uint32_t w, uint32_t h,
+                            PixelFormat format, uint32_t flags)
+{
+    PixelFormatInfo info;
+    status_t err = getPixelFormatInfo(format, &info);
+    if (err) return err;
+
+    // TODO: if eHardware is explicitely requested, we should fail
+    // on systems where we can't allocate memory that can be used with
+    // DMA engines for instance.
+
+    int memory_type = NATIVE_MEMORY_TYPE_PMEM;
+    
+    // pixel-alignment. the final alignment may be bigger because
+    // we always force a 4-byte aligned bpr.
+    uint32_t alignment = 1;
+
+    const uint32_t mask = ISurfaceComposer::eGPU | ISurfaceComposer::eSecure;
+    if ((flags & mask) == ISurfaceComposer::eGPU) {
+        // don't grant GPU memory if GPU is disabled
+        char value[PROPERTY_VALUE_MAX];
+        property_get("debug.egl.hw", value, "1");
+        if (atoi(value) != 0) {
+            flags |= ISurfaceComposer::eHardware;
+            memory_type = NATIVE_MEMORY_TYPE_GPU;
+            // TODO: this value should come from the h/w
+            alignment = 8; 
+        }
+    }
+
+    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
+    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
+    sp<MemoryDealer> allocators[2];
+    for (int i=0 ; i<2 ; i++) {
+        allocators[i] = client->createAllocator(memory_type);
+        if (allocators[i] == 0)
+            return NO_MEMORY;
+        mBuffers[i].init(allocators[i]);
+        int err = mBuffers[i].setBits(w, h, alignment, format, LayerBitmap::SECURE_BITS);
+        if (err != NO_ERROR)
+            return err;
+        mBuffers[i].clear(); // clear the bits for security
+        mBuffers[i].getInfo(lcblk->surface + i);
+    }
+
+    mSurface = new Surface(clientIndex(),
+            allocators[0]->getMemoryHeap(),
+            allocators[1]->getMemoryHeap(),
+            memory_type, mIdentity);
+
+    return NO_ERROR;
+}
+
+void Layer::reloadTexture(const Region& dirty)
+{
+    if (UNLIKELY(mTextureName == -1U)) {
+        // create the texture name the first time
+        // can't do that in the ctor, because it runs in another thread.
+        mTextureName = createTexture();
+    }
+    const GGLSurface& t(frontBuffer().surface());
+    loadTexture(dirty, mTextureName, t, mTextureWidth, mTextureHeight);
+}
+
+
+void Layer::onDraw(const Region& clip) const
+{
+    if (UNLIKELY(mTextureName == -1LU)) {
+        //LOGW("Layer %p doesn't have a texture", this);
+        // the texture has not been created yet, this Layer has
+        // in fact never been drawn into. this happens frequently with
+        // SurfaceView.
+        clearWithOpenGL(clip);
+        return;
+    }
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const LayerBitmap& front(frontBuffer());
+    const GGLSurface& t(front.surface());
+
+    status_t err = NO_ERROR;
+    const int can_use_copybit = canUseCopybit();
+    if (can_use_copybit)  {
+        // StopWatch watch("copybit");
+        const State& s(drawingState());
+
+        copybit_image_t dst;
+        hw.getDisplaySurface(&dst);
+        const copybit_rect_t& drect
+            = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
+
+        copybit_image_t src;
+        front.getBitmapSurface(&src);
+        copybit_rect_t srect = { 0, 0, t.width, t.height };
+
+        copybit_t* copybit = mFlinger->getBlitEngine();
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation());
+        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+        copybit->set_parameter(copybit, COPYBIT_DITHER,
+                s.flags & ISurfaceComposer::eLayerDither ?
+                        COPYBIT_ENABLE : COPYBIT_DISABLE);
+
+        region_iterator it(clip);
+        err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+    }
+
+    if (!can_use_copybit || err) {
+        drawWithOpenGL(clip, mTextureName, t);
+    }
+}
+
+status_t Layer::reallocateBuffer(int32_t index, uint32_t w, uint32_t h)
+{
+    LOGD_IF(DEBUG_RESIZE,
+                "reallocateBuffer (layer=%p), "
+                "requested (%dx%d), "
+                "index=%d, (%dx%d), (%dx%d)",
+                this,
+                int(w), int(h),
+                int(index),
+                int(mBuffers[0].width()), int(mBuffers[0].height()),
+                int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+    status_t err = mBuffers[index].resize(w, h);
+    if (err == NO_ERROR) {
+        mBuffers[index].getInfo(lcblk->surface + index);
+    } else {
+        LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s",
+            index, w, h, err, strerror(err));
+        // XXX: what to do, what to do? We could try to free some
+        // hidden surfaces, instead of killing this one?
+    }
+    return err;
+}
+
+uint32_t Layer::doTransaction(uint32_t flags)
+{
+    const Layer::State& front(drawingState());
+    const Layer::State& temp(currentState());
+
+    // the test front.{w|h} != temp.{w|h} is not enough because it is possible
+    // that the size changed back to its previous value before the buffer
+    // was resized (in the eLocked case below), in which case, we still
+    // need to execute the code below so the clients have a chance to be
+    // release. resze() deals with the fact that the size can be the same.
+
+    /*
+     *  Various states we could be in...
+
+         resize = state & eResizeRequested;
+         if (backbufferChanged) {
+             if (resize == 0) {
+                 // ERROR, the resized buffer doesn't have its resize flag set
+             } else if (resize == mask) {
+                 // ERROR one of the buffer has already been resized
+             } else if (resize == mask ^ eResizeRequested) {
+                 // ERROR, the resized buffer doesn't have its resize flag set
+             } else if (resize == eResizeRequested) {
+                 // OK, Normal case, proceed with resize
+             }
+         } else {
+             if (resize == 0) {
+                 // OK, nothing special, do nothing
+             } else if (resize == mask) {
+                 // restarted transaction, do nothing
+             } else if (resize == mask ^ eResizeRequested) {
+                 // restarted transaction, do nothing
+             } else if (resize == eResizeRequested) {
+                 // OK, size reset to previous value, proceed with resize
+             }
+         }
+     */
+
+    // Index of the back buffer
+    const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
+    const uint32_t state = lcblk->swapState;
+    const int32_t clientBackBufferIndex = layer_cblk_t::backBuffer(state);
+    const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
+    uint32_t resizeFlags = state & eResizeRequested;
+
+    if (UNLIKELY(backbufferChanged && (resizeFlags != eResizeRequested))) {
+        LOGE(   "backbuffer size changed, but both resize flags are not set! "
+                "(layer=%p), state=%08x, requested (%dx%d), drawing (%d,%d), "
+                "index=%d, (%dx%d), (%dx%d)",
+                this,  state,
+                int(temp.w), int(temp.h),
+                int(drawingState().w), int(drawingState().h),
+                int(clientBackBufferIndex),
+                int(mBuffers[0].width()), int(mBuffers[0].height()),
+                int(mBuffers[1].width()), int(mBuffers[1].height()));
+        // if we get there we're pretty screwed. the only reasonable
+        // thing to do is to pretend we should do the resize since
+        // backbufferChanged is set (this also will give a chance to
+        // client to get unblocked)
+        resizeFlags = eResizeRequested;
+    }
+
+    if (resizeFlags == eResizeRequested)  {
+        // NOTE: asserting that clientBackBufferIndex!=mFrontBufferIndex
+        // here, would be wrong and misleading because by this point
+        // mFrontBufferIndex has not been updated yet.
+
+        LOGD_IF(DEBUG_RESIZE,
+                    "resize (layer=%p), state=%08x, "
+                    "requested (%dx%d), "
+                    "drawing (%d,%d), "
+                    "index=%d, (%dx%d), (%dx%d)",
+                    this,  state,
+                    int(temp.w), int(temp.h),
+                    int(drawingState().w), int(drawingState().h),
+                    int(clientBackBufferIndex),
+                    int(mBuffers[0].width()), int(mBuffers[0].height()),
+                    int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+        if (state & eLocked) {
+            // if the buffer is locked, we can't resize anything because
+            // - the backbuffer is currently in use by the user
+            // - the front buffer is being shown
+            // We just act as if the transaction didn't happen and we
+            // reschedule it later...
+            flags |= eRestartTransaction;
+        } else {
+            // This buffer needs to be resized
+            status_t err =
+                resize(clientBackBufferIndex, temp.w, temp.h, "transaction");
+            if (err == NO_ERROR) {
+                const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
+                android_atomic_and(~mask, &(lcblk->swapState));
+                // since a buffer became availlable, we can let the client go...
+                mFlinger->scheduleBroadcast(client);
+                mResizeTransactionDone = true;
+
+                // we're being resized and there is a freeze display request,
+                // acquire a freeze lock, so that the screen stays put
+                // until we've redrawn at the new size; this is to avoid
+                // glitches upon orientation changes.
+                if (mFlinger->hasFreezeRequest()) {
+                    // if the surface is hidden, don't try to acquire the
+                    // freeze lock, since hidden surfaces may never redraw
+                    if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
+                        mFreezeLock = mFlinger->getFreezeLock();
+                    }
+                }
+            }
+        }
+    }
+    
+    if (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);
+}
+
+status_t Layer::resize(
+        int32_t clientBackBufferIndex,
+        uint32_t width, uint32_t height,
+        const char* what)
+{
+    /*
+     * handle resize (backbuffer and frontbuffer reallocation)
+     */
+
+    const LayerBitmap& clientBackBuffer(mBuffers[clientBackBufferIndex]);
+
+    // if the new (transaction) size is != from the the backbuffer
+    // then we need to reallocate the backbuffer
+    bool backbufferChanged = (clientBackBuffer.width()  != width) ||
+                             (clientBackBuffer.height() != height);
+
+    LOGD_IF(!backbufferChanged,
+            "(%s) eResizeRequested (layer=%p), but size not changed: "
+            "requested (%dx%d), drawing (%d,%d), current (%d,%d),"
+            "state=%08lx, index=%d, (%dx%d), (%dx%d)",
+            what, this,
+            int(width), int(height),
+            int(drawingState().w), int(drawingState().h),
+            int(currentState().w), int(currentState().h),
+            long(lcblk->swapState),
+            int(clientBackBufferIndex),
+            int(mBuffers[0].width()), int(mBuffers[0].height()),
+            int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+    // this can happen when changing the size back and forth quickly
+    status_t err = NO_ERROR;
+    if (backbufferChanged) {
+        err = reallocateBuffer(clientBackBufferIndex, width, height);
+    }
+    if (UNLIKELY(err != NO_ERROR)) {
+        // couldn't reallocate the surface
+        android_atomic_write(eInvalidSurface, &lcblk->swapState);
+        memset(lcblk->surface+clientBackBufferIndex, 0, sizeof(surface_info_t));
+    }
+    return err;
+}
+
+void Layer::setSizeChanged(uint32_t w, uint32_t h)
+{
+    LOGD_IF(DEBUG_RESIZE,
+            "setSizeChanged w=%d, h=%d (old: w=%d, h=%d)",
+            w, h, mCurrentState.w, mCurrentState.h);
+    android_atomic_or(eResizeRequested, &(lcblk->swapState));
+}
+
+// ----------------------------------------------------------------------------
+// pageflip handling...
+// ----------------------------------------------------------------------------
+
+void Layer::lockPageFlip(bool& recomputeVisibleRegions)
+{
+    uint32_t state = android_atomic_or(eBusy, &(lcblk->swapState));
+    // preemptively block the client, because he might set
+    // eFlipRequested at any time and want to use this buffer
+    // for the next frame. This will be unset below if it
+    // turns out we didn't need it.
+
+    uint32_t mask = eInvalidSurface | eFlipRequested | eResizeRequested;
+    if (!(state & mask))
+        return;
+
+    if (UNLIKELY(state & eInvalidSurface)) {
+        // if eInvalidSurface is set, this means the surface
+        // became invalid during a transaction (NO_MEMORY for instance)
+        mFlinger->scheduleBroadcast(client);
+        return;
+    }
+
+    if (UNLIKELY(state & eFlipRequested)) {
+        uint32_t oldState;
+        mPostedDirtyRegion = post(&oldState, recomputeVisibleRegions);
+        if (oldState & eNextFlipPending) {
+            // Process another round (we know at least a buffer
+            // is ready for that client).
+            mFlinger->signalEvent();
+        }
+    }
+}
+
+Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions)
+{
+    // atomically swap buffers and (re)set eFlipRequested
+    int32_t oldValue, newValue;
+    layer_cblk_t * const lcblk = this->lcblk;
+    do {
+        oldValue = lcblk->swapState;
+            // get the current value
+
+        LOG_ASSERT(oldValue&eFlipRequested,
+            "eFlipRequested not set, yet we're flipping! (state=0x%08lx)",
+            long(oldValue));
+
+        newValue = (oldValue ^ eIndex);
+            // swap buffers
+
+        newValue &= ~(eFlipRequested | eNextFlipPending);
+            // clear eFlipRequested and eNextFlipPending
+
+        if (oldValue & eNextFlipPending)
+            newValue |= eFlipRequested;
+            // if eNextFlipPending is set (second buffer already has something
+            // in it) we need to reset eFlipRequested because the client
+            // might never do it
+
+    } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
+    *previousSate = oldValue;
+
+    const int32_t index = (newValue & eIndex) ^ 1;
+    mFrontBufferIndex = index;
+
+    // ... post the new front-buffer
+    Region dirty(lcblk->region + index);
+    dirty.andSelf(frontBuffer().bounds());
+
+    //LOGI("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n",
+    //    oldValue, newValue, mFrontBufferIndex);
+    //dirty.dump("dirty");
+
+    if (UNLIKELY(oldValue & eResizeRequested)) {
+
+        LOGD_IF(DEBUG_RESIZE,
+                     "post (layer=%p), state=%08x, "
+                     "index=%d, (%dx%d), (%dx%d)",
+                     this,  newValue,
+                     int(1-index),
+                     int(mBuffers[0].width()), int(mBuffers[0].height()),
+                     int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+        // here, we just posted the surface and we have resolved
+        // the front/back buffer indices. The client is blocked, so
+        // it cannot start using the new backbuffer.
+
+        // If the backbuffer was resized in THIS round, we actually cannot
+        // resize the frontbuffer because it has *just* been drawn (and we
+        // would have nothing to draw). In this case we just skip the resize
+        // it'll happen after the next page flip or during the next
+        // transaction.
+
+        const uint32_t mask = (1-index) ? eResizeBuffer1 : eResizeBuffer0;
+        if (mResizeTransactionDone && (newValue & mask)) {
+            // Resize the layer's second buffer only if the transaction
+            // happened. It may not have happened yet if eResizeRequested
+            // was set immediately after the "transactionRequested" test,
+            // in which case the drawing state's size would be wrong.
+            mFreezeLock.clear();
+            const Layer::State& s(drawingState());
+            if (resize(1-index, s.w, s.h, "post") == NO_ERROR) {
+                do {
+                    oldValue = lcblk->swapState;
+                    if ((oldValue & eResizeRequested) == eResizeRequested) {
+                        // ugh, another resize was requested since we processed
+                        // the first buffer, don't free the client, and let
+                        // the next transaction handle everything.
+                        break;
+                    }
+                    newValue = oldValue & ~mask;
+                } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
+            }
+            mResizeTransactionDone = false;
+            recomputeVisibleRegions = true;
+            invalidate = true;
+        }
+    }
+
+    reloadTexture(dirty);
+
+    return dirty;
+}
+
+Point Layer::getPhysicalSize() const
+{
+    const LayerBitmap& front(frontBuffer());
+    return Point(front.width(), front.height());
+}
+
+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);
+
+        // client could be blocked, so signal them so they get a
+        // chance to reevaluate their condition.
+        mFlinger->scheduleBroadcast(client);
+    }
+}
+
+void Layer::finishPageFlip()
+{
+    if (LIKELY(!(lcblk->swapState & eInvalidSurface))) {
+        LOGE_IF(!(lcblk->swapState & eBusy),
+                "layer %p wasn't locked!", this);
+        android_atomic_and(~eBusy, &(lcblk->swapState));
+    }
+    mFlinger->scheduleBroadcast(client);
+}
+
+
+// ---------------------------------------------------------------------------
+
+
+}; // namespace android
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
new file mode 100644
index 0000000..2867f2b
--- /dev/null
+++ b/libs/surfaceflinger/Layer.h
@@ -0,0 +1,120 @@
+/*
+ * 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/PixelFormat.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "LayerBitmap.h"
+#include "LayerBase.h"
+#include "Transform.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class Client;
+class LayerBitmap;
+class MemoryDealer;
+class FreezeLock;
+
+// ---------------------------------------------------------------------------
+
+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,
+                         Client* c, int32_t i);
+
+        virtual ~Layer();
+
+    inline PixelFormat pixelFormat() const {
+        return frontBuffer().pixelFormat();
+    }
+
+    status_t setBuffers(    Client* client,
+                            uint32_t w, uint32_t h,
+                            PixelFormat format, uint32_t flags=0);
+
+    virtual void onDraw(const Region& clip) const;
+    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+    virtual void setSizeChanged(uint32_t w, uint32_t h);
+    virtual uint32_t doTransaction(uint32_t transactionFlags);
+    virtual Point getPhysicalSize() const;
+    virtual void lockPageFlip(bool& recomputeVisibleRegions);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    virtual void finishPageFlip();
+    virtual bool needsBlending() const      { return mNeedsBlending; }
+    virtual bool isSecure() const           { return mSecure; }
+    virtual GLuint getTextureName() const   { return mTextureName; }
+    virtual sp<Surface> getSurface() const;
+
+    const LayerBitmap& getBuffer(int i) const { return mBuffers[i]; }
+          LayerBitmap& getBuffer(int i)       { return mBuffers[i]; }
+
+    // only for debugging
+    const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
+
+private:
+    inline const LayerBitmap&
+            frontBuffer() const { return getBuffer(mFrontBufferIndex); }
+    inline LayerBitmap&
+            frontBuffer()       { return getBuffer(mFrontBufferIndex); }
+    inline const LayerBitmap&
+            backBuffer() const  { return getBuffer(1-mFrontBufferIndex); }
+    inline LayerBitmap&
+            backBuffer()        { return getBuffer(1-mFrontBufferIndex); }
+
+    void reloadTexture(const Region& dirty);
+
+    status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what);
+    Region post(uint32_t* oldState, bool& recomputeVisibleRegions);
+    status_t reallocateBuffer(int32_t index, uint32_t w, uint32_t h);
+
+    sp<Surface>             mSurface;
+
+            bool            mSecure;
+            LayerBitmap     mBuffers[2];
+            int32_t         mFrontBufferIndex;
+            bool            mNeedsBlending;
+            bool            mResizeTransactionDone;
+            Region          mPostedDirtyRegion;
+            sp<FreezeLock>  mFreezeLock;
+            
+            GLuint          mTextureName;
+            GLuint          mTextureWidth;
+            GLuint          mTextureHeight;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_H
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
new file mode 100644
index 0000000..17c9f42
--- /dev/null
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -0,0 +1,700 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "clz.h"
+#include "LayerBase.h"
+#include "LayerBlur.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+// We don't honor the premultipliad alpha flags, which means that
+// premultiplied surface may be composed using a non-premultiplied
+// equation. We do this because it may be a lot faster on some hardware
+// The correct value is HONOR_PREMULTIPLIED_ALPHA = 1
+#define HONOR_PREMULTIPLIED_ALPHA   0
+
+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";
+
+// ---------------------------------------------------------------------------
+
+Vector<GLuint> LayerBase::deletedTextures; 
+
+int32_t LayerBase::sIdentity = 0;
+
+LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
+    : dpy(display), invalidate(false),
+      mFlinger(flinger),
+      mTransformed(false),
+      mOrientation(0),
+      mCanUseCopyBit(false),
+      mTransactionFlags(0),
+      mPremultipliedAlpha(true),
+      mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
+{
+    const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
+    mFlags = hw.getFlags();
+}
+
+LayerBase::~LayerBase()
+{
+}
+
+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.alpha     = 0xFF;
+    mCurrentState.flags     = layerFlags;
+    mCurrentState.sequence  = 0;
+    mCurrentState.transform.set(0, 0);
+
+    // drawing state & current state are identical
+    mDrawingState = mCurrentState;
+}
+
+void LayerBase::commitTransaction(bool skipSize) {
+    const uint32_t w = mDrawingState.w;
+    const uint32_t h = mDrawingState.h;
+    mDrawingState = mCurrentState;
+    if (skipSize) {
+        mDrawingState.w = w;
+        mDrawingState.h = h;
+    }
+}
+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);
+}
+
+void LayerBase::setSizeChanged(uint32_t w, uint32_t h) {
+}
+
+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.w == w && mCurrentState.h == h)
+        return false;
+    setSizeChanged(w, h);
+    mCurrentState.w = w;
+    mCurrentState.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 (temp.sequence != front.sequence) {
+        // invalidate and recompute the visible regions if needed
+        flags |= eVisibleRegion;
+        this->invalidate = true;
+    }
+    
+    // Commit the transaction
+    commitTransaction(flags & eRestartTransaction);
+    return flags;
+}
+
+Point LayerBase::getPhysicalSize() const
+{
+    const Layer::State& front(drawingState());
+    return Point(front.w, front.h);
+}
+
+void LayerBase::validateVisibility(const Transform& planeTransform)
+{
+    const Layer::State& s(drawingState());
+    const Transform tr(planeTransform * s.transform);
+    const bool transformed = tr.transformed();
+   
+    const Point size(getPhysicalSize());
+    uint32_t w = size.x;
+    uint32_t h = size.y;    
+    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();
+
+    // see if we can/should use 2D h/w with the new configuration
+    mCanUseCopyBit = false;
+    copybit_t* copybit = mFlinger->getBlitEngine();
+    if (copybit) { 
+        const int step = copybit->get(copybit, COPYBIT_ROTATION_STEP_DEG);
+        const int scaleBits = copybit->get(copybit, COPYBIT_SCALING_FRAC_BITS);
+        mCanUseCopyBit = true;
+        if ((mOrientation < 0) && (step > 1)) {
+            // arbitrary orientations not supported
+            mCanUseCopyBit = false;
+        } else if ((mOrientation > 0) && (step > 90)) {
+            // 90 deg rotations not supported
+            mCanUseCopyBit = false;
+        } else if ((tr.getType() & SkMatrix::kScale_Mask) && (scaleBits < 12)) { 
+            // arbitrary scaling not supported
+            mCanUseCopyBit = false;
+        }
+#if HONOR_PREMULTIPLIED_ALPHA 
+        else if (needsBlending() && mPremultipliedAlpha) {
+            // pre-multiplied alpha not supported
+            mCanUseCopyBit = false;
+        }
+#endif
+        else {
+            // here, we determined we can use copybit
+            if (tr.getType() & SkMatrix::kScale_Mask) {
+                // and we have scaling
+                if (!transparentRegionScreen.isRect()) {
+                    // we punt because blending is cheap (h/w) and the region is
+                    // complex, which may causes artifacts when copying
+                    // scaled content
+                    transparentRegionScreen.clear();
+                }
+            }
+        }
+    }
+}
+
+void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
+{
+}
+
+void LayerBase::unlockPageFlip(
+        const Transform& planeTransform, Region& outDirtyRegion)
+{
+}
+
+void LayerBase::finishPageFlip()
+{
+}
+
+void LayerBase::drawRegion(const Region& reg) const
+{
+    Region::iterator iterator(reg);
+    if (iterator) {
+        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 (iterator.iterate(&r)) {
+            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;
+        }        
+    }
+    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);
+    if (mFlags & DisplayHardware::SLOW_CONFIG) {
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    } else {
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    }
+    return textureName;
+}
+
+void LayerBase::clearWithOpenGL(const Region& clip) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t fbHeight = hw.getHeight();
+    glColor4x(0,0,0,0);
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+    Rect r;
+    Region::iterator iterator(clip);
+    if (iterator) {
+        glVertexPointer(2, GL_FIXED, 0, mVertices);
+        while (iterator.iterate(&r)) {
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+        }
+    }
+}
+
+void LayerBase::drawWithOpenGL(const Region& clip,
+        GLint textureName, const GGLSurface& t) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t fbHeight = hw.getHeight();
+    const State& s(drawingState());
+
+    // bind our texture
+    validateTexture(textureName);
+    glEnable(GL_TEXTURE_2D);
+
+    // Dithering...
+    if (s.flags & ISurfaceComposer::eLayerDither) {
+        glEnable(GL_DITHER);
+    } else {
+        glDisable(GL_DITHER);
+    }
+
+    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);
+        if (needsBlending()) {
+            GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+            glEnable(GL_BLEND);
+            glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+            glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
+        } else {
+            glDisable(GL_BLEND);
+        }
+    }
+
+    if (UNLIKELY(transformed()
+            || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) 
+    {
+        //StopWatch watch("GL transformed");
+        Region::iterator iterator(clip);
+        if (iterator) {
+            // always use high-quality filtering with fast configurations
+            bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
+            if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            }            
+            const GLfixed texCoords[4][2] = {
+                    { 0,        0 },
+                    { 0,        0x10000 },
+                    { 0x10000,  0x10000 },
+                    { 0x10000,  0 }
+            };
+
+            glMatrixMode(GL_TEXTURE);
+            glLoadIdentity();
+            if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
+                // find the smalest power-of-two that will accomodate our surface
+                GLuint tw = 1 << (31 - clz(t.width));
+                GLuint th = 1 << (31 - clz(t.height));
+                if (tw < t.width)  tw <<= 1;
+                if (th < t.height) th <<= 1;
+                // this divide should be relatively fast because it's
+                // a power-of-two (optimized path in libgcc)
+                GLfloat ws = GLfloat(t.width) /tw;
+                GLfloat hs = GLfloat(t.height)/th;
+                glScalef(ws, hs, 1.0f);
+            }
+
+            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+            glVertexPointer(2, GL_FIXED, 0, mVertices);
+            glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+            Rect r;
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+            }
+
+            if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+            }
+            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        }
+    } else {
+        Region::iterator iterator(clip);
+        if (iterator) {
+            Rect r;
+            GLint crop[4] = { 0, t.height, t.width, -t.height };
+            glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+            int x = tx();
+            int y = ty();
+            y = fbHeight - (y + t.height);
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawTexiOES(x, y, 0, t.width, t.height);
+            }
+        }
+    }
+}
+
+void LayerBase::validateTexture(GLint textureName) const
+{
+    glBindTexture(GL_TEXTURE_2D, textureName);
+    // TODO: reload the texture if needed
+    // this is currently done in loadTexture() below
+}
+
+void LayerBase::loadTexture(const Region& dirty,
+        GLint textureName, const GGLSurface& t,
+        GLuint& textureWidth, GLuint& textureHeight) const
+{
+    // TODO: defer the actual texture reload until LayerBase::validateTexture
+    // is called.
+
+    uint32_t flags = mFlags;
+    glBindTexture(GL_TEXTURE_2D, textureName);
+
+    GLuint tw = t.width;
+    GLuint th = t.height;
+
+    /*
+     * In OpenGL ES we can't specify a stride with glTexImage2D (however,
+     * GL_UNPACK_ALIGNMENT is 4, which in essence allows 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
+     */
+
+    tw += (((t.stride - tw) * bytesPerPixel(t.format)) / 4);
+
+    /*
+     * round to POT if needed 
+     */
+    
+    GLuint texture_w = tw;
+    GLuint texture_h = th;
+    if (!(flags & DisplayHardware::NPOT_EXTENSION)) {
+        // find the smalest power-of-two that will accomodate our surface
+        texture_w = 1 << (31 - clz(t.width));
+        texture_h = 1 << (31 - clz(t.height));
+        if (texture_w < t.width)  texture_w <<= 1;
+        if (texture_h < t.height) texture_h <<= 1;
+        if (texture_w != tw || texture_h != th) {
+            // we can't use DIRECT_TEXTURE since we changed the size
+            // of the texture
+            flags &= ~DisplayHardware::DIRECT_TEXTURE;
+        }
+    }
+
+    if (flags & DisplayHardware::DIRECT_TEXTURE) {
+        // here we're guaranteed that texture_{w|h} == t{w|h}
+        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
+                    GL_RGB, tw, th, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t.data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
+                    GL_RGBA, tw, th, 0,
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t.data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
+                    GL_RGBA, tw, th, 0,
+                    GL_RGBA, GL_UNSIGNED_BYTE, t.data);
+        } else {
+            // oops, we don't handle this format, try the regular path
+            goto regular;
+        }
+        textureWidth = tw;
+        textureHeight = th;
+    } else {
+regular:
+        Rect bounds(dirty.bounds());
+        GLvoid* data = 0;
+        if (texture_w!=textureWidth || texture_w!=textureHeight) {
+            // texture size changed, we need to create a new one
+
+            if (!textureWidth || !textureHeight) {
+                // this is the first time, load the whole texture
+                if (texture_w==tw && texture_h==th) {
+                    // we can do it one pass
+                    data = t.data;
+                } else {
+                    // we have to create the texture first because it
+                    // doesn't match the size of the buffer
+                    bounds.set(Rect(tw, th));
+                }
+            }
+
+            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_RGB, tw, th, 0,
+                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_RGBA, tw, th, 0,
+                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_RGBA, tw, th, 0,
+                        GL_RGBA, GL_UNSIGNED_BYTE, data);
+            } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
+                        t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
+                // just show the Y plane of YUV buffers
+                data = t.data;
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_LUMINANCE, tw, th, 0,
+                        GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+            }
+            textureWidth = tw;
+            textureHeight = th;
+        }
+        if (!data) {
+            if (t.format == GGL_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.width*2);
+            } else if (t.format == GGL_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.width*2);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+                glTexSubImage2D(GL_TEXTURE_2D, 0,
+                        0, bounds.top, t.width, bounds.height(),
+                        GL_RGBA, GL_UNSIGNED_BYTE,
+                        t.data + bounds.top*t.width*4);
+            }
+        }
+    }
+}
+
+bool LayerBase::canUseCopybit() const
+{
+    return mCanUseCopyBit;
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
+        Client* c, int32_t i)
+    : LayerBase(flinger, display), client(c),
+      lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ),
+      mIndex(i)
+{
+    if (client) {
+        client->bindLayer(this, i);
+
+        // Initialize this layer's control block
+        memset(this->lcblk, 0, sizeof(layer_cblk_t));
+        this->lcblk->identity = mIdentity;
+        Region::writeEmpty(&(this->lcblk->region[0]), sizeof(flat_region_t));
+        Region::writeEmpty(&(this->lcblk->region[1]), sizeof(flat_region_t));
+    }
+}
+
+LayerBaseClient::~LayerBaseClient()
+{
+    if (client) {
+        client->free(mIndex);
+    }
+}
+
+int32_t LayerBaseClient::serverIndex() const {
+    if (client) {
+        return (client->cid<<16)|mIndex;
+    }
+    return 0xFFFF0000 | mIndex;
+}
+
+sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() const
+{
+    return new Surface(clientIndex(), mIdentity);
+}
+
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
new file mode 100644
index 0000000..10c1bc1
--- /dev/null
+++ b/libs/surfaceflinger/LayerBase.h
@@ -0,0 +1,271 @@
+/*
+ * 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 <private/ui/LayerState.h>
+
+#include <ui/Region.h>
+#include <pixelflinger/pixelflinger.h>
+
+#include "Transform.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class SurfaceFlinger;
+class DisplayHardware;
+class GraphicPlane;
+class Client;
+
+// ---------------------------------------------------------------------------
+
+class LayerBase
+{
+    // 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;
+    }
+
+    
+    static Vector<GLuint> deletedTextures; 
+
+    LayerBase(SurfaceFlinger* flinger, DisplayID display);
+    virtual ~LayerBase();
+    
+    DisplayID           dpy;
+    mutable bool        invalidate;
+            Region      visibleRegionScreen;
+            Region      transparentRegionScreen;
+            Region      coveredRegionScreen;
+            
+            struct State {
+                uint32_t        w;
+                uint32_t        h;
+                uint32_t        z;
+                uint8_t         alpha;
+                uint8_t         flags;
+                uint8_t         sequence;   // changes when visible regions can change
+                uint8_t         reserved;
+                uint32_t        tint;
+                Transform       transform;
+                Region          transparentRegion;
+            };
+
+            // 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 skipSize);
+            bool requestTransaction();
+
+            uint32_t getTransactionFlags(uint32_t flags);
+            uint32_t setTransactionFlags(uint32_t flags);
+            
+            void validateVisibility(const Transform& globalTransform);
+            Rect visibleBounds() const;
+            void drawRegion(const Region& reg) const;
+
+    virtual void draw(const Region& clip) const;
+    virtual void onDraw(const Region& clip) const = 0;
+    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+    virtual void setSizeChanged(uint32_t w, uint32_t h);
+    virtual uint32_t doTransaction(uint32_t transactionFlags);
+    virtual void setVisibleRegion(const Region& visibleRegion);
+    virtual void setCoveredRegion(const Region& coveredRegion);
+    virtual Point getPhysicalSize() const;
+    virtual void lockPageFlip(bool& recomputeVisibleRegions);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    virtual void finishPageFlip();
+    virtual bool needsBlending() const  { return false; }
+    virtual bool isSecure() const       { return false; }
+
+            enum { // flags for doTransaction()
+                eVisibleRegion      = 0x00000002,
+                eRestartTransaction = 0x00000008
+            };
+
+
+    inline  const State&    drawingState() const    { return mDrawingState; }
+    inline  const State&    currentState() const    { return mCurrentState; }
+    inline  State&          currentState()          { return mCurrentState; }
+
+    static int compareCurrentStateZ(LayerBase*const* layerA, LayerBase*const* layerB) {
+        return layerA[0]->currentState().z - layerB[0]->currentState().z;
+    }
+
+    int32_t  getOrientation() const { return mOrientation; }
+    bool transformed() const    { return mTransformed; }
+    int  tx() const             { return mLeft; }
+    int  ty() const             { return mTop; }
+    
+protected:
+    const GraphicPlane& graphicPlane(int dpy) const;
+          GraphicPlane& graphicPlane(int dpy);
+
+          GLuint createTexture() const;
+    
+          void drawWithOpenGL(const Region& clip,
+                  GLint textureName, const GGLSurface& surface) const;
+
+          void clearWithOpenGL(const Region& clip) const;
+
+          void loadTexture(const Region& dirty,
+                  GLint textureName, const GGLSurface& t,
+                  GLuint& textureWidth, GLuint& textureHeight) const;
+
+          bool canUseCopybit() const;
+          
+          
+                SurfaceFlinger* mFlinger;
+                uint32_t        mFlags;
+
+                // cached during validateVisibility()
+                bool            mTransformed;
+                int32_t         mOrientation;
+                GLfixed         mVertices[4][2];
+                Rect            mTransformedBounds;
+                bool            mCanUseCopyBit;
+                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;
+
+                // only read
+     const      uint32_t        mIdentity;
+                
+
+private:
+                void validateTexture(GLint textureName) const;
+    static      int32_t         sIdentity;
+};
+
+
+// ---------------------------------------------------------------------------
+
+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; }
+
+    LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 
+            Client* client, int32_t i);
+    virtual ~LayerBaseClient();
+
+
+    Client*             const client;
+    layer_cblk_t*       const lcblk;
+
+    inline  int32_t     clientIndex() const { return mIndex; }
+            int32_t     serverIndex() const;
+
+    virtual sp<Surface> getSurface() const;
+   
+            uint32_t    getIdentity() const { return mIdentity; }
+
+    class Surface : public BnSurface 
+    {
+    public:
+        Surface(SurfaceID id, int identity) { 
+            mParams.token = id;
+            mParams.identity = identity;
+            mParams.type = 0;
+        }
+        Surface(SurfaceID id, 
+                const sp<IMemoryHeap>& heap0,
+                const sp<IMemoryHeap>& heap1,
+                int memory_type, int identity)
+        {
+            mParams.token = id;
+            mParams.identity = identity;
+            mParams.type = memory_type;
+            mParams.heap[0] = heap0;
+            mParams.heap[1] = heap1;
+        }
+        virtual ~Surface() {
+            // TODO: We now have a point here were we can clean-up the
+            // client's mess.
+            // This is also where surface id should be recycled.
+            //LOGD("Surface %d, heaps={%p, %p}, type=%d destroyed",
+            //        mId, mHeap[0].get(), mHeap[1].get(), mMemoryType);
+        }
+
+        virtual void getSurfaceData(
+                ISurfaceFlingerClient::surface_data_t* params) const {
+            *params = mParams;
+        }
+
+        virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
+                PixelFormat format, const sp<IMemoryHeap>& heap) 
+                { return INVALID_OPERATION; }
+        virtual void postBuffer(ssize_t offset) { }
+        virtual void unregisterBuffers() { };
+
+    private:
+        ISurfaceFlingerClient::surface_data_t mParams;
+    };
+
+private:
+    int32_t mIndex;
+
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BASE_H
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
new file mode 100644
index 0000000..7c98857
--- /dev/null
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -0,0 +1,188 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/memory.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/MemoryDealer.h>
+#include <utils/IMemory.h>
+#include <ui/PixelFormat.h>
+#include <pixelflinger/pixelflinger.h>
+
+#include "LayerBitmap.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+LayerBitmap::LayerBitmap()
+    : mAllocFlags(0), mOffset(0), mSize(-1U), mAlignment(2)
+{
+    memset(&mSurface, 0, sizeof(mSurface));
+}
+
+LayerBitmap::~LayerBitmap()
+{
+    mSurface.data = 0;
+}
+
+status_t LayerBitmap::init(const sp<MemoryDealer>& allocator)
+{
+    if (mAllocator != NULL)
+        return BAD_VALUE;
+    mAllocator = allocator;
+    return NO_ERROR;
+}
+
+status_t LayerBitmap::setBits(uint32_t w, uint32_t h, uint32_t alignment, 
+        PixelFormat format, uint32_t flags)
+{
+    const sp<MemoryDealer>& allocator(mAllocator);
+    if (allocator == NULL)
+        return NO_INIT;
+
+    if (UNLIKELY(w == mSurface.width && h == mSurface.height &&
+            format == mSurface.format))
+    { // same format and size, do nothing.
+        return NO_ERROR;
+    }
+
+    uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED;
+    const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT
+    const uint32_t Bpp = bytesPerPixel(format);
+    uint32_t stride = (w + (alignment-1)) & ~(alignment-1);
+    stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp;
+    size_t size = stride * h * Bpp;
+    if (format == PIXEL_FORMAT_YCbCr_422_SP ||
+        format == PIXEL_FORMAT_YCbCr_420_SP) {
+        // in YUV planar, bitsPerPixel is for the Y plane
+        size = (size * bitsPerPixel(format)) / 8;
+    }
+
+    if (allocFlags & MemoryDealer::PAGE_ALIGNED) {
+        size_t pagesize = getpagesize();
+        size = (size + (pagesize-1)) & ~(pagesize-1);
+    }
+
+    /* FIXME: we should be able to have a h/v stride because the user of the
+     * surface might have stride limitation (for instance h/w codecs often do)
+     */
+    int32_t vstride = 0;
+
+    mAlignment = alignment;
+    mAllocFlags = allocFlags;
+    mOffset = 0;
+    if (mSize != size) {
+        // would be nice to have a reallocate() api
+        mBitsMemory.clear(); // free-memory
+        mBitsMemory = allocator->allocate(size, allocFlags);
+        mSize = size;
+    } else {
+        // don't erase memory if we didn't have to reallocate
+        flags &= ~SECURE_BITS;
+    }
+    if (mBitsMemory != 0) {
+        mOffset = mBitsMemory->offset();
+        mSurface.data = static_cast<GGLubyte*>(mBitsMemory->pointer());
+        mSurface.version = sizeof(GGLSurface);
+        mSurface.width  = w;
+        mSurface.height = h;
+        mSurface.stride = stride;
+        mSurface.vstride = vstride;
+        mSurface.format = format;
+        if (flags & SECURE_BITS)
+            clear();
+    }
+
+    if (mBitsMemory==0 || mSurface.data==0) {
+        LOGE("not enough memory for layer bitmap size=%u", size);
+        allocator->dump("LayerBitmap");
+        mSurface.data = 0;
+        mSize = -1U;
+        return NO_MEMORY;
+    }
+    return NO_ERROR;
+}
+
+void LayerBitmap::clear()
+{
+    // NOTE: this memset should not be necessary, at least for
+    // opaque surface. However, for security reasons it's better to keep it
+    // (in the case of pmem, it's possible that the memory contains old
+    // data)
+    if (mSurface.data) {
+        memset(mSurface.data, 0, mSize);
+        //if (bytesPerPixel(mSurface.format) == 4) {
+        //    android_memset32((uint32_t*)mSurface.data, 0xFF0000FF, mSize);
+        //} else  {
+        //    android_memset16((uint16_t*)mSurface.data, 0xF800, mSize);
+        //}
+    }
+}
+
+status_t LayerBitmap::getInfo(surface_info_t* info) const
+{
+    if (mSurface.data == 0) {
+        memset(info, 0, sizeof(surface_info_t));
+        info->bits_offset = NO_MEMORY;
+        return NO_MEMORY;
+    }
+    info->w     = uint16_t(width());
+    info->h     = uint16_t(height());
+    info->stride= uint16_t(stride());
+    info->bpr   = uint16_t(stride() * bytesPerPixel(pixelFormat()));
+    info->format= uint8_t(pixelFormat());
+    info->flags = surface_info_t::eBufferDirty;
+    info->bits_offset = ssize_t(mOffset);
+    return NO_ERROR;
+}
+
+status_t LayerBitmap::resize(uint32_t w, uint32_t h)
+{
+    int err = setBits(w, h, mAlignment, pixelFormat(), SECURE_BITS);
+    return err;
+}
+
+size_t LayerBitmap::size() const
+{
+    return mSize;
+}
+
+void LayerBitmap::getBitmapSurface(copybit_image_t* img) const
+{
+    const sp<IMemoryHeap>& mh(getAllocator()->getMemoryHeap());
+    void* sbase = mh->base();
+    const GGLSurface& t(surface());
+    img->w = t.stride  ?: t.width;
+    img->h = t.vstride ?: t.height;
+    img->format = t.format;
+    img->offset = intptr_t(t.data) - intptr_t(sbase);
+    img->base = sbase;
+    img->fd = mh->heapID();
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
new file mode 100644
index 0000000..4c2eb50
--- /dev/null
+++ b/libs/surfaceflinger/LayerBitmap.h
@@ -0,0 +1,87 @@
+/*
+ * 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_BITMAP_H
+#define ANDROID_LAYER_BITMAP_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Atomic.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <private/ui/SharedState.h>
+#include <pixelflinger/pixelflinger.h>
+
+class copybit_image_t;
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class IMemory;
+class MemoryDealer;
+class LayerBitmap;
+
+// ---------------------------------------------------------------------------
+
+class LayerBitmap
+{
+public:
+
+    enum {
+        // erase memory to ensure security when necessary
+        SECURE_BITS = 0x00000001
+    };
+
+                LayerBitmap();
+                ~LayerBitmap();
+    status_t    init(const sp<MemoryDealer>& allocator);
+
+    status_t    setBits(uint32_t w, uint32_t h, uint32_t alignment,
+                        PixelFormat format, uint32_t flags = 0);
+    void        clear();
+
+    status_t    getInfo(surface_info_t* info) const;
+    status_t    resize(uint32_t w, uint32_t h);
+
+    const GGLSurface& surface() const   { return mSurface; }
+    Rect bounds() const                 { return Rect(width(), height()); }
+    uint32_t width() const              { return surface().width; }
+    uint32_t height() const             { return surface().height; }
+    uint32_t stride() const             { return surface().stride; }
+    PixelFormat pixelFormat() const     { return surface().format; }
+    void* serverBits() const            { return surface().data; }
+    size_t size() const;
+    const sp<MemoryDealer>& getAllocator() const { return mAllocator; }
+    void getBitmapSurface(copybit_image_t* img) const;
+
+private:
+    LayerBitmap(const LayerBitmap& rhs);
+    LayerBitmap& operator = (const LayerBitmap& rhs);
+
+    sp<MemoryDealer>        mAllocator;
+    sp<IMemory>             mBitsMemory;
+    uint32_t                mAllocFlags;
+    ssize_t                 mOffset;
+    GGLSurface              mSurface;
+    size_t                  mSize;
+    uint32_t                mAlignment;
+};
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BITMAP_H
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
new file mode 100644
index 0000000..192ceda
--- /dev/null
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -0,0 +1,229 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.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,
+        Client* client, int32_t i)
+     : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
+     mRefreshCache(true), mCacheAge(0), mTextureName(-1U)
+{
+}
+
+LayerBlur::~LayerBlur()
+{
+    if (mTextureName != -1U) {
+        //glDeleteTextures(1, &mTextureName);
+        deletedTextures.add(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->invalidate = 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);
+    }
+
+    Region::iterator iterator(clip);
+    if (iterator) {
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, mTextureName);
+    
+        if (mRefreshCache) {
+            mRefreshCache = false;
+            mAutoRefreshPending = false;
+            
+            uint16_t* const pixels = (uint16_t*)malloc(w*h*2);
+
+            // 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.
+            glReadPixels(X, Y, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+            
+            // blur that texture.
+            GGLSurface bl;
+            bl.version = sizeof(GGLSurface);
+            bl.width = w;
+            bl.height = h;
+            bl.stride = w;
+            bl.format = GGL_PIXEL_FORMAT_RGB_565;
+            bl.data = (GGLubyte*)pixels;            
+            blurFilter(&bl, 8, 2);
+            
+            // NOTE: this works only because we have POT. we'd have to round the
+            // texture size up, otherwise.
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+
+            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);
+        }
+
+        glDisable(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(1.0f/w, -1.0f/h, 1);
+            glTranslatef(-x, -y, 0);
+            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+            glVertexPointer(2, GL_FIXED, 0, mVertices);
+            glTexCoordPointer(2, GL_FIXED, 0, mVertices);
+            Rect r;
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+            }       
+        } else {
+            Region::iterator iterator(clip);
+            if (iterator) {
+                // 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 (iterator.iterate(&r)) {
+                    const GLint sy = fbHeight - (r.top + r.height());
+                    glScissor(r.left, sy, r.width(), r.height());
+                    glDrawTexiOES(x, y, 0, w, h);
+                }
+            }
+        }
+    }
+
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
new file mode 100644
index 0000000..24b1156
--- /dev/null
+++ b/libs/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 <private/ui/LayerState.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,
+                        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;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BLUR_H
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
new file mode 100644
index 0000000..d871fc3
--- /dev/null
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -0,0 +1,366 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#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/PixelFormat.h>
+#include <ui/EGLDisplaySurface.h>
+
+#include "LayerBuffer.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20;
+const char* const LayerBuffer::typeID = "LayerBuffer";
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
+        Client* client, int32_t i)
+    : LayerBaseClient(flinger, display, client, i),
+    mBuffer(0), mTextureName(-1U), mInvalidate(false), mNeedsBlending(false)
+{
+}
+
+LayerBuffer::~LayerBuffer()
+{
+    sp<SurfaceBuffer> s(getClientSurface());
+    if (s != 0) {
+        s->disown();
+        mClientSurface.clear();
+    }
+
+    // this should always be called from the OpenGL thread
+    if (mTextureName != -1U) {
+        //glDeleteTextures(1, &mTextureName);
+        deletedTextures.add(mTextureName);
+    }
+    // to help debugging we set those to zero
+    mWidth = mHeight = 0;
+}
+
+bool LayerBuffer::needsBlending() const
+{
+    Mutex::Autolock _l(mLock);
+    return mNeedsBlending;
+}
+
+void LayerBuffer::onDraw(const Region& clip) const
+{
+    sp<Buffer> buffer(getBuffer());
+    if (UNLIKELY(buffer == 0))  {
+        // nothing to do, we don't have a buffer
+        clearWithOpenGL(clip);
+        return;
+    }
+
+    status_t err = NO_ERROR;
+    NativeBuffer src(buffer->getBuffer());
+    const int can_use_copybit = canUseCopybit();
+
+    if (can_use_copybit)  {
+        //StopWatch watch("MDP");
+
+        const int src_width  = src.crop.r - src.crop.l;
+        const int src_height = src.crop.b - src.crop.t;
+        int W = mTransformedBounds.width();
+        int H = mTransformedBounds.height();
+        if (getOrientation() & Transform::ROT_90) {
+            int t(W); W=H; H=t;
+        }
+
+        /* With LayerBuffer, it is likely that we'll have to rescale the
+         * surface, because this is often used for video playback or
+         * camera-preview. Since we want these operation as fast as possible
+         * we make sure we can use the 2D H/W even if it doesn't support
+         * the requested scale factor, in which case we perform the scaling
+         * in several passes. */
+
+        copybit_t* copybit = mFlinger->getBlitEngine();
+        const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
+        const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
+
+        float xscale = 1.0f;
+        if (src_width > W*min)          xscale = 1.0f / min;
+        else if (src_width*mag < W)     xscale = mag;
+
+        float yscale = 1.0f;
+        if (src_height > H*min)         yscale = 1.0f / min;
+        else if (src_height*mag < H)    yscale = mag;
+
+        if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
+            //LOGD("MDP scaling hack w=%d, h=%d, ww=%d, wh=%d, xs=%f, ys=%f",
+            //        src_width, src_height, W, H, xscale, yscale);
+
+            if (UNLIKELY(mTemporaryDealer == 0)) {
+                // allocate a memory-dealer for this the first time
+                mTemporaryDealer = mFlinger->getSurfaceHeapManager()
+                        ->createHeap(NATIVE_MEMORY_TYPE_PMEM);
+                mTempBitmap.init(mTemporaryDealer);
+            }
+
+            const int tmp_w = floorf(src_width  * xscale);
+            const int tmp_h = floorf(src_height * yscale);
+            err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format);
+
+            if (LIKELY(err == NO_ERROR)) {
+                NativeBuffer tmp;
+                mTempBitmap.getBitmapSurface(&tmp.img);
+                tmp.crop.l = 0;
+                tmp.crop.t = 0;
+                tmp.crop.r = tmp.img.w;
+                tmp.crop.b = tmp.img.h;
+
+                region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.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.img, &src.img, &tmp.crop, &src.crop, &tmp_it);
+                src = tmp;
+            }
+        }
+
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+        copybit_image_t dst;
+        hw.getDisplaySurface(&dst);
+        const copybit_rect_t& drect
+                = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
+        const State& s(drawingState());
+        region_iterator it(clip);
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation());
+        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+        copybit->set_parameter(copybit, COPYBIT_DITHER,
+                s.flags & ISurfaceComposer::eLayerDither ?
+                        COPYBIT_ENABLE : COPYBIT_DISABLE);
+        err = copybit->stretch(copybit,
+                &dst, &src.img, &drect, &src.crop, &it);
+    }
+
+    if (!can_use_copybit || err) {
+        if (UNLIKELY(mTextureName == -1LU)) {
+            mTextureName = createTexture();
+        }
+        GLuint w = 0;
+        GLuint h = 0;
+        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*)(intptr_t(src.img.base) + src.img.offset);
+        const Region dirty(Rect(t.width, t.height));
+        loadTexture(dirty, mTextureName, t, w, h);
+        drawWithOpenGL(clip, mTextureName, t);
+    }
+}
+
+void LayerBuffer::invalidateLocked()
+{
+    mInvalidate = true;
+    mFlinger->signalEvent();
+}
+
+void LayerBuffer::invalidate()
+{
+    Mutex::Autolock _l(mLock);
+    invalidateLocked();
+}
+
+void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
+        Region& outDirtyRegion)
+{
+    Mutex::Autolock _l(mLock);
+    if (mInvalidate) {
+        mInvalidate = false;
+        outDirtyRegion.orSelf(visibleRegionScreen);
+    }
+}
+
+sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const
+{
+    Mutex::Autolock _l(mLock);
+    return mClientSurface.promote();
+}
+
+sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const
+{
+    sp<SurfaceBuffer> s;
+    Mutex::Autolock _l(mLock);
+    s = mClientSurface.promote();
+    if (s == 0) {
+        s = new SurfaceBuffer(clientIndex(),
+                const_cast<LayerBuffer *>(this));
+        mClientSurface = s;
+    }
+    return s;
+}
+
+
+status_t LayerBuffer::registerBuffers(int w, int h, int hstride, int vstride,
+            PixelFormat format, const sp<IMemoryHeap>& memoryHeap)
+{
+    status_t err = (memoryHeap!=0 && memoryHeap->heapID() >= 0) ? NO_ERROR : NO_INIT;
+    if (err != NO_ERROR)
+        return err;
+
+    // TODO: validate format/parameters
+
+    Mutex::Autolock _l(mLock);
+    mHeap = memoryHeap;
+    mWidth = w;
+    mHeight = h;
+    mHStride = hstride;
+    mVStride = vstride;
+    mFormat = format;
+    PixelFormatInfo info;
+    getPixelFormatInfo(format, &info);
+    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
+    return NO_ERROR;
+}
+
+void LayerBuffer::postBuffer(ssize_t offset)
+{
+    sp<IMemoryHeap> heap;
+    int w, h, hs, vs, f;
+    { // scope for the lock
+        Mutex::Autolock _l(mLock);
+        w = mWidth;
+        h = mHeight;
+        hs= mHStride;
+        vs= mVStride;
+        f = mFormat;
+        heap = mHeap;
+    }
+
+    sp<Buffer> buffer;
+    if (heap != 0) {
+        buffer = new Buffer(heap, offset, w, h, hs, vs, f);
+        if (buffer->getStatus() != NO_ERROR)
+            buffer.clear();
+        setBuffer(buffer);
+        invalidate();
+    }
+}
+
+void LayerBuffer::unregisterBuffers()
+{
+    Mutex::Autolock _l(mLock);
+    mHeap.clear();
+    mBuffer.clear();
+    invalidateLocked();
+}
+
+sp<LayerBuffer::Buffer> LayerBuffer::getBuffer() const
+{
+    Mutex::Autolock _l(mLock);
+    return mBuffer;
+}
+
+void LayerBuffer::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
+{
+    Mutex::Autolock _l(mLock);
+    mBuffer = buffer;
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner)
+    : LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner)
+{
+}
+
+LayerBuffer::SurfaceBuffer::~SurfaceBuffer()
+{
+    unregisterBuffers();
+    mOwner = 0;
+}
+
+status_t LayerBuffer::SurfaceBuffer::registerBuffers(
+        int w, int h, int hs, int vs,
+        PixelFormat format, const sp<IMemoryHeap>& heap)
+{
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        return owner->registerBuffers(w, h, hs, vs, format, heap);
+    return NO_INIT;
+}
+
+void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset)
+{
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        owner->postBuffer(offset);
+}
+
+void LayerBuffer::SurfaceBuffer::unregisterBuffers()
+{
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        owner->unregisterBuffers();
+}
+
+void LayerBuffer::SurfaceBuffer::disown()
+{
+    Mutex::Autolock _l(mLock);
+    mOwner = 0;
+}
+
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::Buffer::Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
+        int w, int h, int hs, int vs, int f)
+    : mCount(0), mHeap(heap)
+{
+    NativeBuffer& src(mNativeBuffer);
+    src.crop.l = 0;
+    src.crop.t = 0;
+    src.crop.r = w;
+    src.crop.b = h;
+    src.img.w = hs ?: w;
+    src.img.h = vs ?: h;
+    src.img.format = f;
+    src.img.offset = offset;
+    src.img.base   = heap->base();
+    src.img.fd     = heap->heapID();
+    // FIXME: make sure this buffer lies within the heap, in which case, set
+    // mHeap to null
+}
+
+LayerBuffer::Buffer::~Buffer()
+{
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
new file mode 100644
index 0000000..ef473dd
--- /dev/null
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -0,0 +1,145 @@
+/*
+ * 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 <utils/IMemory.h>
+#include <private/ui/LayerState.h>
+#include <GLES/eglnatives.h>
+
+#include "LayerBase.h"
+#include "LayerBitmap.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MemoryDealer;
+class Region;
+
+class LayerBuffer : 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; }
+
+            LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
+                        Client* client, int32_t i);
+        virtual ~LayerBuffer();
+
+    virtual bool needsBlending() const;
+
+    virtual sp<LayerBaseClient::Surface> getSurface() const;
+    virtual void onDraw(const Region& clip) const;
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+
+    status_t registerBuffers(int w, int h, int hstride, int vstride,
+            PixelFormat format, const sp<IMemoryHeap>& heap);
+    void postBuffer(ssize_t offset);
+    void unregisterBuffers();
+    void invalidate();
+    void invalidateLocked();
+
+private:
+
+    struct NativeBuffer
+    {
+        copybit_image_t   img;
+        copybit_rect_t    crop;
+    };
+
+    class Buffer
+    {
+    public:
+        Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
+                int w, int h, int hs, int vs, int f);
+        inline void incStrong(void*) const {
+            android_atomic_inc(&mCount);
+        }
+        inline void decStrong(void*) const {
+            int32_t c = android_atomic_dec(&mCount);
+            //LOGE_IF(c<1, "Buffer::decStrong() called too many times");
+            if (c == 1) {
+                 delete this;
+             }
+        }
+        inline status_t getStatus() const {
+            return mHeap!=0 ? NO_ERROR : NO_INIT;
+        }
+        inline const NativeBuffer& getBuffer() const {
+            return mNativeBuffer;
+        }
+    protected:
+        Buffer& operator = (const Buffer& rhs);
+        Buffer(const Buffer& rhs);
+        ~Buffer();
+        mutable volatile int32_t mCount;
+    private:
+        sp<IMemoryHeap>    mHeap;
+        NativeBuffer       mNativeBuffer;
+    };
+
+    class SurfaceBuffer : public LayerBaseClient::Surface
+    {
+    public:
+                SurfaceBuffer(SurfaceID id, LayerBuffer* owner);
+        virtual ~SurfaceBuffer();
+        virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
+                PixelFormat format, const sp<IMemoryHeap>& heap);
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        void disown();
+    private:
+        LayerBuffer* getOwner() const {
+            Mutex::Autolock _l(mLock);
+            return mOwner;
+        }
+        mutable Mutex   mLock;
+        LayerBuffer*    mOwner;
+    };
+
+    friend class SurfaceFlinger;
+    sp<Buffer> getBuffer() const;
+    void       setBuffer(const sp<Buffer>& buffer);
+    sp<SurfaceBuffer>   getClientSurface() const;
+
+    mutable Mutex   mLock;
+    sp<IMemoryHeap> mHeap;
+    sp<Buffer>      mBuffer;
+    int             mWidth;
+    int             mHeight;
+    int             mHStride;
+    int             mVStride;
+    int             mFormat;
+    mutable GLuint  mTextureName;
+    bool            mInvalidate;
+    bool            mNeedsBlending;
+    mutable wp<SurfaceBuffer> mClientSurface;
+    mutable sp<MemoryDealer> mTemporaryDealer;
+    mutable LayerBitmap mTempBitmap;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BUFFER_H
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
new file mode 100644
index 0000000..fc23d53
--- /dev/null
+++ b/libs/surfaceflinger/LayerDim.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "LayerDim.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
+const char* const LayerDim::typeID = "LayerDim";
+sp<MemoryDealer> LayerDim::mDimmerDealer;
+LayerBitmap LayerDim::mDimmerBitmap;
+
+// ---------------------------------------------------------------------------
+
+LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
+        Client* client, int32_t i)
+     : LayerBaseClient(flinger, display, client, i)
+{
+}
+
+void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
+{
+    // must only be called once.
+    mDimmerDealer = flinger->getSurfaceHeapManager()
+            ->createHeap(NATIVE_MEMORY_TYPE_PMEM);
+    if (mDimmerDealer != 0) {
+        mDimmerBitmap.init(mDimmerDealer);
+        mDimmerBitmap.setBits(w, h, 1, PIXEL_FORMAT_RGB_565);
+        mDimmerBitmap.clear();
+    }
+}
+
+LayerDim::~LayerDim()
+{
+}
+
+void LayerDim::onDraw(const Region& clip) const
+{
+    const State& s(drawingState());
+
+    Region::iterator iterator(clip);
+    if (s.alpha>0 && iterator) {
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+
+        status_t err = NO_ERROR;
+        const int can_use_copybit = canUseCopybit();
+        if (can_use_copybit)  {
+            // StopWatch watch("copybit");
+            copybit_image_t dst;
+            hw.getDisplaySurface(&dst);
+            const copybit_rect_t& drect
+                = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
+
+            copybit_image_t src;
+            mDimmerBitmap.getBitmapSurface(&src);
+            const copybit_rect_t& srect(drect);
+
+            copybit_t* copybit = mFlinger->getBlitEngine();
+            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+            region_iterator it(clip);
+            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+        }
+
+        if (!can_use_copybit || err) {
+            const GGLfixed alpha = (s.alpha << 16)/255;
+            const uint32_t fbHeight = hw.getHeight();
+            glDisable(GL_TEXTURE_2D);
+            glDisable(GL_DITHER);
+            glEnable(GL_BLEND);
+            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+            glColor4x(0, 0, 0, alpha);
+            glVertexPointer(2, GL_FIXED, 0, mVertices);
+            Rect r;
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+            }
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h
new file mode 100644
index 0000000..3e37a47
--- /dev/null
+++ b/libs/surfaceflinger/LayerDim.h
@@ -0,0 +1,57 @@
+/*
+ * 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 "LayerBase.h"
+#include "LayerBitmap.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class LayerDim : 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; }
+    
+                LayerDim(SurfaceFlinger* flinger, DisplayID display,
+                        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);
+
+private:
+    static sp<MemoryDealer> mDimmerDealer;
+    static LayerBitmap mDimmerBitmap;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_DIM_H
diff --git a/libs/surfaceflinger/LayerScreenshot.cpp b/libs/surfaceflinger/LayerScreenshot.cpp
new file mode 100644
index 0000000..9b82bad
--- /dev/null
+++ b/libs/surfaceflinger/LayerScreenshot.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <graphics/SkBitmap.h>
+
+#include <ui/EGLDisplaySurface.h>
+
+#include "LayerBase.h"
+#include "LayerScreenshot.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerScreenshot::typeInfo = LayerBase::typeInfo | 0x20;
+const char* const LayerScreenshot::typeID = "LayerScreenshot";
+
+// ---------------------------------------------------------------------------
+
+LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display)
+    : LayerBase(flinger, display), mReply(0)
+{
+}
+
+LayerScreenshot::~LayerScreenshot()
+{
+}
+
+void LayerScreenshot::onDraw(const Region& clip) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    copybit_image_t dst;
+    hw.getDisplaySurface(&dst);
+    if (dst.base != 0) {
+        uint8_t const* src = (uint8_t const*)(intptr_t(dst.base) + dst.offset); 
+        const int fbWidth = dst.w;
+        const int fbHeight = dst.h;
+        const int fbFormat = dst.format;
+
+        int x = mTransformedBounds.left;
+        int y = mTransformedBounds.top;
+        int w = mTransformedBounds.width();
+        int h = mTransformedBounds.height();
+        Parcel* const reply = mReply;
+        if (reply) {
+            const size_t Bpp = bytesPerPixel(fbFormat);
+            const size_t size = w * h * Bpp;
+            int32_t cfg = SkBitmap::kNo_Config;
+            switch (fbFormat) {
+                case PIXEL_FORMAT_RGBA_4444: cfg = SkBitmap::kARGB_4444_Config;
+                case PIXEL_FORMAT_RGBA_8888: cfg = SkBitmap::kARGB_8888_Config;
+                case PIXEL_FORMAT_RGB_565:   cfg = SkBitmap::kRGB_565_Config;
+                case PIXEL_FORMAT_A_8:       cfg = SkBitmap::kA8_Config;
+            }
+            reply->writeInt32(0);
+            reply->writeInt32(cfg);
+            reply->writeInt32(w);
+            reply->writeInt32(h);
+            reply->writeInt32(w * Bpp);
+            void* data = reply->writeInplace(size);
+            if (data) {
+                uint8_t* d = (uint8_t*)data;
+                uint8_t const* s = src + (x + y*fbWidth) * Bpp;
+                if (w == fbWidth) {
+                    memcpy(d, s, w*h*Bpp);   
+                } else {
+                    for (int y=0 ; y<h ; y++) {
+                        memcpy(d, s, w*Bpp);
+                        d += w*Bpp;
+                        s += fbWidth*Bpp;
+                    }
+                }
+            }
+        }
+    }
+    mCV.broadcast();
+}
+
+void LayerScreenshot::takeScreenshot(Mutex& lock, Parcel* reply)
+{
+    mReply = reply;
+    mCV.wait(lock);
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerScreenshot.h b/libs/surfaceflinger/LayerScreenshot.h
new file mode 100644
index 0000000..2d9a8ec
--- /dev/null
+++ b/libs/surfaceflinger/LayerScreenshot.h
@@ -0,0 +1,57 @@
+/*
+ * 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_SCREENSHOT_H
+#define ANDROID_LAYER_SCREENSHOT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/threads.h>
+#include <utils/Parcel.h>
+
+#include "LayerBase.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class LayerScreenshot : public LayerBase
+{
+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; }
+    
+                LayerScreenshot(SurfaceFlinger* flinger, DisplayID display);
+        virtual ~LayerScreenshot();
+
+    virtual void onDraw(const Region& clip) const;
+    virtual bool needsBlending() const  { return true; }
+    virtual bool isSecure() const       { return false; }
+
+    void takeScreenshot(Mutex& lock, Parcel* reply);
+    
+private:
+    mutable Condition   mCV;
+    Parcel*             mReply;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_SCREENSHOT_H
diff --git a/libs/surfaceflinger/MODULE_LICENSE_APACHE2 b/libs/surfaceflinger/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/surfaceflinger/MODULE_LICENSE_APACHE2
diff --git a/libs/surfaceflinger/RFBServer.cpp b/libs/surfaceflinger/RFBServer.cpp
new file mode 100644
index 0000000..c2c1989
--- /dev/null
+++ b/libs/surfaceflinger/RFBServer.cpp
@@ -0,0 +1,722 @@
+/*
+ * 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 "RFBServer"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <netinet/in.h>
+
+#include <cutils/sockets.h>
+
+#include <utils/Log.h>
+#include <ui/Rect.h>
+
+#ifdef HAVE_ANDROID_OS
+#include <linux/input.h>
+#endif
+
+#include "RFBServer.h"
+#include "SurfaceFlinger.h"
+
+/* BUG=773511: this is a temporary hack required while developing the new
+   set of "clean kernel headers" for the Bionic C library. */
+#ifndef KEY_STAR
+#define KEY_STAR    227
+#endif
+#ifndef KEY_SHARP
+#define KEY_SHARP   228
+#endif
+#ifndef KEY_SOFT1
+#define KEY_SOFT1   229
+#endif
+#ifndef KEY_SOFT2
+#define KEY_SOFT2   230
+#endif
+#ifndef KEY_CENTER
+#define KEY_CENTER  232
+#endif
+
+// ----------------------------------------------------------------------------
+
+#define DEBUG_MSG   0
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+const int VNC_PORT = 5900;
+
+RFBServer::RFBServer(uint32_t w, uint32_t h, android::PixelFormat format)
+    : Thread(false), mFD(-1), mStatus(NO_INIT), mIoVec(0)
+{
+    mFrameBuffer.version = sizeof(mFrameBuffer);
+    mFrameBuffer.width = w;
+    mFrameBuffer.height = h;
+    mFrameBuffer.stride = w;
+    mFrameBuffer.format = format;
+    mFrameBuffer.data = 0;
+}
+
+RFBServer::~RFBServer()
+{
+    if (mRobinThread != 0) {
+        // ask the thread to exit first
+        mRobinThread->exitAndWait();
+    }
+
+    free(mFrameBuffer.data);
+
+    delete [] mIoVec;
+}
+
+void RFBServer::onFirstRef()
+{
+    run("Batman");
+}
+
+status_t RFBServer::readyToRun()
+{
+    LOGI("RFB server ready to run");
+    return NO_ERROR;
+}
+
+bool RFBServer::threadLoop()
+{
+    struct sockaddr addr;
+    socklen_t alen;
+    int serverfd = -1;
+    int port = VNC_PORT;
+
+    do {
+        retry:
+        if (serverfd < 0) {
+            serverfd = socket_loopback_server(port, SOCK_STREAM);
+            if (serverfd < 0) {
+                if ((errno == EADDRINUSE) && (port < (VNC_PORT+10))) {
+                    LOGW("port %d already in use, trying %d", port, port+1);
+                    port++;
+                    goto retry;
+                }
+                LOGE("couldn't create socket, port=%d, error %d (%s)",
+                        port, errno, strerror(errno));
+                sleep(1);
+                break;
+            }
+            fcntl(serverfd, F_SETFD, FD_CLOEXEC);
+        }
+
+        alen = sizeof(addr);
+        mFD = accept(serverfd, &addr, &alen);
+
+        if (mFD < 0) {
+            LOGE("couldn't accept(), error %d (%s)", errno, strerror(errno));
+            // we could have run out of file descriptors, wait a bit and
+            // try again.
+            sleep(1);
+            goto retry;
+        }
+        fcntl(mFD, F_SETFD, FD_CLOEXEC);
+
+        // send protocol version and Authentication method
+        mStatus = NO_ERROR;
+        handshake(3, 3, Authentication::None);
+
+        if (alive()) {
+            // create the thread we use to send data to the client
+            mRobinThread = new ServerThread(this);
+        }
+
+        while( alive() ) {
+            // client message must be destroyed at each iteration
+            // (most of the time this is a no-op)
+            ClientMessage msg;
+            waitForClientMessage(msg);
+            if (alive()) {
+                handleClientMessage(msg);
+            }
+        }
+
+    } while( alive() );
+
+    // free-up some resources
+    if (mRobinThread != 0) {
+        mRobinThread->exitAndWait();
+        mRobinThread.clear();
+    }
+
+    free(mFrameBuffer.data);
+    mFrameBuffer.data = 0;
+
+    close(mFD);
+    close(serverfd);
+    mFD = -1;
+
+    // we'll try again
+    return true;
+}
+
+// ----------------------------------------------------------------------------
+
+RFBServer::ServerThread::ServerThread(const sp<RFBServer>& receiver)
+            : Thread(false), mReceiver(receiver)
+{
+    LOGD("RFB Server Thread created");
+}
+
+RFBServer::ServerThread::~ServerThread()
+{
+    LOGD("RFB Server Thread destroyed");
+}
+
+void RFBServer::ServerThread::onFirstRef()
+{
+    mUpdateBarrier.close();
+    run("Robin");
+}
+
+status_t RFBServer::ServerThread::readyToRun()
+{
+    return NO_ERROR;
+}
+
+void RFBServer::ServerThread::wake()
+{
+    mUpdateBarrier.open();
+}
+
+void RFBServer::ServerThread::exitAndWait()
+{
+    requestExit();
+    mUpdateBarrier.open();
+    requestExitAndWait();
+}
+
+bool RFBServer::ServerThread::threadLoop()
+{
+    sp<RFBServer> receiver(mReceiver.promote());
+    if (receiver == 0)
+        return false;
+
+    // wait for something to do
+    mUpdateBarrier.wait();
+
+    // we're asked to quit, abort everything
+    if (exitPending())
+        return false;
+
+    mUpdateBarrier.close();
+
+    // process updates
+    receiver->sendFrameBufferUpdates();
+    return !exitPending();
+}
+
+// ----------------------------------------------------------------------------
+
+void RFBServer::handshake(uint8_t major, uint8_t minor, uint32_t auth)
+{
+    ProtocolVersion protocolVersion(major, minor);
+    if( !write(protocolVersion) )
+        return;
+
+    if ( !read(protocolVersion) )
+        return;
+
+    int maj, min;
+    if ( protocolVersion.decode(maj, min) != NO_ERROR ) {
+        mStatus = -1;
+        return;
+    }
+
+#if DEBUG_MSG
+    LOGD("client protocol string: <%s>", (char*)protocolVersion.payload());
+    LOGD("client wants protocol version %d.%d\n", maj, min);
+#endif
+
+    Authentication authentication(auth);
+    if( !write(authentication) )
+        return;
+
+    ClientInitialization clientInit;
+    if ( !read(clientInit) )
+        return;
+
+#if DEBUG_MSG
+    LOGD("client initialization: sharedFlags = %d\n", clientInit.sharedFlags());
+#endif
+
+    ServerInitialization serverInit("Android RFB");
+    ServerInitialization::Payload& message(serverInit.message());
+        message.framebufferWidth = htons(mFrameBuffer.width);
+        message.framebufferHeight = htons(mFrameBuffer.height);
+        message.serverPixelFormat.bitsPerPixel = 16;
+        message.serverPixelFormat.depth = 16;
+        message.serverPixelFormat.bigEndianFlag = 0;
+        message.serverPixelFormat.trueColorFlag = 1;
+        message.serverPixelFormat.redMax   = htons((1<<5)-1);
+        message.serverPixelFormat.greenMax = htons((1<<6)-1);
+        message.serverPixelFormat.blueMax  = htons((1<<5)-1);
+        message.serverPixelFormat.redShift     = 11;
+        message.serverPixelFormat.greenShift   = 5;
+        message.serverPixelFormat.blueShift    = 0;
+
+    mIoVec = new iovec[mFrameBuffer.height];
+
+    write(serverInit);
+}
+
+void RFBServer::handleClientMessage(const ClientMessage& msg)
+{
+    switch(msg.type()) {
+    case SET_PIXEL_FORMAT:
+        handleSetPixelFormat(msg.messages().setPixelFormat);
+        break;
+    case SET_ENCODINGS:
+        handleSetEncodings(msg.messages().setEncodings);
+        break;
+    case FRAME_BUFFER_UPDATE_REQ:
+        handleFrameBufferUpdateReq(msg.messages().frameBufferUpdateRequest);
+        break;
+    case KEY_EVENT:
+        handleKeyEvent(msg.messages().keyEvent);
+        break;
+    }
+}
+
+void RFBServer::handleSetPixelFormat(const SetPixelFormat& msg)
+{
+    if (!validatePixelFormat(msg.pixelFormat)) {
+        LOGE("The builtin VNC server only supports the RGB 565 pixel format");
+        LOGD("requested pixel format:");
+        LOGD("bitsPerPixel:     %d", msg.pixelFormat.bitsPerPixel);
+        LOGD("depth:            %d", msg.pixelFormat.depth);
+        LOGD("bigEndianFlag:    %d", msg.pixelFormat.bigEndianFlag);
+        LOGD("trueColorFlag:    %d", msg.pixelFormat.trueColorFlag);
+        LOGD("redmax:           %d", ntohs(msg.pixelFormat.redMax));
+        LOGD("bluemax:          %d", ntohs(msg.pixelFormat.greenMax));
+        LOGD("greenmax:         %d", ntohs(msg.pixelFormat.blueMax));
+        LOGD("redshift:         %d", msg.pixelFormat.redShift);
+        LOGD("greenshift:       %d", msg.pixelFormat.greenShift);
+        LOGD("blueshift:        %d", msg.pixelFormat.blueShift);
+        mStatus = -1;
+    }
+}
+
+bool RFBServer::validatePixelFormat(const PixelFormat& pf)
+{
+    if ((pf.bitsPerPixel != 16) || (pf.depth != 16))
+        return false;
+
+    if (pf.bigEndianFlag || !pf.trueColorFlag)
+        return false;
+
+    if (ntohs(pf.redMax)!=0x1F ||
+        ntohs(pf.greenMax)!=0x3F ||
+        ntohs(pf.blueMax)!=0x1F) {
+        return false;
+    }
+
+    if (pf.redShift!=11 || pf.greenShift!=5 || pf.blueShift!=0)
+        return false;
+
+    return true;
+}
+
+void RFBServer::handleSetEncodings(const SetEncodings& msg)
+{
+    /* From the RFB specification:
+        Sets the encoding types in which pixel data can be sent by the server.
+        The order of the encoding types given in this message is a hint by the
+        client as to its preference (the first encoding specified being most
+        preferred). The server may or may not choose to make use of this hint.
+        Pixel data may always be sent in raw encoding even if not specified
+        explicitly here.
+    */
+
+    LOGW("SetEncodings received. Only RAW is supported.");
+}
+
+void RFBServer::handleFrameBufferUpdateReq(const FrameBufferUpdateRequest& msg)
+{
+#if DEBUG_MSG
+    LOGD("handle FrameBufferUpdateRequest");
+#endif
+
+    Rect r;
+    r.left = ntohs(msg.x);
+    r.top = ntohs(msg.y);
+    r.right = r.left + ntohs(msg.width);
+    r.bottom = r.top + ntohs(msg.height);
+
+    Mutex::Autolock _l(mRegionLock);
+    mClientRegionRequest.set(r);
+    if (!msg.incremental)
+        mDirtyRegion.orSelf(r);
+
+    mRobinThread->wake();
+}
+
+void RFBServer::handleKeyEvent(const KeyEvent& msg)
+{
+#ifdef HAVE_ANDROID_OS
+
+    int scancode = 0;
+    int code = ntohl(msg.key);
+
+    if (code>='0' && code<='9') {
+        scancode = (code & 0xF) - 1;
+        if (scancode<0) scancode += 10;
+        scancode += KEY_1;
+    } else if (code>=0xFF50 && code<=0xFF58) {
+        static const uint16_t map[] =
+             {  KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN,
+                KEY_SOFT1, KEY_SOFT2, KEY_END, 0 };
+        scancode = map[code & 0xF];
+    } else if (code>=0xFFE1 && code<=0xFFEE) {
+        static const uint16_t map[] =
+             {  KEY_LEFTSHIFT, KEY_LEFTSHIFT,
+                KEY_COMPOSE, KEY_COMPOSE,
+                KEY_LEFTSHIFT, KEY_LEFTSHIFT,
+                0,0,
+                KEY_LEFTALT, KEY_RIGHTALT,
+                0, 0, 0, 0 };
+        scancode = map[code & 0xF];
+    } else if ((code>='A' && code<='Z') || (code>='a' && code<='z')) {
+        static const uint16_t map[] = {
+                KEY_A, KEY_B, KEY_C, KEY_D, KEY_E,
+                KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
+                KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
+                KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
+                KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z };
+        scancode = map[(code & 0x5F) - 'A'];
+    } else {
+        switch (code) {
+            case 0x0003:    scancode = KEY_CENTER;      break;
+            case 0x0020:    scancode = KEY_SPACE;       break;
+            case 0x0023:    scancode = KEY_SHARP;       break;
+            case 0x0033:    scancode = KEY_SHARP;       break;
+            case 0x002C:    scancode = KEY_COMMA;       break;
+            case 0x003C:    scancode = KEY_COMMA;       break;
+            case 0x002E:    scancode = KEY_DOT;         break;
+            case 0x003E:    scancode = KEY_DOT;         break;
+            case 0x002F:    scancode = KEY_SLASH;       break;
+            case 0x003F:    scancode = KEY_SLASH;       break;
+            case 0x0032:    scancode = KEY_EMAIL;       break;
+            case 0x0040:    scancode = KEY_EMAIL;       break;
+            case 0xFF08:    scancode = KEY_BACKSPACE;   break;
+            case 0xFF1B:    scancode = KEY_BACK;        break;
+            case 0xFF09:    scancode = KEY_TAB;         break;
+            case 0xFF0D:    scancode = KEY_ENTER;       break;
+            case 0x002A:    scancode = KEY_STAR;        break;
+            case 0xFFBE:    scancode = KEY_SEND;        break; // F1
+            case 0xFFBF:    scancode = KEY_END;         break; // F2
+            case 0xFFC0:    scancode = KEY_HOME;        break; // F3
+            case 0xFFC5:    scancode = KEY_POWER;       break; // F8
+        }
+    }
+
+#if DEBUG_MSG
+   LOGD("handle KeyEvent 0x%08x, %d, scancode=%d\n", code, msg.downFlag, scancode);
+#endif
+
+    if (scancode) {
+        mEventInjector.injectKey(uint16_t(scancode),
+             msg.downFlag ? EventInjector::DOWN : EventInjector::UP);
+    }
+#endif
+}
+
+void RFBServer::waitForClientMessage(ClientMessage& msg)
+{
+    if ( !read(msg.payload(), 1) )
+        return;
+
+    switch(msg.type()) {
+
+    case SET_PIXEL_FORMAT:
+        read(msg.payload(1), sizeof(SetPixelFormat)-1);
+        break;
+
+    case FIX_COLOUR_MAP_ENTRIES:
+        mStatus = UNKNOWN_ERROR;
+        return;
+
+    case SET_ENCODINGS:
+    {
+        if ( !read(msg.payload(1), sizeof(SetEncodings)-1) )
+            return;
+
+        size_t size = ntohs( msg.messages().setEncodings.numberOfEncodings ) * 4;
+        if (msg.resize(sizeof(SetEncodings) + size) != NO_ERROR) {
+            mStatus = NO_MEMORY;
+            return;
+        }
+
+        if ( !read(msg.payload(sizeof(SetEncodings)), size) )
+            return;
+
+        break;
+    }
+
+    case FRAME_BUFFER_UPDATE_REQ:
+        read(msg.payload(1), sizeof(FrameBufferUpdateRequest)-1);
+        break;
+
+    case KEY_EVENT:
+        read(msg.payload(1), sizeof(KeyEvent)-1);
+        break;
+
+    case POINTER_EVENT:
+        read(msg.payload(1), sizeof(PointerEvent)-1);
+        break;
+
+    case CLIENT_CUT_TEXT:
+    {
+        if ( !read(msg.payload(1), sizeof(ClientCutText)-1) )
+            return;
+
+        size_t size = ntohl( msg.messages().clientCutText.length );
+        if (msg.resize(sizeof(ClientCutText) + size) != NO_ERROR) {
+            mStatus = NO_MEMORY;
+            return;
+        }
+
+        if ( !read(msg.payload(sizeof(SetEncodings)), size) )
+            return;
+
+        break;
+    }
+
+    default:
+        LOGE("Unknown Message %d", msg.type());
+        mStatus = UNKNOWN_ERROR;
+        return;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+bool RFBServer::write(const Message& msg)
+{
+    write(msg.payload(), msg.size());
+    return alive();
+}
+
+bool RFBServer::read(Message& msg)
+{
+    read(msg.payload(), msg.size());
+    return alive();
+}
+
+bool RFBServer::write(const void* buffer, int size)
+{
+    int wr = ::write(mFD, buffer, size);
+    if (wr != size) {
+        //LOGE("write(%d) error %d (%s)", size, wr, strerror(errno));
+        mStatus = (wr == -1) ? errno : -1;
+    }
+    return alive();
+}
+
+bool RFBServer::read(void* buffer, int size)
+{
+    int rd = ::read(mFD, buffer, size);
+    if (rd != size) {
+        //LOGE("read(%d) error %d (%s)", size, rd, strerror(errno));
+        mStatus = (rd == -1) ? errno : -1;
+    }
+    return alive();
+}
+
+bool RFBServer::alive() const
+{
+    return  mStatus == 0;
+}
+
+bool RFBServer::isConnected() const
+{
+    return alive();
+}
+
+// ----------------------------------------------------------------------------
+
+void RFBServer::frameBufferUpdated(const GGLSurface& front, const Region& reg)
+{
+    Mutex::Autolock _l(mRegionLock);
+
+    // update dirty region
+    mDirtyRegion.orSelf(reg);
+
+    // remember the front-buffer
+    mFrontBuffer = front;
+
+    // The client has not requested anything, don't do anything more
+    if (mClientRegionRequest.isEmpty())
+        return;
+
+    // wake the sending thread up
+    mRobinThread->wake();
+}
+
+void RFBServer::sendFrameBufferUpdates()
+{
+    Vector<Rect> rects;
+    size_t countRects;
+    GGLSurface fb;
+
+    { // Scope for the lock
+        Mutex::Autolock _l(mRegionLock);
+        if (mFrontBuffer.data == 0)
+            return;
+
+        const Region reg( mDirtyRegion.intersect(mClientRegionRequest) );
+        if (reg.isEmpty())
+            return;
+
+        mDirtyRegion.subtractSelf(reg);
+        countRects = reg.rects(rects);
+
+        // copy the frame-buffer so we can stay responsive
+        size_t bytesPerPix = bytesPerPixel(mFrameBuffer.format);
+        size_t bpr = mFrameBuffer.stride * bytesPerPix;
+        if (mFrameBuffer.data == 0) {
+            mFrameBuffer.data = (GGLubyte*)malloc(bpr * mFrameBuffer.height);
+            if (mFrameBuffer.data == 0)
+            	return;
+        }
+
+        memcpy(mFrameBuffer.data, mFrontBuffer.data, bpr*mFrameBuffer.height);
+        fb = mFrameBuffer;
+    }
+
+    FrameBufferUpdate msgHeader;
+    msgHeader.type = 0;
+    msgHeader.numberOfRectangles = htons(countRects);
+    write(&msgHeader, sizeof(msgHeader));
+
+    Rectangle rectangle;
+    for (size_t i=0 ; i<countRects ; i++) {
+        const Rect& r = rects[i];
+        rectangle.x = htons( r.left );
+        rectangle.y = htons( r.top );
+        rectangle.w = htons( r.width() );
+        rectangle.h = htons( r.height() );
+        rectangle.encoding = htons( SetEncodings::Raw );
+        write(&rectangle, sizeof(rectangle));
+        size_t h = r.height();
+        size_t w = r.width();
+        size_t bytesPerPix = bytesPerPixel(fb.format);
+        size_t bpr = fb.stride * bytesPerPix;
+        size_t bytes = w * bytesPerPix;
+        size_t offset = (r.top * bpr) + (r.left * bytesPerPix);
+        uint8_t* src = static_cast<uint8_t*>(fb.data) + offset;
+        iovec* iov = mIoVec;
+        while (h--) {
+            iov->iov_base = src;
+            iov->iov_len = bytes;
+            src += bpr;
+            iov++;
+        }
+        size_t iovcnt = iov - mIoVec;
+        int wr = ::writev(mFD, mIoVec, iovcnt);
+        if (wr < 0) {
+            //LOGE("write(%d) error %d (%s)", size, wr, strerror(errno));
+            mStatus =  errno;
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+RFBServer::Message::Message(size_t size)
+    : mSize(size), mAllocatedSize(size)
+{
+    mPayload = malloc(size);
+}
+
+RFBServer::Message::Message(void* payload, size_t size)
+    : mPayload(payload), mSize(size), mAllocatedSize(0)
+{
+}
+
+RFBServer::Message::~Message()
+{
+    if (mAllocatedSize)
+        free(mPayload);
+}
+
+status_t RFBServer::Message::resize(size_t size)
+{
+    if (size > mAllocatedSize) {
+        void* newp;
+        if (mAllocatedSize) {
+            newp = realloc(mPayload, size);
+            if (!newp) return NO_MEMORY;
+        } else {
+            newp = malloc(size);
+            if (!newp) return NO_MEMORY;
+            memcpy(newp, mPayload, mSize);
+            mAllocatedSize = size;
+        }
+        mPayload = newp;
+    }
+    mSize = size;
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+RFBServer::EventInjector::EventInjector()
+    : mFD(-1)
+{
+}
+
+RFBServer::EventInjector::~EventInjector()
+{
+}
+
+void RFBServer::EventInjector::injectKey(uint16_t code, uint16_t value)
+{
+#ifdef HAVE_ANDROID_OS
+    // XXX: we need to open the right event device
+    int version;
+    mFD = open("/dev/input/event0", O_RDWR);
+    ioctl(mFD, EVIOCGVERSION, &version);
+
+    input_event ev;
+    memset(&ev, 0, sizeof(ev));
+    ev.type = EV_KEY;
+    ev.code = code;
+    ev.value = value;
+    ::write(mFD, &ev, sizeof(ev));
+
+    close(mFD);
+    mFD = -1;
+#endif
+}
+
+
+}; // namespace android
+
diff --git a/libs/surfaceflinger/RFBServer.h b/libs/surfaceflinger/RFBServer.h
new file mode 100644
index 0000000..420912e
--- /dev/null
+++ b/libs/surfaceflinger/RFBServer.h
@@ -0,0 +1,316 @@
+/*
+ * 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_RFB_SERVER_H
+#define ANDROID_RFB_SERVER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <ui/Region.h>
+#include <ui/PixelFormat.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "Barrier.h"
+
+namespace android {
+
+class SurfaceFlinger;
+
+class RFBServer : public Thread
+{
+public:
+                        RFBServer(uint32_t w, uint32_t h, android::PixelFormat format);
+    virtual             ~RFBServer();
+
+    void    frameBufferUpdated(const GGLSurface& front, const Region& reg);
+    bool    isConnected() const;
+
+private:
+            typedef uint8_t     card8;
+            typedef uint16_t    card16;
+            typedef uint32_t    card32;
+
+            struct Message {
+                                Message(size_t size);
+                virtual         ~Message();
+                void*           payload(int offset=0) {
+                    return static_cast<char*>(mPayload)+offset;
+                }
+                void const *    payload(int offset=0) const {
+                    return static_cast<char const *>(mPayload)+offset;
+                }
+                size_t          size() const { return mSize; }
+            protected:
+                                Message(void* payload, size_t size);
+                status_t        resize(size_t size);
+            private:
+                void*       mPayload;
+                size_t      mSize;
+                size_t      mAllocatedSize;
+            };
+
+            struct ProtocolVersion : public Message {
+                ProtocolVersion(uint8_t major, uint8_t minor)
+                    : Message(&messageData, 12) {
+                    char* p = static_cast<char*>(payload());
+                    snprintf(p, 13, "RFB %03u.%03u%c", major, minor, 0xA);
+                }
+                status_t decode(int& maj, int& min) {
+                    char* p = static_cast<char*>(payload());
+                    int n = sscanf(p, "RFB %03u.%03u", &maj, &min);
+                    return (n == 2) ? NO_ERROR : NOT_ENOUGH_DATA;
+                }
+            private:
+                char messageData[12+1];
+            };
+            
+            struct Authentication : public Message {
+                enum { Failed=0, None=1, Vnc=2 };
+                Authentication(int auth) : Message(&messageData, 4) {
+                    *static_cast<card32*>(payload()) = htonl(auth);
+                }
+            private:
+                card32 messageData;
+            };
+            
+            struct ClientInitialization : public Message {
+                ClientInitialization() : Message(&messageData, 1) { }
+                int sharedFlags() {
+                    return messageData;
+                }
+            private:
+                card8 messageData;
+            };
+
+            struct PixelFormat {
+                card8   bitsPerPixel;
+                card8   depth;
+                card8   bigEndianFlag;
+                card8   trueColorFlag;
+                card16  redMax;
+                card16  greenMax;
+                card16  blueMax;
+                card8   redShift;
+                card8   greenShift;
+                card8   blueShift;
+                uint8_t padding[3];
+            } __attribute__((packed));
+            
+            struct ServerInitialization : public Message {
+                ServerInitialization(char const * name)
+                    : Message(sizeof(Payload) + strlen(name))
+                {
+                    const size_t nameLength = size() - sizeof(Payload);
+                    message().nameLength = htonl(nameLength); 
+                    memcpy((char*)message().nameString, name,nameLength);
+                }
+                struct Payload {
+                    card16      framebufferWidth;
+                    card16      framebufferHeight;
+                    PixelFormat serverPixelFormat;
+                    card32      nameLength;
+                    card8       nameString[0];
+                } __attribute__((packed));
+                Payload& message() {
+                    return *static_cast<Payload*>(payload());
+                }
+            };
+
+            // client messages...
+            
+            struct SetPixelFormat {
+                card8           type;
+                uint8_t         padding[3];
+                PixelFormat     pixelFormat;
+            } __attribute__((packed));
+
+            struct SetEncodings {
+                enum { Raw=0, CoR=1, RRE=2, CoRRE=4, Hextile=5 };
+                card8           type;
+                uint8_t         padding;
+                card16          numberOfEncodings;
+                card32          encodings[0];
+            } __attribute__((packed));
+
+            struct FrameBufferUpdateRequest {
+                card8           type;
+                card8           incremental;
+                card16          x;
+                card16          y;
+                card16          width;
+                card16          height;
+            } __attribute__((packed));
+            
+            struct KeyEvent {
+                card8           type;
+                card8           downFlag;
+                uint8_t         padding[2];
+                card32          key;
+            } __attribute__((packed));
+
+            struct PointerEvent {
+                card8           type;
+                card8           buttonMask;
+                card16          x;
+                card16          y;
+            } __attribute__((packed));
+
+            struct ClientCutText {
+                card8           type;
+                uint8_t         padding[3];
+                card32          length;
+                card8           text[0];
+            } __attribute__((packed));
+            
+            union ClientMessages {
+                card8                       type;
+                SetPixelFormat              setPixelFormat;
+                SetEncodings                setEncodings;
+                FrameBufferUpdateRequest    frameBufferUpdateRequest;
+                KeyEvent                    keyEvent;
+                PointerEvent                pointerEvent;
+                ClientCutText               clientCutText;
+            };
+
+            struct Rectangle {
+                card16      x;
+                card16      y;
+                card16      w;
+                card16      h;
+                card32      encoding;
+            } __attribute__((packed));
+
+            struct FrameBufferUpdate {
+                card8       type;
+                uint8_t     padding;
+                card16      numberOfRectangles;
+                Rectangle   rectangles[0];            
+            } __attribute__((packed));
+
+            enum {
+                SET_PIXEL_FORMAT        = 0,
+                FIX_COLOUR_MAP_ENTRIES  = 1,
+                SET_ENCODINGS           = 2,
+                FRAME_BUFFER_UPDATE_REQ = 3,
+                KEY_EVENT               = 4,
+                POINTER_EVENT           = 5,
+                CLIENT_CUT_TEXT         = 6,
+            };
+
+            struct ClientMessage : public Message {
+                ClientMessage()
+                    : Message(&messageData, sizeof(messageData)) {
+                }
+                const ClientMessages& messages() const {
+                    return *static_cast<ClientMessages const *>(payload());
+                }
+                const int type() const {
+                    return messages().type;
+                }
+                status_t resize(size_t size) {
+                    return Message::resize(size);
+                }
+
+                ClientMessages messageData;
+            };
+
+            
+            class ServerThread : public Thread
+            {
+                friend class RFBServer;
+            public:
+                        ServerThread(const sp<RFBServer>& receiver);
+                virtual ~ServerThread();
+                void wake();
+                void exitAndWait();
+            private:
+                virtual bool threadLoop();
+                virtual status_t readyToRun();
+                virtual void onFirstRef();
+                wp<RFBServer> mReceiver;
+                bool (RFBServer::*mAction)();
+                Barrier mUpdateBarrier;
+            };
+            
+            class EventInjector {
+            public:
+                enum { UP=0, DOWN=1 };
+                EventInjector();
+                ~EventInjector();
+                void injectKey(uint16_t code, uint16_t value);
+            private:
+                struct input_event {
+                    struct timeval time;
+                    uint16_t type;
+                    uint16_t code;
+                    uint32_t value;
+                };
+                int mFD;
+            };
+            
+            void        handshake(uint8_t major, uint8_t minor, uint32_t auth);
+            void        waitForClientMessage(ClientMessage& msg);
+            void        handleClientMessage(const ClientMessage& msg);
+            void        handleSetPixelFormat(const SetPixelFormat& msg);
+            void        handleSetEncodings(const SetEncodings& msg);
+            void        handleFrameBufferUpdateReq(const FrameBufferUpdateRequest& msg);
+            void        handleKeyEvent(const KeyEvent& msg);
+            void        sendFrameBufferUpdates();
+
+            bool        validatePixelFormat(const PixelFormat& pf);
+            bool        alive() const;
+            bool        write(const Message& msg);
+            bool        read(Message& msg);
+
+            bool        write(const void* buffer, int size);
+            bool        read(void* buffer, int size);
+
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+            sp<ServerThread>    mRobinThread;
+
+            int         mFD;
+            int         mStatus;
+            iovec*      mIoVec;
+    
+            EventInjector   mEventInjector;
+
+            Mutex       mRegionLock;
+            // This is the region requested by the client since the last
+            // time we updated it
+            Region      mClientRegionRequest;
+            // This is the region of the screen that needs to be sent to the
+            // client since the last time we updated it.
+            // Typically this is the dirty region, but not necessarily, for
+            // instance if the client asked for a non incremental update.
+            Region      mDirtyRegion;
+            
+            GGLSurface  mFrameBuffer;
+            GGLSurface  mFrontBuffer;
+};
+
+}; // namespace android
+
+#endif // ANDROID_RFB_SERVER_H
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
new file mode 100644
index 0000000..45496b2
--- /dev/null
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -0,0 +1,1895 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/StopWatch.h>
+
+#include <ui/BlitHardware.h>
+#include <ui/PixelFormat.h>
+#include <ui/DisplayInfo.h>
+#include <ui/EGLDisplaySurface.h>
+
+#include <pixelflinger/pixelflinger.h>
+#include <GLES/gl.h>
+
+#include "clz.h"
+#include "CPUGauge.h"
+#include "Layer.h"
+#include "LayerBlur.h"
+#include "LayerBuffer.h"
+#include "LayerDim.h"
+#include "LayerBitmap.h"
+#include "LayerScreenshot.h"
+#include "SurfaceFlinger.h"
+#include "RFBServer.h"
+#include "VRamHeap.h"
+
+#include "DisplayHardware/DisplayHardware.h"
+#include "GPUHardware/GPUHardware.h"
+
+
+// the VNC server even on local ports presents a significant
+// thread as it can allow an application to control and "see" other
+// applications, de-facto bypassing security permissions.
+#define ENABLE_VNC_SERVER   0
+
+#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(
+        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);
+        LOG_ASSERT(layers[idx]==key,
+            "LayerVector[%p]: layers[%d]=%p, key=%p",
+            this, int(idx), layers[idx], key);
+        return idx;
+    }
+    return i;
+}
+
+ssize_t SurfaceFlinger::LayerVector::add(
+        LayerBase* layer,
+        Vector<LayerBase*>::compar_t cmp)
+{
+    size_t count = layers.size();
+    ssize_t l = 0;
+    ssize_t h = count-1;
+    ssize_t mid;
+    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(LayerBase* layer)
+{
+    const ssize_t keyIndex = lookup.indexOfKey(layer);
+    if (keyIndex >= 0) {
+        const size_t index = lookup.valueAt(keyIndex);
+        LOG_ASSERT(layers[index]==layer,
+                "LayerVector[%p]: layers[%u]=%p, layer=%p",
+                this, int(index), layers[index], layer);
+        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(
+        LayerBase* layer,
+        Vector<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),
+        mBootTime(systemTime()),
+        mLastScheduledBroadcast(NULL),
+        mVisibleRegionsDirty(false),
+        mDeferReleaseConsole(false),
+        mFreezeDisplay(false),
+        mFreezeCount(0),
+        mDebugRegion(0),
+        mDebugCpu(0),
+        mDebugFps(0),
+        mDebugBackground(0),
+        mDebugNoBootAnimation(0),
+        mSyncObject(),
+        mDeplayedTransactionPending(0),
+        mConsoleSignals(0),
+        mSecureFrameBuffer(0)
+{
+    init();
+}
+
+void SurfaceFlinger::init()
+{
+    LOGI("SurfaceFlinger is starting");
+
+    // create the shared control-block
+    mServerHeap = new MemoryDealer(4096, MemoryDealer::READ_ONLY);
+    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
+
+    mServerCblkMemory = mServerHeap->allocate(4096);
+    LOGE_IF(mServerCblkMemory==0, "can't create shared control block");
+
+    mServerCblk = static_cast<surface_flinger_cblk_t *>(mServerCblkMemory->pointer());
+    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
+    new(mServerCblk) surface_flinger_cblk_t;
+
+    // create the surface Heap manager, which manages the heaps
+    // (be it in RAM or VRAM) where surfaces are allocated
+    // We give 8 MB per client.
+    mSurfaceHeapManager = new SurfaceHeapManager(8 << 20);
+    mGPU = new GPUHardware();
+
+    // debugging stuff...
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.sf.showupdates", value, "0");
+    mDebugRegion = atoi(value);
+    property_get("debug.sf.showcpu", value, "0");
+    mDebugCpu = atoi(value);
+    property_get("debug.sf.showbackground", value, "0");
+    mDebugBackground = atoi(value);
+    property_get("debug.sf.showfps", value, "0");
+    mDebugFps = atoi(value);
+    property_get("debug.sf.nobootanimation", value, "0");
+    mDebugNoBootAnimation = atoi(value);
+
+    LOGI_IF(mDebugRegion,           "showupdates enabled");
+    LOGI_IF(mDebugCpu,              "showcpu enabled");
+    LOGI_IF(mDebugBackground,       "showbackground enabled");
+    LOGI_IF(mDebugFps,              "showfps enabled");
+    LOGI_IF(mDebugNoBootAnimation,  "boot animation disabled");
+}
+
+SurfaceFlinger::~SurfaceFlinger()
+{
+    glDeleteTextures(1, &mWormholeTexName);
+}
+
+copybit_t* SurfaceFlinger::getBlitEngine() const
+{
+    return graphicPlane(0).displayHardware().getBlitEngine();
+}
+
+sp<IMemory> SurfaceFlinger::getCblk() const
+{
+    return mServerCblkMemory;
+}
+
+status_t SurfaceFlinger::requestGPU(const sp<IGPUCallback>& callback,
+        gpu_info_t* gpu)
+{
+    status_t err = mGPU->request(callback, gpu);
+    return err;
+}
+
+status_t SurfaceFlinger::revokeGPU()
+{
+    return mGPU->friendlyRevoke();
+}
+
+sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
+{
+    Mutex::Autolock _l(mStateLock);
+    uint32_t token = mTokens.acquire();
+
+    Client* client = new Client(token, this);
+    if ((client == 0) || (client->ctrlblk == 0)) {
+        mTokens.release(token);
+        return 0;
+    }
+    status_t err = mClientsMap.add(token, client);
+    if (err < 0) {
+        delete client;
+        mTokens.release(token);
+        return 0;
+    }
+    sp<BClient> bclient =
+        new BClient(this, token, client->controlBlockMemory());
+    return bclient;
+}
+
+void SurfaceFlinger::destroyConnection(ClientID cid)
+{
+    Mutex::Autolock _l(mStateLock);
+    Client* const client = mClientsMap.valueFor(cid);
+    if (client) {
+        // free all the layers this client owns
+        const Vector<LayerBaseClient*>& layers = client->getLayers();
+        const size_t count = layers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            LayerBaseClient* const layer = layers[i];
+            removeLayer_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)) );
+    if (mBootAnimation != 0) {
+        mBootAnimation->requestExit();
+        mBootAnimation.clear();
+    }
+}
+
+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;
+}
+
+// this is defined in libGLES_CM.so
+extern ISurfaceComposer* GLES_localSurfaceManager;
+
+status_t SurfaceFlinger::readyToRun()
+{
+    LOGI(   "SurfaceFlinger's main thread ready to run. "
+            "Initializing graphics H/W...");
+
+    //
+    GLES_localSurfaceManager = static_cast<ISurfaceComposer*>(this);
+
+    // 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);
+    }
+
+    // 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            = w;
+    dcblk->h            = h;
+    dcblk->format       = f;
+    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
+    dcblk->xdpi         = hw.getDpiX();
+    dcblk->ydpi         = hw.getDpiY();
+    dcblk->fps          = hw.getRefreshRate();
+    dcblk->density      = 1.0f; // XXX: do someting more real here...
+    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);
+    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 CPU gauge display
+    if (mDebugCpu)
+        mCpuGauge = new CPUGauge(this, ms2ns(500));
+
+    // the boot animation!
+    if (mDebugNoBootAnimation == false)
+        mBootAnimation = new BootAnimation(this);
+
+    if (ENABLE_VNC_SERVER)
+        mRFBServer = new RFBServer(w, h, f);
+
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Events Handler
+#endif
+
+void SurfaceFlinger::waitForEvent()
+{
+    // wait for something to do
+    if (UNLIKELY(isFrozen())) {
+        // wait 2 seconds
+        int err = mSyncObject.wait(ms2ns(3000));
+        if (err != NO_ERROR) {
+            if (isFrozen()) {
+                // we timed out and are still frozen
+                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
+                        mFreezeDisplay, mFreezeCount);
+                mFreezeCount = 0;
+            }
+        }
+    } else {
+        mSyncObject.wait();
+    }
+}
+
+void SurfaceFlinger::signalEvent() {
+    mSyncObject.open();
+}
+
+void SurfaceFlinger::signal() const {
+    mSyncObject.open();
+}
+
+void SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
+{
+    if (android_atomic_or(1, &mDeplayedTransactionPending) == 0) {
+        sp<DelayedTransaction> delayedEvent(new DelayedTransaction(this, delay));
+        delayedEvent->run("DelayedeEvent", PRIORITY_URGENT_DISPLAY);
+    }
+}
+
+// ----------------------------------------------------------------------------
+#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())) {
+        // repaint the framebuffer (if needed)
+        handleRepaint();
+
+        // release the clients before we flip ('cause flip might block)
+        unlockClients();
+        executeScheduledBroadcasts();
+
+        // sample the cpu gauge
+        if (UNLIKELY(mDebugCpu)) {
+            handleDebugCpu();
+        }
+
+        postFramebuffer();
+    } else {
+        // pretend we did the post
+        unlockClients();
+        executeScheduledBroadcasts();
+        usleep(16667); // 60 fps period
+    }
+    return true;
+}
+
+void SurfaceFlinger::postFramebuffer()
+{
+    if (UNLIKELY(isFrozen())) {
+        // we are not allowed to draw, but pause a bit to make sure
+        // apps don't end up using the whole CPU, if they depend on
+        // surfaceflinger for synchronization.
+        usleep(8333); // 8.3ms ~ 120fps
+        return;
+    }
+
+    if (!mInvalidRegion.isEmpty()) {
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+
+        if (UNLIKELY(mDebugFps)) {
+            debugShowFPS();
+        }
+
+        if (UNLIKELY(ENABLE_VNC_SERVER &&
+                mRFBServer!=0 && mRFBServer->isConnected())) {
+            if (!mSecureFrameBuffer) {
+                GGLSurface fb;
+                // backbufer, is going to become the front buffer really soon
+                hw.getDisplaySurface(&fb);
+                if (LIKELY(fb.data != 0)) {
+                    mRFBServer->frameBufferUpdated(fb, mInvalidRegion);
+                }
+            }
+        }
+
+        hw.flip(mInvalidRegion);
+
+        mInvalidRegion.clear();
+
+        if (Layer::deletedTextures.size()) {
+            glDeleteTextures(
+                    Layer::deletedTextures.size(),
+                    Layer::deletedTextures.array());
+            Layer::deletedTextures.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 aquire signal
+        mDeferReleaseConsole = false;
+        revokeGPU();
+        hw.releaseScreen();
+    }
+
+    if (what & eConsoleReleased) {
+        if (hw.canDraw()) {
+            revokeGPU();
+            hw.releaseScreen();
+        } else {
+            mDeferReleaseConsole = true;
+        }
+    }
+
+    mDirtyRegion.set(hw.bounds());
+}
+
+void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
+{
+    Mutex::Autolock _l(mStateLock);
+
+    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++) {
+            LayerBase* const 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;
+
+            if (flags & Layer::eRestartTransaction) {
+                // restart the transaction, but back-off a little
+                layer->setTransactionFlags(eTransactionNeeded);
+                setTransactionFlags(eTraversalNeeded, ms2ns(8));
+            }
+        }
+    }
+
+    /*
+     * 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;
+            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;
+            if (orientation & eOrientationSwapMask) {
+                // 90 or 270 degrees orientation
+                dcblk->w = hw.getHeight();
+                dcblk->h = hw.getWidth();
+            } else {
+                dcblk->w = hw.getWidth();
+                dcblk->h = hw.getHeight();
+            }
+
+            mVisibleRegionsDirty = true;
+            mDirtyRegion.set(hw.bounds());
+        }
+
+        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
+            // freezing or unfreezing the display -> trigger animation if needed
+            mFreezeDisplay = mCurrentState.freezeDisplay;
+            const nsecs_t now = systemTime();
+            if (mFreezeDisplay) {
+                mFreezeDisplayTime = now;
+            } else {
+                //LOGD("Screen was frozen for %llu us",
+                //        ns2us(now-mFreezeDisplayTime));
+            }
+        }
+
+        // some layers might have been removed, so
+        // we need to update the regions they're exposing.
+        size_t c = mRemovedLayers.size();
+        if (c) {
+            mVisibleRegionsDirty = true;
+        }
+
+        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
+            // layers have been added
+            mVisibleRegionsDirty = true;
+        }
+
+        // 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());
+
+    Region aboveOpaqueLayers;
+    Region aboveCoveredLayers;
+    Region dirty;
+
+    bool secureFrameBuffer = false;
+
+    size_t i = currentLayers.size();
+    while (i--) {
+        LayerBase* const layer = currentLayers[i];
+        layer->validateVisibility(planeTransform);
+
+        // start with the whole surface at its current location
+        const Layer::State& s = layer->drawingState();
+        const Rect bounds(layer->visibleBounds());
+
+        // handle hidden surfaces by setting the visible region to empty
+        Region opaqueRegion;
+        Region visibleRegion;
+        Region coveredRegion;
+        if (UNLIKELY((s.flags & ISurfaceComposer::eLayerHidden) || !s.alpha)) {
+            visibleRegion.clear();
+        } else {
+            const bool translucent = layer->needsBlending();
+            visibleRegion.set(bounds);
+            coveredRegion = visibleRegion;
+
+            // Remove the transparent area from the visible region
+            if (translucent) {
+                visibleRegion.subtractSelf(layer->transparentRegionScreen);
+            }
+
+            // compute the opaque region
+            if (s.alpha==255 && !translucent && layer->getOrientation()>=0) {
+                // the opaque region is the visible region
+                opaqueRegion = visibleRegion;
+            }
+        }
+
+        // subtract the opaque region covered by the layers above us
+        visibleRegion.subtractSelf(aboveOpaqueLayers);
+        coveredRegion.andSelf(aboveCoveredLayers);
+
+        // compute this layer's dirty region
+        if (layer->invalidate) {
+            // we need to invalidate the whole region
+            dirty = visibleRegion;
+            // as well, as the old visible region
+            dirty.orSelf(layer->visibleRegionScreen);
+            layer->invalidate = false;
+        } else {
+            // compute the exposed region
+            // dirty = what's visible now - what's wasn't covered before
+            //       = what's visible now & what's was covered before
+            dirty = visibleRegion.intersect(layer->coveredRegionScreen);            
+        }
+        dirty.subtractSelf(aboveOpaqueLayers);
+
+        // accumulate to the screen dirty region
+        dirtyRegion.orSelf(dirty);
+
+        // updade aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
+        aboveOpaqueLayers.orSelf(opaqueRegion);
+        aboveCoveredLayers.orSelf(bounds);
+        
+        // Store the visible region is screen space
+        layer->setVisibleRegion(visibleRegion);
+        layer->setCoveredRegion(coveredRegion);
+
+        // If a secure layer is partially visible, lockdown the screen!
+        if (layer->isSecure() && !visibleRegion.isEmpty()) {
+            secureFrameBuffer = true;
+        }
+    }
+
+    mSecureFrameBuffer = secureFrameBuffer;
+    opaqueRegion = aboveOpaqueLayers;
+}
+
+
+void SurfaceFlinger::commitTransaction()
+{
+    mDrawingState = mCurrentState;
+    mTransactionCV.signal();
+}
+
+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();
+    LayerBase* const* layers = currentLayers.array();
+    for (size_t i=0 ; i<count ; i++) {
+        LayerBase* const 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();
+    LayerBase* const* layers = currentLayers.array();
+    for (size_t i=0 ; i<count ; i++) {
+        LayerBase* const layer = layers[i];
+        layer->unlockPageFlip(planeTransform, mDirtyRegion);
+    }
+}
+
+void SurfaceFlinger::handleRepaint()
+{
+    // set the frame buffer
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    if (UNLIKELY(mDebugRegion)) {
+        debugFlashRegions();
+    }
+
+    // compute the invalid region
+    mInvalidRegion.orSelf(mDirtyRegion);
+
+    uint32_t flags = hw.getFlags();
+    if (flags & DisplayHardware::BUFFER_PRESERVED) {
+        if (flags & DisplayHardware::COPY_BACK_EXTENSION) {
+            // yay. nothing to do here.
+        } else {
+            if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
+                // we need to fully redraw the part that will be updated
+                mDirtyRegion.set(mInvalidRegion.bounds());
+            } else {
+                // TODO: we only need te redraw the part that had been drawn
+                // the round before and is not drawn now
+            }
+        }
+    } else {
+        // COPY_BACK_EXTENSION makes no sense here
+        if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
+            // we need to fully redraw the part that will be updated
+            mDirtyRegion.set(mInvalidRegion.bounds());
+        } else {
+            // we need to redraw everything
+            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();
+    LayerBase const* const* const layers = drawingLayers.array();
+    for (size_t i=0 ; i<count ; ++i) {
+        LayerBase const * const 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();
+    LayerBase* const* const layers = drawingLayers.array();
+    for (size_t i=0 ; i<count ; ++i) {
+        LayerBase* const layer = layers[i];
+        layer->finishPageFlip();
+    }
+}
+
+void SurfaceFlinger::scheduleBroadcast(Client* client)
+{
+    if (mLastScheduledBroadcast != client) {
+        mLastScheduledBroadcast = client;
+        mScheduledBroadcasts.add(client);
+    }
+}
+
+void SurfaceFlinger::executeScheduledBroadcasts()
+{
+    SortedVector<Client*>& list = mScheduledBroadcasts;
+    size_t count = list.size();
+    while (count--) {
+        per_client_cblk_t* const cblk = list[count]->ctrlblk;
+        if (cblk->lock.tryLock() == NO_ERROR) {
+            cblk->cv.broadcast();
+            list.removeAt(count);
+            cblk->lock.unlock();
+        } else {
+            // schedule another round
+            LOGW("executeScheduledBroadcasts() skipped, "
+                "contention on the client. We'll try again later...");
+            signalDelayedEvent(ms2ns(4));
+        }
+    }
+    mLastScheduledBroadcast = 0;
+}
+
+void SurfaceFlinger::handleDebugCpu()
+{
+    Mutex::Autolock _l(mDebugLock);
+    if (mCpuGauge != 0)
+        mCpuGauge->sample();
+}
+
+void SurfaceFlinger::debugFlashRegions()
+{
+    if (UNLIKELY(!mDirtyRegion.isRect())) {
+        // TODO: do this only if we don't have preserving
+        // swapBuffer. If we don't have update-on-demand,
+        // redraw everything.
+        composeSurfaces(Region(mDirtyRegion.bounds()));
+    }
+
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+    glDisable(GL_SCISSOR_TEST);
+
+    glColor4x(0x10000, 0, 0x10000, 0x10000);
+
+    Rect r;
+    Region::iterator iterator(mDirtyRegion);
+    while (iterator.iterate(&r)) {
+        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);
+    }
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    hw.flip(mDirtyRegion.merge(mInvalidRegion));
+    mInvalidRegion.clear();
+
+    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);
+        Rect r;
+        Region::iterator iterator(region);
+        while (iterator.iterate(&r)) {
+            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);
+        Rect r;
+        Region::iterator iterator(region);
+        while (iterator.iterate(&r)) {
+            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_l(LayerBase* layer)
+{
+    ssize_t i = mCurrentState.layersSortedByZ.add(
+                layer, &LayerBase::compareCurrentStateZ);
+    LayerBaseClient* lbc = LayerBase::dynamicCast<LayerBaseClient*>(layer);
+    if (lbc) {
+        mLayerMap.add(lbc->serverIndex(), lbc);
+    }
+    mRemovedLayers.remove(layer);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::removeLayer_l(LayerBase* layerBase)
+{
+    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
+    if (index >= 0) {
+        mRemovedLayers.add(layerBase);
+        LayerBaseClient* layer = LayerBase::dynamicCast<LayerBaseClient*>(layerBase);
+        if (layer) {
+            mLayerMap.removeItem(layer->serverIndex());
+        }
+        return NO_ERROR;
+    }
+    // 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 destroySurface,
+    // destroyclient and destroySurface-from-a-transaction.
+    return (index == NAME_NOT_FOUND) ? status_t(NO_ERROR) : index;
+}
+
+void SurfaceFlinger::free_resources_l()
+{
+    // Destroy layers that were removed
+    destroy_all_removed_layers_l();
+
+    // free resources associated with disconnected clients
+    SortedVector<Client*>& scheduledBroadcasts(mScheduledBroadcasts);
+    Vector<Client*>& disconnectedClients(mDisconnectedClients);
+    const size_t count = disconnectedClients.size();
+    for (size_t i=0 ; i<count ; i++) {
+        Client* client = disconnectedClients[i];
+        // if this client is the scheduled broadcast list,
+        // remove it from there (and we don't need to signal it
+        // since it is dead).
+        int32_t index = scheduledBroadcasts.indexOf(client);
+        if (index >= 0) {
+            scheduledBroadcasts.removeItemsAt(index);
+        }
+        mTokens.release(client->cid);
+        delete client;
+    }
+    disconnectedClients.clear();
+}
+
+void SurfaceFlinger::destroy_all_removed_layers_l()
+{
+    size_t c = mRemovedLayers.size();
+    while (c--) {
+        LayerBase* const removed_layer = mRemovedLayers[c];
+
+        LOGE_IF(mCurrentState.layersSortedByZ.indexOf(removed_layer) >= 0,
+            "layer %p removed but still in the current state list",
+            removed_layer);
+
+        delete removed_layer;
+    }
+    mRemovedLayers.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();
+    }
+}
+
+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 fadding)
+    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 fadding)
+    return NO_ERROR;
+}
+
+int SurfaceFlinger::setOrientation(DisplayID dpy, int orientation)
+{
+    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.orientation = orientation;
+            setTransactionFlags(eTransactionNeeded);
+            mTransactionCV.wait(mStateLock);
+        } else {
+            orientation = BAD_VALUE;
+        }
+    }
+    return orientation;
+}
+
+sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
+        ISurfaceFlingerClient::surface_data_t* params,
+        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
+        uint32_t flags)
+{
+    LayerBaseClient* layer = 0;
+    sp<LayerBaseClient::Surface> surfaceHandle;
+    Mutex::Autolock _l(mStateLock);
+    Client* const c = mClientsMap.valueFor(clientId);
+    if (UNLIKELY(!c)) {
+        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 = c->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(c, d, id, w, h, flags);
+            } else {
+                layer = createNormalSurfaceLocked(c, d, id, w, h, format, flags);
+            }
+            break;
+        case eFXSurfaceBlur:
+            layer = createBlurSurfaceLocked(c, d, id, w, h, flags);
+            break;
+        case eFXSurfaceDim:
+            layer = createDimSurfaceLocked(c, d, id, w, h, flags);
+            break;
+    }
+
+    if (layer) {
+        setTransactionFlags(eTransactionNeeded);
+        surfaceHandle = layer->getSurface();
+        if (surfaceHandle != 0)
+            surfaceHandle->getSurfaceData(params);
+    }
+
+    return surfaceHandle;
+}
+
+LayerBaseClient* SurfaceFlinger::createNormalSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
+{
+    // 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;
+    }
+
+    Layer* layer = new Layer(this, display, client, id);
+    status_t err = layer->setBuffers(client, w, h, format, flags);
+    if (LIKELY(err == NO_ERROR)) {
+        layer->initStates(w, h, flags);
+        addLayer_l(layer);
+    } else {
+        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
+        delete layer;
+        return 0;
+    }
+    return layer;
+}
+
+LayerBaseClient* SurfaceFlinger::createBlurSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerBlur* layer = new LayerBlur(this, display, client, id);
+    layer->initStates(w, h, flags);
+    addLayer_l(layer);
+    return layer;
+}
+
+LayerBaseClient* SurfaceFlinger::createDimSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerDim* layer = new LayerDim(this, display, client, id);
+    layer->initStates(w, h, flags);
+    addLayer_l(layer);
+    return layer;
+}
+
+LayerBaseClient* SurfaceFlinger::createPushBuffersSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerBuffer* layer = new LayerBuffer(this, display, client, id);
+    layer->initStates(w, h, flags);
+    addLayer_l(layer);
+    return layer;
+}
+
+status_t SurfaceFlinger::destroySurface(SurfaceID index)
+{
+    Mutex::Autolock _l(mStateLock);
+    LayerBaseClient* const layer = getLayerUser_l(index);
+    status_t err = removeLayer_l(layer);
+    if (err < 0)
+        return err;
+    setTransactionFlags(eTransactionNeeded);
+    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];
+        LayerBaseClient* layer = getLayerUser_l(s.surface | cid);
+        if (layer) {
+            const uint32_t what = s.what;
+            // check if it has been destroyed first
+            if (what & eDestroyed) {
+                if (removeLayer_l(layer) == NO_ERROR) {
+                    flags |= eTransactionNeeded;
+                    // we skip everything else... well, no, not really
+                    // we skip ONLY that transaction.
+                    continue;
+                }
+            }
+            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;
+            }
+            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;
+}
+
+LayerBaseClient* SurfaceFlinger::getLayerUser_l(SurfaceID s) const
+{
+    return mLayerMap.valueFor(s);
+}
+
+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 (checkCallingPermission(
+            String16("android.permission.DUMP")) == false)
+    { // not allowed
+        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 {
+        Mutex::Autolock _l(mStateLock);
+        size_t s = mClientsMap.size();
+        char name[64];
+        for (size_t i=0 ; i<s ; i++) {
+            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 ***/
+            LayerBase const * const 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, invalidate=%1d, "
+                    "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
+                    layer->getTypeID(), layer,
+                    s.z, layer->tx(), layer->ty(), s.w, s.h,
+                    layer->needsBlending(), layer->invalidate,
+                    s.alpha, s.flags,
+                    s.transform[0], s.transform[1],
+                    s.transform[2], s.transform[3]);
+            result.append(buffer);
+            buffer[0] = 0;
+            /*** LayerBaseClient ***/
+            LayerBaseClient* const lbc =
+                LayerBase::dynamicCast<LayerBaseClient*>((LayerBase*)layer);
+            if (lbc) {
+                snprintf(buffer, SIZE,
+                        "      "
+                        "id=0x%08x, client=0x%08x, identity=%u\n",
+                        lbc->clientIndex(), lbc->client ? lbc->client->cid : 0,
+                        lbc->getIdentity());
+            }
+            result.append(buffer);
+            buffer[0] = 0;
+            /*** LayerBuffer ***/
+            LayerBuffer* const lbuf =
+                LayerBase::dynamicCast<LayerBuffer*>((LayerBase*)layer);
+            if (lbuf) {
+                sp<LayerBuffer::Buffer> lbb(lbuf->getBuffer());
+                if (lbb != 0) {
+                    const LayerBuffer::NativeBuffer& nbuf(lbb->getBuffer());
+                    snprintf(buffer, SIZE,
+                            "      "
+                            "mBuffer={w=%u, h=%u, f=%d, offset=%u, base=%p, fd=%d }\n",
+                            nbuf.img.w, nbuf.img.h, nbuf.img.format, nbuf.img.offset,
+                            nbuf.img.base, nbuf.img.fd);
+                }
+            }
+            result.append(buffer);
+            buffer[0] = 0;
+            /*** Layer ***/
+            Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer);
+            if (l) {
+                const LayerBitmap& buf0(l->getBuffer(0));
+                const LayerBitmap& buf1(l->getBuffer(1));
+                snprintf(buffer, SIZE,
+                        "      "
+                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u], mTextureName=%d,"
+                        " freezeLock=%p, swapState=0x%08x\n",
+                        l->pixelFormat(),
+                        buf0.width(), buf0.height(), buf0.stride(),
+                        buf1.width(), buf1.height(), buf1.stride(),
+                        l->getTextureName(), l->getFreezeLock().get(),
+                        l->lcblk->swapState);
+            }
+            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);
+
+        sp<AllocatorInterface> allocator;
+        if (mGPU != 0) {
+            snprintf(buffer, SIZE, "  GPU owner: %d\n", mGPU->getOwner());
+            result.append(buffer);
+            allocator = mGPU->getAllocator();
+            if (allocator != 0) {
+                allocator->dump(result, "GPU Allocator");
+            }
+        }
+        allocator = mSurfaceHeapManager->getAllocator(NATIVE_MEMORY_TYPE_PMEM);
+        if (allocator != 0) {
+            allocator->dump(result, "PMEM Allocator");
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case CREATE_CONNECTION:
+        case OPEN_GLOBAL_TRANSACTION:
+        case CLOSE_GLOBAL_TRANSACTION:
+        case SET_ORIENTATION:
+        case FREEZE_DISPLAY:
+        case UNFREEZE_DISPLAY:
+        case BOOT_FINISHED:
+        case REVOKE_GPU:
+        {
+            // codes that require permission check
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int self_pid = getpid();
+            if (UNLIKELY(pid != self_pid)) {
+                // we're called from a different process, do the real check
+                if (!checkCallingPermission(
+                        String16("android.permission.ACCESS_SURFACE_FLINGER")))
+                {
+                    const int uid = ipc->getCallingUid();
+                    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) {
+        if (code == 1012) {
+            // take screen-shot of the front buffer
+            if (UNLIKELY(checkCallingPermission(
+                    String16("android.permission.READ_FRAME_BUFFER")) == false))
+            { // not allowed
+                LOGE("Permission Denial: "
+                        "can't take screenshots from pid=%d, uid=%d\n",
+                        IPCThreadState::self()->getCallingPid(),
+                        IPCThreadState::self()->getCallingUid());
+                return PERMISSION_DENIED;
+            }
+
+            if (UNLIKELY(mSecureFrameBuffer)) {
+                LOGE("A secure window is on screen: "
+                        "can't take screenshots from pid=%d, uid=%d\n",
+                        IPCThreadState::self()->getCallingPid(),
+                        IPCThreadState::self()->getCallingUid());
+                return PERMISSION_DENIED;
+            }
+
+            LOGI("Taking a screenshot...");
+
+            LayerScreenshot* l = new LayerScreenshot(this, 0);
+
+            Mutex::Autolock _l(mStateLock);
+            const DisplayHardware& hw(graphicPlane(0).displayHardware());
+            l->initStates(hw.getWidth(), hw.getHeight(), 0);
+            l->setLayer(INT_MAX);
+
+            addLayer_l(l);
+            setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
+
+            l->takeScreenshot(mStateLock, reply);
+
+            removeLayer_l(l);
+            setTransactionFlags(eTransactionNeeded);
+            return NO_ERROR;
+        } else {
+            // HARDWARE_TEST stuff...
+            if (UNLIKELY(checkCallingPermission(
+                    String16("android.permission.HARDWARE_TEST")) == false))
+            { // not allowed
+                LOGE("Permission Denial: pid=%d, uid=%d\n",
+                        IPCThreadState::self()->getCallingPid(),
+                        IPCThreadState::self()->getCallingUid());
+                return PERMISSION_DENIED;
+            }
+            int n;
+            switch (code) {
+            case 1000: // SHOW_CPU
+                n = data.readInt32();
+                mDebugCpu = n ? 1 : 0;
+                if (mDebugCpu) {
+                    if (mCpuGauge == 0) {
+                        mCpuGauge = new CPUGauge(this, ms2ns(500));
+                    }
+                } else {
+                    if (mCpuGauge != 0) {
+                        mCpuGauge->requestExitAndWait();
+                        Mutex::Autolock _l(mDebugLock);
+                        mCpuGauge.clear();
+                    }
+                }
+                return NO_ERROR;
+            case 1001:  // SHOW_FPS
+                n = data.readInt32();
+                mDebugFps = n ? 1 : 0;
+                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: // ask GPU revoke
+                mGPU->friendlyRevoke();
+                return NO_ERROR;
+            case 1006: // revoke GPU
+                mGPU->unconditionalRevoke();
+                return NO_ERROR;
+            case 1007: // set mFreezeCount
+                mFreezeCount = data.readInt32();
+                return NO_ERROR;
+            case 1010:  // interrogate.
+                reply->writeInt32(mDebugCpu);
+                reply->writeInt32(0);
+                reply->writeInt32(mDebugRegion);
+                reply->writeInt32(mDebugBackground);
+                return NO_ERROR;
+            case 1013: { // screenshot
+                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)
+{
+    mSharedHeapAllocator = getSurfaceHeapManager()->createHeap(NATIVE_MEMORY_TYPE_HEAP);
+    const int pgsize = getpagesize();
+    const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
+    mCblkHeap = new MemoryDealer(cblksize);
+    mCblkMemory = mCblkHeap->allocate(cblksize);
+    if (mCblkMemory != 0) {
+        ctrlblk = static_cast<per_client_cblk_t *>(mCblkMemory->pointer());
+        if (ctrlblk) { // construct the shared structure in-place.
+            new(ctrlblk) per_client_cblk_t;
+        }
+    }
+}
+
+Client::~Client() {
+    if (ctrlblk) {
+        const int pgsize = getpagesize();
+        ctrlblk->~per_client_cblk_t();  // destroy our shared-structure.
+    }
+}
+
+const sp<SurfaceHeapManager>& Client::getSurfaceHeapManager() const {
+    return mFlinger->getSurfaceHeapManager();
+}
+
+const sp<GPUHardwareInterface>& Client::getGPU() const {
+    return mFlinger->getGPU();
+}
+
+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(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);
+    }
+}
+
+sp<MemoryDealer> Client::createAllocator(int memory_type)
+{
+    sp<MemoryDealer> allocator;
+    if (memory_type == NATIVE_MEMORY_TYPE_GPU) {
+        allocator = getGPU()->request(getClientPid());
+        if (allocator == 0)
+            memory_type = NATIVE_MEMORY_TYPE_PMEM;
+    }
+    if (memory_type == NATIVE_MEMORY_TYPE_PMEM) {
+        allocator = mPMemAllocator;
+        if (allocator == 0) {
+            allocator = getSurfaceHeapManager()->createHeap(
+                    NATIVE_MEMORY_TYPE_PMEM);
+            mPMemAllocator = allocator;
+        }
+    }
+    if (allocator == 0)
+        allocator = mSharedHeapAllocator;
+
+    return allocator;
+}
+
+bool Client::isValid(int32_t i) const {
+    return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
+}
+const uint8_t* Client::inUseArray() const {
+    return mInUse.array();
+}
+size_t Client::numActiveLayers() const {
+    return mInUse.size();
+}
+LayerBaseClient* Client::getLayerUser(int32_t i) const {
+    ssize_t idx = mInUse.indexOf(uint8_t(i));
+    if (idx<0) return 0;
+    return mLayers[idx];
+}
+
+void Client::dump(const char* what)
+{
+}
+
+// ---------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemory>& cblk)
+    : mId(cid), mFlinger(flinger), mCblk(cblk)
+{
+}
+
+BClient::~BClient() {
+    // destroy all resources attached to this client
+    mFlinger->destroyConnection(mId);
+}
+
+void BClient::getControlBlocks(sp<IMemory>* ctrl) const {
+    *ctrl = mCblk;
+}
+
+sp<ISurface> BClient::createSurface(
+        ISurfaceFlingerClient::surface_data_t* params, int pid,
+        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
+        uint32_t flags)
+{
+    return mFlinger->createSurface(mId, pid, params, display, w, h, format, flags);
+}
+
+status_t BClient::destroySurface(SurfaceID sid)
+{
+    sid |= (mId << 16); // add the client-part to id
+    return mFlinger->destroySurface(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;
+}
+
+void GraphicPlane::setDisplayHardware(DisplayHardware *hw) {
+    mHw = hw;
+}
+
+void GraphicPlane::setTransform(const Transform& tr) {
+    mTransform = tr;
+    mGlobalTransform = mOrientationTransform * mTransform;
+}
+
+status_t GraphicPlane::setOrientation(int orientation)
+{
+    float a, b, c, d, x, y;
+
+    const DisplayHardware& hw(displayHardware());
+    const float w = hw.getWidth();
+    const float h = hw.getHeight();
+
+    if (orientation == ISurfaceComposer::eOrientationDefault) {
+        // make sure the default orientation is optimal
+        mOrientationTransform.reset();
+        mGlobalTransform = mTransform;
+        return NO_ERROR;
+    }
+
+    // If the rotation can be handled in hardware, this is where
+    // the magic should happen.
+
+    switch (orientation) {
+    case ISurfaceComposer::eOrientation90:
+        a=0; b=-1; c=1; d=0; x=w; y=0;
+        break;
+    case ISurfaceComposer::eOrientation180:
+        a=-1; b=0; c=0; d=-1; x=w; y=h;
+        break;
+    case ISurfaceComposer::eOrientation270:
+        a=0; b=1; c=-1; d=0; x=0; y=h;
+        break;
+    case 42: {
+        const float r = (3.14159265f / 180.0f) * 42.0f;
+        const float si = sinf(r);
+        const float co = cosf(r);
+        a=co; b=-si; c=si; d=co;
+        x = si*(h*0.5f) + (1-co)*(w*0.5f);
+        y =-si*(w*0.5f) + (1-co)*(h*0.5f);
+    } break;
+    default:
+        return BAD_VALUE;
+    }
+    mOrientationTransform.set(a, b, c, d);
+    mOrientationTransform.set(x, y);
+    mGlobalTransform = mOrientationTransform * mTransform;
+    return NO_ERROR;
+}
+
+const DisplayHardware& GraphicPlane::displayHardware() const {
+    return *mHw;
+}
+
+const Transform& GraphicPlane::transform() const {
+    return mGlobalTransform;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
new file mode 100644
index 0000000..1581474
--- /dev/null
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -0,0 +1,433 @@
+/*
+ * 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/MemoryDealer.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+#include <private/ui/SurfaceFlingerSynchro.h>
+
+#include "Layer.h"
+#include "Tokenizer.h"
+#include "CPUGauge.h"
+#include "BootAnimation.h"
+#include "Barrier.h"
+
+struct copybit_t;
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class BClient;
+class Client;
+class DisplayHardware;
+class GPUHardwareInterface;
+class IGPUCallback;
+class Layer;
+class LayerBuffer;
+class RFBServer;
+class SurfaceHeapManager;
+class FreezeLock;
+
+typedef int32_t ClientID;
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+class Client
+{
+public:
+            Client(ClientID cid, const sp<SurfaceFlinger>& flinger);
+            ~Client();
+
+            int32_t                 generateId(int pid);
+            void                    free(int32_t id);
+            status_t                bindLayer(LayerBaseClient* layer, int32_t id);
+            sp<MemoryDealer>        createAllocator(int memory_type);
+
+    inline  bool                    isValid(int32_t i) const;
+    inline  const uint8_t*          inUseArray() const;
+    inline  size_t                  numActiveLayers() const;
+    LayerBaseClient*                getLayerUser(int32_t i) const;
+    const Vector<LayerBaseClient*>& getLayers() const { return mLayers; }
+    const sp<IMemory>&              controlBlockMemory() const { return mCblkMemory; }
+    void                            dump(const char* what);
+    const sp<SurfaceHeapManager>&   getSurfaceHeapManager() const;
+    
+    // pointer to this client's control block
+    per_client_cblk_t*      ctrlblk;
+    ClientID                cid;
+
+    
+private:
+    int                     getClientPid() const { return mPid; }
+    const sp<GPUHardwareInterface>&  getGPU() const;
+        
+    int                         mPid;
+    uint32_t                    mBitmap;
+    SortedVector<uint8_t>       mInUse;
+    Vector<LayerBaseClient*>    mLayers;
+    sp<MemoryDealer>            mCblkHeap;
+    sp<SurfaceFlinger>          mFlinger;
+    sp<MemoryDealer>            mSharedHeapAllocator;
+    sp<MemoryDealer>            mPMemAllocator;
+    sp<IMemory>                 mCblkMemory;
+};
+
+// ---------------------------------------------------------------------------
+
+class GraphicPlane
+{
+public:
+
+                                GraphicPlane();
+                                ~GraphicPlane();
+
+        bool                    initialized() const;
+
+        void                    setDisplayHardware(DisplayHardware *);
+        void                    setTransform(const Transform& tr);
+        status_t                setOrientation(int orientation);
+
+        const DisplayHardware&  displayHardware() const;
+        const Transform&        transform() const;
+private:
+                                GraphicPlane(const GraphicPlane&);
+        GraphicPlane            operator = (const GraphicPlane&);
+
+        DisplayHardware*        mHw;
+        Transform               mTransform;
+        Transform               mOrientationTransform;
+        Transform               mGlobalTransform;
+};
+
+// ---------------------------------------------------------------------------
+
+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<IMemory>                 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);
+    virtual void                        signal() const;
+    virtual status_t requestGPU(const sp<IGPUCallback>& callback, 
+            gpu_info_t* gpu);
+    virtual status_t revokeGPU();
+
+            void                        screenReleased(DisplayID dpy);
+            void                        screenAcquired(DisplayID dpy);
+
+            const sp<SurfaceHeapManager>& getSurfaceHeapManager() const { 
+                return mSurfaceHeapManager; 
+            }
+
+            const sp<GPUHardwareInterface>& getGPU() const {
+                return mGPU; 
+            }
+
+            copybit_t* getBlitEngine() const;
+            
+private:
+    friend class BClient;
+    friend class LayerBase;
+    friend class LayerBuffer;
+    friend class LayerBaseClient;
+    friend class Layer;
+    friend class LayerBlur;
+
+    sp<ISurface> createSurface(ClientID client, int pid, 
+            ISurfaceFlingerClient::surface_data_t* params,
+            DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
+            uint32_t flags);
+
+    LayerBaseClient* createNormalSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+
+    LayerBaseClient* createBlurSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+
+    LayerBaseClient* createDimSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+
+    LayerBaseClient* createPushBuffersSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+
+    status_t    destroySurface(SurfaceID surface_id);
+    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 LayerBase*const* array() const { return layers.array(); }
+        ssize_t             add(LayerBase*, Vector<LayerBase*>::compar_t);
+        ssize_t             remove(LayerBase*);
+        ssize_t             reorder(LayerBase*, Vector<LayerBase*>::compar_t);
+        ssize_t             indexOf(LayerBase* key, size_t guess=0) const;
+        inline LayerBase*   operator [] (size_t i) const { return layers[i]; }
+    private:
+        KeyedVector<LayerBase*, size_t> lookup;
+        Vector<LayerBase*>              layers;
+    };
+
+    struct State {
+        State() {
+            orientation = ISurfaceComposer::eOrientationDefault;
+            freezeDisplay = 0;
+        }
+        LayerVector     layersSortedByZ;
+        uint8_t         orientation;
+        uint8_t         freezeDisplay;
+    };
+
+    class DelayedTransaction : public Thread
+    {
+        friend class SurfaceFlinger;
+        sp<SurfaceFlinger>  mFlinger;
+        nsecs_t             mDelay;
+    public:
+        DelayedTransaction(const sp<SurfaceFlinger>& flinger, nsecs_t delay)
+            : Thread(false), mFlinger(flinger), mDelay(delay) {
+        }
+        virtual bool threadLoop() {
+            usleep(mDelay / 1000);
+            if (android_atomic_and(~1,
+                    &mFlinger->mDeplayedTransactionPending) == 1) {
+                mFlinger->signalEvent();
+            }
+            return false;
+        }
+    };
+
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+    const GraphicPlane&     graphicPlane(int dpy) const;
+          GraphicPlane&     graphicPlane(int dpy);
+
+            void        waitForEvent();
+            void        signalEvent();
+            void        signalDelayedEvent(nsecs_t delay);
+
+            void        handleConsoleEvents();
+            void        handleTransaction(uint32_t transactionFlags);
+
+            void        computeVisibleRegions(
+                            LayerVector& currentLayers,
+                            Region& dirtyRegion,
+                            Region& wormholeRegion);
+
+            void        handlePageFlip();
+            bool        lockPageFlip(const LayerVector& currentLayers);
+            void        unlockPageFlip(const LayerVector& currentLayers);
+            void        handleRepaint();
+            void        handleDebugCpu();
+            void        scheduleBroadcast(Client* client);
+            void        executeScheduledBroadcasts();
+            void        postFramebuffer();
+            void        composeSurfaces(const Region& dirty);
+            void        unlockClients();
+
+
+            void        destroyConnection(ClientID cid);
+            LayerBaseClient* getLayerUser_l(SurfaceID index) const;
+            status_t    addLayer_l(LayerBase* layer);
+            status_t    removeLayer_l(LayerBase* layer);
+            void        destroy_all_removed_layers_l();
+            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() { mFreezeCount++; }
+            inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
+            inline bool hasFreezeRequest() const { return mFreezeDisplay; }
+            inline bool isFrozen() const { 
+                return mFreezeDisplay || mFreezeCount>0;
+            }
+
+            
+            void        debugFlashRegions();
+            void        debugShowFPS() const;
+            void        drawWormhole() const;
+           
+                // access must be protected by mStateLock
+    mutable     Mutex                   mStateLock;
+                State                   mCurrentState;
+                State                   mDrawingState;
+    volatile    int32_t                 mTransactionFlags;
+    volatile    int32_t                 mTransactionCount;
+                Condition               mTransactionCV;
+
+                // protected by mStateLock (but we could use another lock)
+                Tokenizer                               mTokens;
+                DefaultKeyedVector<ClientID, Client*>   mClientsMap;
+                DefaultKeyedVector<SurfaceID, LayerBaseClient*>   mLayerMap;
+                GraphicPlane                            mGraphicPlanes[1];
+                SortedVector<LayerBase*>                mRemovedLayers;
+                Vector<Client*>                         mDisconnectedClients;
+
+                // constant members (no synchronization needed for access)
+                sp<MemoryDealer>            mServerHeap;
+                sp<IMemory>                 mServerCblkMemory;
+                surface_flinger_cblk_t*     mServerCblk;
+                sp<SurfaceHeapManager>      mSurfaceHeapManager;
+                sp<GPUHardwareInterface>    mGPU;
+                GLuint                      mWormholeTexName;
+                sp<BootAnimation>           mBootAnimation;
+                sp<RFBServer>               mRFBServer;
+                nsecs_t                     mBootTime;
+                
+                // Can only accessed from the main thread, these members
+                // don't need synchronization
+                Region                      mDirtyRegion;
+                Region                      mInvalidRegion;
+                Region                      mWormholeRegion;
+                Client*                     mLastScheduledBroadcast;
+                SortedVector<Client*>       mScheduledBroadcasts;
+                bool                        mVisibleRegionsDirty;
+                bool                        mDeferReleaseConsole;
+                bool                        mFreezeDisplay;
+                int32_t                     mFreezeCount;
+                nsecs_t                     mFreezeDisplayTime;
+
+                // access protected by mDebugLock
+    mutable     Mutex                       mDebugLock;
+                sp<CPUGauge>                mCpuGauge;
+
+                // don't use a lock for these, we don't care
+                int                         mDebugRegion;
+                int                         mDebugCpu;
+                int                         mDebugFps;
+                int                         mDebugBackground;
+                int                         mDebugNoBootAnimation;
+
+                // these are thread safe
+    mutable     Barrier                     mReadyToRunBarrier;
+    mutable     SurfaceFlingerSynchro       mSyncObject;
+    volatile    int32_t                     mDeplayedTransactionPending;
+
+                // 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 {
+    SurfaceFlinger* mFlinger;
+    mutable volatile int32_t mCount;
+public:
+    FreezeLock(SurfaceFlinger* flinger)
+        : mFlinger(flinger), mCount(0) {
+        mFlinger->incFreezeCount();
+    }
+    ~FreezeLock() {
+        mFlinger->decFreezeCount();
+    }
+    inline void incStrong(void*) const {
+        android_atomic_inc(&mCount);
+    }
+    inline void decStrong(void*) const {
+        if (android_atomic_dec(&mCount) == 1)
+             delete this;
+    }
+};
+
+// ---------------------------------------------------------------------------
+
+class BClient : public BnSurfaceFlingerClient
+{
+public:
+    BClient(SurfaceFlinger *flinger, ClientID cid,
+            const sp<IMemory>& cblk);
+    ~BClient();
+
+    // ISurfaceFlingerClient interface
+    virtual void getControlBlocks(sp<IMemory>* ctrl) const;
+
+    virtual sp<ISurface> createSurface(
+            surface_data_t* params, int pid,
+            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<IMemory>         mCblk;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SURFACE_FLINGER_H
diff --git a/libs/surfaceflinger/Tokenizer.cpp b/libs/surfaceflinger/Tokenizer.cpp
new file mode 100644
index 0000000..ef51d6a
--- /dev/null
+++ b/libs/surfaceflinger/Tokenizer.cpp
@@ -0,0 +1,172 @@
+/*
+ * 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 = %lu)\n", this, c);
+    for (size_t i=0 ; i<c ; i++) {
+        printf("%lu: (%u, %u)\n", i, ranges[i].first, ranges[i].length);
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/surfaceflinger/Tokenizer.h b/libs/surfaceflinger/Tokenizer.h
new file mode 100644
index 0000000..6b3057d
--- /dev/null
+++ b/libs/surfaceflinger/Tokenizer.h
@@ -0,0 +1,57 @@
+/*
+ * 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
new file mode 100644
index 0000000..bec7a64
--- /dev/null
+++ b/libs/surfaceflinger/Transform.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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 <ui/Region.h>
+
+#include <private/pixelflinger/ggl_fixed.h>
+
+#include "Transform.h"
+
+// ---------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+Transform::Transform()
+    : mType(0)
+{
+    mTransform.reset();
+}
+
+Transform::Transform(const Transform&  other)
+    : mTransform(other.mTransform), mType(other.mType)
+{
+}
+
+Transform::~Transform() {
+}
+
+Transform Transform::operator * (const Transform& rhs) const
+{
+    if (LIKELY(mType == 0))
+        return rhs;
+
+    Transform r(*this);
+    r.mTransform.preConcat(rhs.mTransform);
+    r.mType |= rhs.mType;
+    return r;
+}
+
+float Transform::operator [] (int i) const
+{
+    float r = 0;
+    switch(i) {
+        case 0: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleX] );  break;
+        case 1: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewX] );   break;
+        case 2: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewY] );   break;
+        case 3: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleY] );  break;
+    }
+    return r;
+}
+
+uint8_t Transform::type() const
+{
+    if (UNLIKELY(mType & 0x80000000)) {
+        mType = mTransform.getType();
+    }
+    return uint8_t(mType & 0xFF);
+}
+
+bool Transform::transformed() const {
+    return type() > SkMatrix::kTranslate_Mask;
+}
+
+int Transform::tx() const {
+    return SkScalarRound( mTransform[SkMatrix::kMTransX] );
+}
+
+int Transform::ty() const {
+    return SkScalarRound( mTransform[SkMatrix::kMTransY] );
+}
+
+void Transform::reset() {
+    mTransform.reset();
+    mType = 0;
+}
+
+void Transform::set( float xx, float xy,
+                     float yx, float yy)
+{
+    mTransform.set(SkMatrix::kMScaleX, SkFloatToScalar(xx));
+    mTransform.set(SkMatrix::kMSkewX, SkFloatToScalar(xy));
+    mTransform.set(SkMatrix::kMSkewY, SkFloatToScalar(yx));
+    mTransform.set(SkMatrix::kMScaleY, SkFloatToScalar(yy));
+    mType |= 0x80000000;
+}
+
+void Transform::set(int tx, int ty)
+{
+    if (tx | ty) {
+        mTransform.set(SkMatrix::kMTransX, SkIntToScalar(tx));
+        mTransform.set(SkMatrix::kMTransY, SkIntToScalar(ty));
+        mType |= SkMatrix::kTranslate_Mask;
+    } else {
+        mTransform.set(SkMatrix::kMTransX, 0);
+        mTransform.set(SkMatrix::kMTransY, 0);
+        mType &= ~SkMatrix::kTranslate_Mask;
+    }
+}
+
+void Transform::transform(GLfixed* point, int x, int y) const
+{
+    SkPoint s;
+    mTransform.mapXY(SkIntToScalar(x), SkIntToScalar(y), &s);
+    point[0] = SkScalarToFixed(s.fX);
+    point[1] = SkScalarToFixed(s.fY);
+}
+
+Rect Transform::makeBounds(int w, int h) const
+{
+    Rect r;
+    SkRect d, s;
+    s.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
+    mTransform.mapRect(&d, s);
+    r.left   = SkScalarRound( d.fLeft );
+    r.top    = SkScalarRound( d.fTop );
+    r.right  = SkScalarRound( d.fRight );
+    r.bottom = SkScalarRound( d.fBottom );
+    return r;
+}
+
+Rect Transform::transform(const Rect& bounds) const
+{
+    Rect r;
+    SkRect d, s;
+    s.set(  SkIntToScalar( bounds.left ),
+            SkIntToScalar( bounds.top ),
+            SkIntToScalar( bounds.right ),
+            SkIntToScalar( bounds.bottom ));
+    mTransform.mapRect(&d, s);
+    r.left   = SkScalarRound( d.fLeft );
+    r.top    = SkScalarRound( d.fTop );
+    r.right  = SkScalarRound( d.fRight );
+    r.bottom = SkScalarRound( d.fBottom );
+    return r;
+}
+
+Region Transform::transform(const Region& reg) const
+{
+    Region out;
+    if (UNLIKELY(transformed())) {
+        if (LIKELY(preserveRects())) {
+            Rect r;
+            Region::iterator iterator(reg);
+            while (iterator.iterate(&r)) {
+                out.orSelf(transform(r));
+            }
+        } else {
+            out.set(transform(reg.bounds()));
+        }
+    } else {
+        out = reg.translate(tx(), ty());
+    }
+    return out;
+}
+
+int32_t Transform::getOrientation() const
+{
+    uint32_t flags = 0;
+    if (UNLIKELY(transformed())) {
+        SkScalar a = mTransform[SkMatrix::kMScaleX];
+        SkScalar b = mTransform[SkMatrix::kMSkewX];
+        SkScalar c = mTransform[SkMatrix::kMSkewY];
+        SkScalar d = mTransform[SkMatrix::kMScaleY];
+        if (b==0 && c==0 && a && d) {
+            if (a<0)    flags |= FLIP_H;
+            if (d<0)    flags |= FLIP_V;
+        } else if (b && c && a==0 && d==0) {
+            flags |= ROT_90;
+            if (b>0)    flags |= FLIP_H;
+            if (c<0)    flags |= FLIP_V;
+        } else {
+            flags = 0x80000000;
+        }
+    }
+    return flags;
+}
+
+bool Transform::preserveRects() const
+{
+    return mTransform.rectStaysRect();
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
new file mode 100644
index 0000000..2f617c4
--- /dev/null
+++ b/libs/surfaceflinger/Transform.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TRANSFORM_H
+#define ANDROID_TRANSFORM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+#include <GLES/gl.h>
+
+#include <corecg/SkMatrix.h>
+
+namespace android {
+
+class Region;
+
+// ---------------------------------------------------------------------------
+
+class Transform
+{
+public:
+                    Transform();
+                    Transform(const Transform&  other);
+                    ~Transform();
+
+            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 = 0x80000000
+            };
+
+            bool    transformed() const;
+            int32_t getOrientation() const;
+            bool    preserveRects() const;
+            
+            int     tx() const;
+            int     ty() const;
+        
+            void    reset();
+            void    set(float xx, float xy, float yx, float yy);
+            void    set(int tx, int ty);
+
+            Rect    makeBounds(int w, int h) const;
+            void    transform(GLfixed* point, int x, int y) const;
+            Region  transform(const Region& reg) const;
+            Rect    transform(const Rect& bounds) const;
+
+            Transform operator * (const Transform& rhs) const;
+            float operator [] (int i) const;
+
+    inline uint32_t getType() const { return type(); }
+            
+    inline Transform(bool) : mType(0xFF) { };
+
+private:
+    uint8_t     type() const;
+
+private:
+            SkMatrix    mTransform;
+    mutable uint32_t    mType;      
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif /* ANDROID_TRANSFORM_H */
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp
new file mode 100644
index 0000000..3852d51
--- /dev/null
+++ b/libs/surfaceflinger/VRamHeap.cpp
@@ -0,0 +1,161 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+
+#include <GLES/eglnatives.h>
+
+#include "VRamHeap.h"
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Amount of memory we reserve for surface, per client in PMEM
+ * (PMEM is used for 2D acceleration)
+ * 8 MB of address space per client should be enough.
+ */
+static const int PMEM_SIZE = int(8 * 1024 * 1024);
+
+int SurfaceHeapManager::global_pmem_heap = 0;
+
+// ---------------------------------------------------------------------------
+
+SurfaceHeapManager::SurfaceHeapManager(size_t clientHeapSize)
+    : mClientHeapSize(clientHeapSize)
+{
+    SurfaceHeapManager::global_pmem_heap = 1;
+}
+
+SurfaceHeapManager::~SurfaceHeapManager()
+{
+}
+
+void SurfaceHeapManager::onFirstRef()
+{
+    if (global_pmem_heap) {
+        const char* device = "/dev/pmem";
+        mPMemHeap = new PMemHeap(device, PMEM_SIZE);
+        if (mPMemHeap->base() == MAP_FAILED) {
+            mPMemHeap.clear();
+            global_pmem_heap = 0;
+        }
+    }
+}
+
+sp<MemoryDealer> SurfaceHeapManager::createHeap(int type)
+{
+    if (!global_pmem_heap && type==NATIVE_MEMORY_TYPE_PMEM)
+        type = NATIVE_MEMORY_TYPE_HEAP;
+
+    const sp<PMemHeap>& heap(mPMemHeap);
+    sp<MemoryDealer> dealer; 
+    switch (type) {
+    case NATIVE_MEMORY_TYPE_HEAP:
+        dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap");
+        break;
+
+    case NATIVE_MEMORY_TYPE_PMEM:
+        if (heap != 0) {
+            dealer = new MemoryDealer( 
+                    heap->createClientHeap(),
+                    heap->getAllocator());
+        }
+        break;
+    }
+    return dealer;
+}
+
+sp<SimpleBestFitAllocator> SurfaceHeapManager::getAllocator(int type) const 
+{
+    Mutex::Autolock _l(mLock);
+    sp<SimpleBestFitAllocator> allocator;
+
+    // this is only used for debugging
+    switch (type) {
+        case NATIVE_MEMORY_TYPE_PMEM:
+            if (mPMemHeap != 0) {
+                allocator = mPMemHeap->getAllocator();
+            }
+            break;
+    }
+    return allocator;
+}
+
+// ---------------------------------------------------------------------------
+
+PMemHeapInterface::PMemHeapInterface(int fd, size_t size)
+    : MemoryHeapBase(fd, size) {
+}
+PMemHeapInterface::PMemHeapInterface(const char* device, size_t size)
+    : MemoryHeapBase(device, size) {
+}
+PMemHeapInterface::PMemHeapInterface(size_t size, uint32_t flags, char const * name)
+    : MemoryHeapBase(size, flags, name) {
+}
+PMemHeapInterface::~PMemHeapInterface() {
+}
+
+// ---------------------------------------------------------------------------
+
+PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved)
+    : PMemHeapInterface(device, size)
+{
+    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
+    if (base() != MAP_FAILED) {
+        //LOGD("%s, %u bytes", device, virtualSize());
+        if (reserved == 0)
+            reserved = virtualSize();
+        mAllocator = new SimpleBestFitAllocator(reserved);
+    }
+}
+
+PMemHeap::~PMemHeap() {
+    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
+}
+
+sp<MemoryHeapPmem> PMemHeap::createClientHeap() {
+    sp<MemoryHeapBase> parentHeap(this);
+    return new MemoryHeapPmem(parentHeap);
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger/VRamHeap.h b/libs/surfaceflinger/VRamHeap.h
new file mode 100644
index 0000000..03e0336
--- /dev/null
+++ b/libs/surfaceflinger/VRamHeap.h
@@ -0,0 +1,86 @@
+/*
+ * 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_VRAM_HEAP_H
+#define ANDROID_VRAM_HEAP_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/MemoryDealer.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class PMemHeap;
+class MemoryHeapPmem;
+
+// ---------------------------------------------------------------------------
+
+class SurfaceHeapManager  : public RefBase
+{
+public:
+    SurfaceHeapManager(size_t clientHeapSize);
+    virtual ~SurfaceHeapManager();
+    virtual void onFirstRef();
+    sp<MemoryDealer> createHeap(int type);
+    
+    // used for debugging only...
+    sp<SimpleBestFitAllocator> getAllocator(int type) const;
+
+private:
+    sp<PMemHeap> getHeap(int type) const;
+
+    mutable Mutex   mLock;
+    size_t          mClientHeapSize;
+    sp<PMemHeap>    mPMemHeap;
+    static int global_pmem_heap;
+};
+
+// ---------------------------------------------------------------------------
+
+class PMemHeapInterface : public MemoryHeapBase
+{
+public:
+    PMemHeapInterface(int fd, size_t size);
+    PMemHeapInterface(const char* device, size_t size = 0);
+    PMemHeapInterface(size_t size, uint32_t flags = 0, char const * name = NULL);
+    virtual ~PMemHeapInterface();
+    virtual sp<MemoryHeapPmem> createClientHeap() = 0;
+};
+
+// ---------------------------------------------------------------------------
+
+class PMemHeap : public PMemHeapInterface
+{
+public:
+                PMemHeap(const char* const vram,
+                        size_t size=0, size_t reserved=0);
+    virtual     ~PMemHeap();
+    
+    virtual const sp<SimpleBestFitAllocator>& getAllocator() const {
+        return mAllocator; 
+    }
+    virtual sp<MemoryHeapPmem> createClientHeap();
+    
+private:
+    sp<SimpleBestFitAllocator>  mAllocator;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_VRAM_HEAP_H
diff --git a/libs/surfaceflinger/clz.cpp b/libs/surfaceflinger/clz.cpp
new file mode 100644
index 0000000..2456b86
--- /dev/null
+++ b/libs/surfaceflinger/clz.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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 "clz.h"
+
+namespace android {
+
+int clz_impl(int32_t x)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    return __builtin_clz(x);
+#else
+    if (!x) return 32;
+    int e = 31;
+    if (x&0xFFFF0000)   { e -=16; x >>=16; }
+    if (x&0x0000FF00)   { e -= 8; x >>= 8; }
+    if (x&0x000000F0)   { e -= 4; x >>= 4; }
+    if (x&0x0000000C)   { e -= 2; x >>= 2; }
+    if (x&0x00000002)   { e -= 1; }
+    return e;
+#endif
+}
+
+}; // namespace android
diff --git a/libs/surfaceflinger/clz.h b/libs/surfaceflinger/clz.h
new file mode 100644
index 0000000..0ddf986
--- /dev/null
+++ b/libs/surfaceflinger/clz.h
@@ -0,0 +1,37 @@
+/*
+ * 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_CLZ_H
+
+#include <stdint.h>
+
+namespace android {
+
+int clz_impl(int32_t x);
+
+int inline clz(int32_t x)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    return __builtin_clz(x);
+#else
+    return clz_impl(x);
+#endif
+}
+
+
+}; // namespace android
+
+#endif /* ANDROID_SURFACE_FLINGER_CLZ_H */
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
new file mode 100644
index 0000000..71579c5
--- /dev/null
+++ b/libs/ui/Android.mk
@@ -0,0 +1,39 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	BlitHardware.cpp \
+	Camera.cpp \
+	CameraParameters.cpp \
+	EGLDisplaySurface.cpp \
+	EGLNativeWindowSurface.cpp \
+	EventHub.cpp \
+	EventRecurrence.cpp \
+	KeyLayoutMap.cpp \
+	KeyCharacterMap.cpp \
+	ICamera.cpp \
+	ICameraClient.cpp \
+	ICameraService.cpp \
+	ISurfaceComposer.cpp \
+	ISurface.cpp \
+	ISurfaceFlingerClient.cpp \
+	LayerState.cpp \
+	PixelFormat.cpp \
+	Point.cpp \
+	Rect.cpp \
+	Region.cpp \
+	Surface.cpp \
+	SurfaceComposerClient.cpp \
+	SurfaceFlingerSynchro.cpp \
+	Time.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcorecg \
+	libcutils \
+	libutils \
+	libpixelflinger \
+	libhardware
+
+LOCAL_MODULE:= libui
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/BlitHardware.cpp b/libs/ui/BlitHardware.cpp
new file mode 100644
index 0000000..90838b4
--- /dev/null
+++ b/libs/ui/BlitHardware.cpp
@@ -0,0 +1,446 @@
+/*
+ * 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 "SurfaceFlinger"
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <cutils/log.h>
+
+#include <utils/Errors.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+#endif
+
+#include <ui/BlitHardware.h>
+
+/******************************************************************************/
+
+namespace android {
+class CopybitMSM7K : public copybit_t {
+public:
+    CopybitMSM7K();
+    ~CopybitMSM7K();
+    
+    status_t getStatus() const {
+        if (mFD<0) return mFD;
+        return NO_ERROR;
+    }
+
+    status_t setParameter(int name, int value);
+
+    status_t get(int name);
+
+    status_t blit( 
+            const copybit_image_t& dst,
+            const copybit_image_t& src,
+            copybit_region_t const* region);
+
+    status_t stretch( 
+            const copybit_image_t& dst,
+            const copybit_image_t& src, 
+            const copybit_rect_t& dst_rect,
+            const copybit_rect_t& src_rect,
+            copybit_region_t const* region);
+
+#if HAVE_ANDROID_OS
+private:
+    static int copybit_set_parameter(copybit_t* handle, int name, int value);
+    static int copybit_blit( copybit_t* handle, 
+            copybit_image_t const* dst, copybit_image_t const* src,
+            copybit_region_t const* region);
+    static int copybit_stretch(copybit_t* handle, 
+            copybit_image_t const* dst,  copybit_image_t const* src, 
+            copybit_rect_t const* dst_rect, copybit_rect_t const* src_rect,
+            copybit_region_t const* region);
+    static int copybit_get(copybit_t* handle, int name);
+
+    int getFormat(int format);
+    void setImage(mdp_img* img, const copybit_image_t& rhs);
+    void setRects(mdp_blit_req* req, const copybit_rect_t& dst,
+            const copybit_rect_t& src, const copybit_rect_t& scissor);
+    void setInfos(mdp_blit_req* req);
+    static void intersect(copybit_rect_t* out, 
+            const copybit_rect_t& lhs, const copybit_rect_t& rhs);
+    status_t msm_copybit(void const* list);
+#endif
+    int mFD;
+    uint8_t mAlpha;
+    uint8_t mFlags;
+};
+}; // namespace android
+
+using namespace android;
+
+/******************************************************************************/
+
+struct copybit_t* copybit_init()
+{
+    CopybitMSM7K* engine = new CopybitMSM7K();
+    if (engine->getStatus() != NO_ERROR) {
+        delete engine;
+        engine = 0;
+    }
+    return (struct copybit_t*)engine;
+        
+}
+
+int copybit_term(copybit_t* handle)
+{
+    delete static_cast<CopybitMSM7K*>(handle);
+    return NO_ERROR;
+}
+
+namespace android {
+/******************************************************************************/
+
+static inline
+int min(int a, int b) {
+    return (a<b) ? a : b;
+}
+
+static inline
+int max(int a, int b) {
+    return (a>b) ? a : b;
+}
+
+static inline
+void MULDIV(uint32_t& a, uint32_t& b, int mul, int div)
+{
+    if (mul != div) {
+        a = (mul * a) / div;
+        b = (mul * b) / div;
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+#if HAVE_ANDROID_OS
+
+int CopybitMSM7K::copybit_set_parameter(copybit_t* handle, int name, int value)
+{
+    return static_cast<CopybitMSM7K*>(handle)->setParameter(name, value);
+}
+
+int CopybitMSM7K::copybit_get(copybit_t* handle, int name)
+{
+    return static_cast<CopybitMSM7K*>(handle)->get(name);
+}
+
+int CopybitMSM7K::copybit_blit(
+        copybit_t* handle, 
+        copybit_image_t const* dst, 
+        copybit_image_t const* src,
+        struct copybit_region_t const* region)
+{
+    return static_cast<CopybitMSM7K*>(handle)->blit(*dst, *src, region);
+}
+
+int CopybitMSM7K::copybit_stretch(
+        copybit_t* handle, 
+        copybit_image_t const* dst, 
+        copybit_image_t const* src, 
+        copybit_rect_t const* dst_rect,
+        copybit_rect_t const* src_rect,
+        struct copybit_region_t const* region)
+{
+    return static_cast<CopybitMSM7K*>(handle)->stretch(
+            *dst, *src, *dst_rect, *src_rect, region);
+}
+
+//-----------------------------------------------------------------------------
+
+CopybitMSM7K::CopybitMSM7K()
+    : mFD(-1), mAlpha(MDP_ALPHA_NOP), mFlags(0)
+{
+    int fd = open("/dev/graphics/fb0", O_RDWR, 0);
+    if (fd > 0) {
+        struct fb_fix_screeninfo finfo;
+        if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == 0) {
+            if (!strcmp(finfo.id, "msmfb")) {
+                mFD = fd;
+                copybit_t::set_parameter = copybit_set_parameter;
+                copybit_t::get = copybit_get;
+                copybit_t::blit = copybit_blit;
+                copybit_t::stretch = copybit_stretch;
+            }
+        }
+    }
+    if (fd<0 || mFD<0) {
+        if (fd>0) { close(fd); }
+        mFD = -errno;
+    }
+}
+
+CopybitMSM7K::~CopybitMSM7K()
+{
+    if (mFD > 0){
+        close(mFD);
+    }
+}
+
+status_t CopybitMSM7K::setParameter(int name, int value)
+{
+    switch(name) {
+    case COPYBIT_ROTATION_DEG:
+        switch (value) {
+        case 0:
+            mFlags &= ~0x7;
+            break;
+        case 90:
+            mFlags &= ~0x7;
+            mFlags |= MDP_ROT_90;
+            break;
+        case 180:
+            mFlags &= ~0x7;
+            mFlags |= MDP_ROT_180;
+            break;
+        case 270:
+            mFlags &= ~0x7;
+            mFlags |= MDP_ROT_270;
+            break;
+        default:
+            return BAD_VALUE;
+        }
+        break;
+    case COPYBIT_PLANE_ALPHA:
+        if (value < 0)      value = 0;
+        if (value >= 256)   value = 255;
+        mAlpha = value;
+        break;
+    case COPYBIT_DITHER:
+        if (value == COPYBIT_ENABLE) {
+            mFlags |= MDP_DITHER;
+        } else if (value == COPYBIT_DISABLE) {
+            mFlags &= ~MDP_DITHER;
+        }
+        break;
+    case COPYBIT_TRANSFORM:
+        mFlags &= ~0x7;
+        mFlags |= value & 0x7;
+        break;
+    default:
+        return BAD_VALUE;
+    }
+    return NO_ERROR;
+}
+
+status_t CopybitMSM7K::get(int name)
+{
+    switch(name) {
+    case COPYBIT_MINIFICATION_LIMIT:
+        return 4;
+    case COPYBIT_MAGNIFICATION_LIMIT:
+        return 4;
+    case COPYBIT_SCALING_FRAC_BITS:
+        return 32;
+    case COPYBIT_ROTATION_STEP_DEG:
+        return 90;
+    }
+    return BAD_VALUE;
+}
+
+status_t CopybitMSM7K::blit( 
+        const copybit_image_t& dst,
+        const copybit_image_t& src,
+        copybit_region_t const* region)
+{
+    
+    copybit_rect_t dr = { 0, 0, dst.w, dst.h };
+    copybit_rect_t sr = { 0, 0, src.w, src.h };
+    return CopybitMSM7K::stretch(dst, src, dr, sr, region);
+}
+
+status_t CopybitMSM7K::stretch( 
+        const copybit_image_t& dst,
+        const copybit_image_t& src, 
+        const copybit_rect_t& dst_rect,
+        const copybit_rect_t& src_rect,
+        copybit_region_t const* region)
+{
+    struct {
+        uint32_t count;
+        struct mdp_blit_req req[12];
+    } list;
+    
+    if (mAlpha<255) {
+        switch (src.format) {
+            // we dont' support plane alpha with RGBA formats
+            case COPYBIT_RGBA_8888:
+            case COPYBIT_RGBA_5551:
+            case COPYBIT_RGBA_4444:
+                return INVALID_OPERATION;
+        }
+    }
+        
+    const uint32_t maxCount = sizeof(list.req)/sizeof(list.req[0]);
+    const copybit_rect_t bounds = { 0, 0, dst.w, dst.h };
+    copybit_rect_t clip;
+    list.count = 0;
+    int err = 0;
+    while (!err && region->next(region, &clip)) {
+        intersect(&clip, bounds, clip);
+        setInfos(&list.req[list.count]);
+        setImage(&list.req[list.count].dst, dst);
+        setImage(&list.req[list.count].src, src);
+        setRects(&list.req[list.count], dst_rect, src_rect, clip);
+        if (++list.count == maxCount) {
+            err = msm_copybit(&list);
+            list.count = 0;
+        }
+    }
+    if (!err && list.count) {
+        err = msm_copybit(&list);
+    }
+    return err;
+}
+
+status_t CopybitMSM7K::msm_copybit(void const* list)
+{
+    int err = ioctl(mFD, MSMFB_BLIT, static_cast<mdp_blit_req_list const*>(list));
+    LOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
+    if (err == 0)
+        return NO_ERROR;
+    return -errno;
+}
+
+int CopybitMSM7K::getFormat(int format)
+{
+    switch (format) {
+    case COPYBIT_RGBA_8888:     return MDP_RGBA_8888;
+    case COPYBIT_RGB_565:       return MDP_RGB_565;
+    case COPYBIT_YCbCr_422_SP:  return MDP_Y_CBCR_H2V1;
+    case COPYBIT_YCbCr_420_SP:  return MDP_Y_CBCR_H2V2;
+    }
+    return -1;
+}
+
+void CopybitMSM7K::setInfos(mdp_blit_req* req)
+{
+    req->alpha = mAlpha;
+    req->transp_mask = MDP_TRANSP_NOP;
+    req->flags = mFlags;
+}
+
+void CopybitMSM7K::setImage(mdp_img* img, const copybit_image_t& rhs)
+{
+    img->width      = rhs.w;
+    img->height     = rhs.h;
+    img->format     = getFormat(rhs.format);
+    img->offset     = rhs.offset;
+    img->memory_id  = rhs.fd;
+}
+    
+void CopybitMSM7K::setRects(mdp_blit_req* e, 
+        const copybit_rect_t& dst, const copybit_rect_t& src,
+        const copybit_rect_t& scissor)
+{
+    copybit_rect_t clip;
+    intersect(&clip, scissor, dst);
+
+    e->dst_rect.x  = clip.l;
+    e->dst_rect.y  = clip.t;
+    e->dst_rect.w  = clip.r - clip.l;
+    e->dst_rect.h  = clip.b - clip.t;
+
+    uint32_t W, H;
+    if (mFlags & COPYBIT_TRANSFORM_ROT_90) {
+        e->src_rect.x  = (clip.t - dst.t) + src.t;
+        e->src_rect.y  = (dst.r - clip.r) + src.l;
+        e->src_rect.w  = (clip.b - clip.t);
+        e->src_rect.h  = (clip.r - clip.l);
+        W = dst.b - dst.t;
+        H = dst.r - dst.l;
+    } else {
+        e->src_rect.x  = (clip.l - dst.l) + src.l;
+        e->src_rect.y  = (clip.t - dst.t) + src.t;
+        e->src_rect.w  = (clip.r - clip.l);
+        e->src_rect.h  = (clip.b - clip.t);
+        W = dst.r - dst.l;
+        H = dst.b - dst.t;
+    }
+    MULDIV(e->src_rect.x, e->src_rect.w, src.r - src.l, W);
+    MULDIV(e->src_rect.y, e->src_rect.h, src.b - src.t, H);
+    if (mFlags & COPYBIT_TRANSFORM_FLIP_V) {
+        e->src_rect.y = e->src.height - (e->src_rect.y + e->src_rect.h);
+    }
+    if (mFlags & COPYBIT_TRANSFORM_FLIP_H) {
+        e->src_rect.x = e->src.width  - (e->src_rect.x + e->src_rect.w);
+    }
+}
+
+void CopybitMSM7K::intersect(copybit_rect_t* out, 
+        const copybit_rect_t& lhs, const copybit_rect_t& rhs)
+{
+    out->l = max(lhs.l, rhs.l);
+    out->t = max(lhs.t, rhs.t);
+    out->r = min(lhs.r, rhs.r);
+    out->b = min(lhs.b, rhs.b);
+}
+
+/******************************************************************************/
+#else // HAVE_ANDROID_OS
+
+CopybitMSM7K::CopybitMSM7K()
+    : mFD(-1)
+{
+}
+
+CopybitMSM7K::~CopybitMSM7K()
+{
+}
+
+status_t CopybitMSM7K::setParameter(int name, int value)
+{
+    return NO_INIT;
+}
+
+status_t CopybitMSM7K::get(int name)
+{
+    return BAD_VALUE;
+}
+
+status_t CopybitMSM7K::blit( 
+        const copybit_image_t& dst,
+        const copybit_image_t& src,
+        copybit_region_t const* region)
+{
+    return NO_INIT;
+}
+
+status_t CopybitMSM7K::stretch( 
+        const copybit_image_t& dst,
+        const copybit_image_t& src, 
+        const copybit_rect_t& dst_rect,
+        const copybit_rect_t& src_rect,
+        copybit_region_t const* region)
+{
+    return NO_INIT;
+}
+
+#endif // HAVE_ANDROID_OS
+
+/******************************************************************************/
+}; // namespace android
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
new file mode 100644
index 0000000..1528e6e
--- /dev/null
+++ b/libs/ui/Camera.cpp
@@ -0,0 +1,249 @@
+/*
+**
+** 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 "Camera"
+#include <utils/Log.h>
+
+#include <utils/IServiceManager.h>
+#include <utils/threads.h>
+#include <utils/IMemory.h>
+#include <ui/Surface.h>
+
+#include <ui/Camera.h>
+#include <ui/ICameraService.h>
+
+namespace android {
+
+// client singleton for camera service binder interface
+Mutex Camera::mLock;
+sp<ICameraService> Camera::mCameraService;
+sp<Camera::DeathNotifier> Camera::mDeathNotifier;
+
+// establish binder interface to camera service
+const sp<ICameraService>& Camera::getCameraService()
+{
+    Mutex::Autolock _l(mLock);
+    if (mCameraService.get() == 0) {
+        sp<IServiceManager> sm = defaultServiceManager();
+        sp<IBinder> binder;
+        do {
+            binder = sm->getService(String16("media.camera"));
+            if (binder != 0)
+                break;
+            LOGW("CameraService not published, waiting...");
+            usleep(500000); // 0.5 s
+        } while(true);
+        if (mDeathNotifier == NULL) {
+            mDeathNotifier = new DeathNotifier();
+        }
+        binder->linkToDeath(mDeathNotifier);
+        mCameraService = interface_cast<ICameraService>(binder);
+    }
+    LOGE_IF(mCameraService==0, "no CameraService!?");
+    return mCameraService;
+}
+
+// ---------------------------------------------------------------------------
+
+Camera::Camera()
+      : mStatus(UNKNOWN_ERROR),
+        mShutterCallback(0),
+        mShutterCallbackCookie(0),
+        mRawCallback(0),
+        mRawCallbackCookie(0),
+        mJpegCallback(0),
+        mJpegCallbackCookie(0),
+        mFrameCallback(0),
+        mFrameCallbackCookie(0),
+        mErrorCallback(0),
+        mErrorCallbackCookie(0),
+        mAutoFocusCallback(0),
+        mAutoFocusCallbackCookie(0)
+{
+}
+
+Camera::~Camera()
+{
+    disconnect();
+}
+
+sp<Camera> Camera::connect()
+{
+    sp<Camera> c = new Camera();
+    const sp<ICameraService>& cs = getCameraService();
+    if (cs != 0) {
+        c->mCamera = cs->connect(c);
+    }
+    if (c->mCamera != 0) {
+        c->mCamera->asBinder()->linkToDeath(c);
+        c->mStatus = NO_ERROR;
+    }
+    return c;
+}
+
+void Camera::disconnect()
+{
+    if (mCamera != 0) {
+        mErrorCallback = 0;
+        mCamera->disconnect();
+        mCamera = 0;
+    }
+}
+
+// pass the buffered ISurface to the camera service
+status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
+{
+    if (surface == 0) {
+        LOGE("app passed NULL surface");
+        return NO_INIT;
+    }
+    return mCamera->setPreviewDisplay(surface->getISurface());
+}
+
+// start preview mode, must call setPreviewDisplay first
+status_t Camera::startPreview()
+{
+    return mCamera->startPreview();
+}
+
+// stop preview mode
+void Camera::stopPreview()
+{
+    mCamera->stopPreview();
+}
+
+status_t Camera::autoFocus()
+{
+    return mCamera->autoFocus();
+}
+
+// take a picture
+status_t Camera::takePicture()
+{
+    return mCamera->takePicture();
+}
+
+// set preview/capture parameters - key/value pairs
+status_t Camera::setParameters(const String8& params)
+{
+    return mCamera->setParameters(params);
+}
+
+// get preview/capture parameters - key/value pairs
+String8 Camera::getParameters() const
+{
+    String8 params = mCamera->getParameters();
+    return params;
+}
+
+void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
+{
+    mAutoFocusCallback = cb;
+    mAutoFocusCallbackCookie = cookie;
+}
+
+void Camera::setShutterCallback(shutter_callback cb, void *cookie)
+{
+    mShutterCallback = cb;
+    mShutterCallbackCookie = cookie;
+}
+
+void Camera::setRawCallback(frame_callback cb, void *cookie)
+{
+    mRawCallback = cb;
+    mRawCallbackCookie = cookie;
+}
+
+void Camera::setJpegCallback(frame_callback cb, void *cookie)
+{
+    mJpegCallback = cb;
+    mJpegCallbackCookie = cookie;
+}
+
+void Camera::setFrameCallback(frame_callback cb, void *cookie)
+{
+    mFrameCallback = cb;
+    mFrameCallbackCookie = cookie;
+    mCamera->setHasFrameCallback(cb != NULL);
+}
+
+void Camera::setErrorCallback(error_callback cb, void *cookie)
+{
+    mErrorCallback = cb;
+    mErrorCallbackCookie = cookie;
+}
+
+void Camera::autoFocusCallback(bool focused)
+{
+    if (mAutoFocusCallback) {
+        mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
+    }
+}
+
+void Camera::shutterCallback()
+{
+    if (mShutterCallback) {
+        mShutterCallback(mShutterCallbackCookie);
+    }
+}
+
+void Camera::rawCallback(const sp<IMemory>& picture)
+{
+    if (mRawCallback) {
+        mRawCallback(picture, mRawCallbackCookie);
+    }
+}
+
+// callback from camera service when image is ready
+void Camera::jpegCallback(const sp<IMemory>& picture)
+{
+    if (mJpegCallback) {
+        mJpegCallback(picture, mJpegCallbackCookie);
+    }
+}
+
+// callback from camera service when video frame is ready
+void Camera::frameCallback(const sp<IMemory>& frame)
+{
+    if (mFrameCallback) {
+        mFrameCallback(frame, mFrameCallbackCookie);
+    }
+}
+
+// callback from camera service when an error occurs in preview or takePicture
+void Camera::errorCallback(status_t error)
+{
+    if (mErrorCallback) {
+        mErrorCallback(error, mErrorCallbackCookie);
+    }
+}
+
+void Camera::binderDied(const wp<IBinder>& who) {    
+    LOGW("ICamera died");
+    if (mErrorCallback) {
+        mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
+    }
+}
+
+void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {    
+    Mutex::Autolock _l(Camera::mLock);
+    Camera::mCameraService.clear();
+    LOGW("Camera server died!");
+}
+
+}; // namespace android
+
diff --git a/libs/ui/CameraParameters.cpp b/libs/ui/CameraParameters.cpp
new file mode 100644
index 0000000..7ca77bb
--- /dev/null
+++ b/libs/ui/CameraParameters.cpp
@@ -0,0 +1,253 @@
+/*
+**
+** 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 "CameraParams"
+#include <utils/Log.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <ui/CameraParameters.h>
+
+namespace android {
+
+CameraParameters::CameraParameters()
+                : mMap()
+{
+}
+
+CameraParameters::~CameraParameters()
+{
+}
+
+String8 CameraParameters::flatten() const
+{
+    String8 flattened("");
+    size_t size = mMap.size();
+
+    for (size_t i = 0; i < size; i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+
+        flattened += k;
+        flattened += "=";
+        flattened += v;
+        if (i != size-1)
+            flattened += ";";
+    }
+
+    return flattened;
+}
+
+void CameraParameters::unflatten(const String8 &params)
+{
+    const char *a = params.string();
+    const char *b;
+
+    mMap.clear();
+
+    for (;;) {
+        // Find the bounds of the key name.
+        b = strchr(a, '=');
+        if (b == 0)
+            break;
+
+        // Create the key string.
+        String8 k(a, (size_t)(b-a));
+
+        // Find the value.
+        a = b+1;
+        b = strchr(a, ';');
+        if (b == 0) {
+            // If there's no semicolon, this is the last item.
+            String8 v(a);
+            mMap.add(k, v);
+            break;
+        }
+
+        String8 v(a, (size_t)(b-a));
+        mMap.add(k, v);
+        a = b+1;
+    }
+}
+
+
+void CameraParameters::set(const char *key, const char *value)
+{
+    // XXX i think i can do this with strspn() 
+    if (strchr(key, '=') || strchr(key, ';')) {
+        //XXX LOGE("Key \"%s\"contains invalid character (= or ;)", key);
+        return;
+    }
+
+    if (strchr(value, '=') || strchr(key, ';')) {
+        //XXX LOGE("Value \"%s\"contains invalid character (= or ;)", value);
+        return;
+    }
+
+    mMap.replaceValueFor(String8(key), String8(value));
+}
+
+void CameraParameters::set(const char *key, int value)
+{
+    char str[16];
+    sprintf(str, "%d", value);
+    set(key, str);
+}
+
+const char *CameraParameters::get(const char *key) const
+{
+    String8 v = mMap.valueFor(String8(key));
+    if (v.length() == 0)
+        return 0;
+    return v.string();
+}
+
+int CameraParameters::getInt(const char *key) const
+{
+    const char *v = get(key);
+    if (v == 0)
+        return -1;
+    return strtol(v, 0, 0);
+}
+
+static int parse_size(const char *str, int &width, int &height)
+{
+    // Find the width.
+    char *end;
+    int w = (int)strtol(str, &end, 10);
+    // If an 'x' does not immediately follow, give up.
+    if (*end != 'x')
+        return -1;
+
+    // Find the height, immediately after the 'x'.
+    int h = (int)strtol(end+1, 0, 10);
+
+    width = w;
+    height = h;
+
+    return 0;
+}
+
+void CameraParameters::setPreviewSize(int width, int height)
+{
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set("preview-size", str);
+}
+
+void CameraParameters::getPreviewSize(int *width, int *height) const
+{
+    *width = -1;
+    *height = -1;
+
+    // Get the current string, if it doesn't exist, leave the -1x-1
+    const char *p = get("preview-size");
+    if (p == 0)
+        return;
+
+    int w, h;
+    if (parse_size(p, w, h) == 0) {
+        *width = w;
+        *height = h;
+    }
+}
+
+void CameraParameters::setPreviewFrameRate(int fps)
+{
+    set("preview-frame-rate", fps);
+}
+
+int CameraParameters::getPreviewFrameRate() const
+{
+    return getInt("preview-frame-rate");
+}
+
+void CameraParameters::setPreviewFormat(const char *format)
+{
+    set("preview-format", format);
+}
+
+const char *CameraParameters::getPreviewFormat() const
+{
+    return get("preview-format");
+}
+
+void CameraParameters::setPictureSize(int width, int height)
+{
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set("picture-size", str);
+}
+
+void CameraParameters::getPictureSize(int *width, int *height) const
+{
+    *width = -1;
+    *height = -1;
+
+    // Get the current string, if it doesn't exist, leave the -1x-1
+    const char *p = get("picture-size");
+    if (p == 0)
+        return;
+
+    int w, h;
+    if (parse_size(p, w, h) == 0) {
+        *width = w;
+        *height = h;
+    }
+}
+
+void CameraParameters::setPictureFormat(const char *format)
+{
+    set("picture-format", format);
+}
+
+const char *CameraParameters::getPictureFormat() const
+{
+    return get("picture-format");
+}
+
+void CameraParameters::dump() const
+{
+    LOGD("dump: mMap.size = %d", mMap.size());
+    for (size_t i = 0; i < mMap.size(); i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+        LOGD("%s: %s\n", k.string(), v.string());
+    }
+}
+
+status_t CameraParameters::dump(int fd, const Vector<String16>& args) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %d\n", mMap.size());
+    result.append(buffer);
+    for (size_t i = 0; i < mMap.size(); i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+        snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/libs/ui/EGLDisplaySurface.cpp b/libs/ui/EGLDisplaySurface.cpp
new file mode 100644
index 0000000..ea245f5
--- /dev/null
+++ b/libs/ui/EGLDisplaySurface.cpp
@@ -0,0 +1,471 @@
+/*
+ **
+ ** 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 "EGLDisplaySurface"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <ui/SurfaceComposerClient.h>
+#include <ui/DisplayInfo.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/msm_mdp.h>
+#endif
+
+#include <GLES/egl.h>
+
+#include <pixelflinger/format.h>
+
+#include <ui/EGLDisplaySurface.h>
+
+// ----------------------------------------------------------------------------
+
+egl_native_window_t* android_createDisplaySurface()
+{
+    egl_native_window_t* s = new android::EGLDisplaySurface();
+    s->memory_type = NATIVE_MEMORY_TYPE_GPU;
+    return s;
+}
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+EGLDisplaySurface::EGLDisplaySurface()
+    : EGLNativeSurface<EGLDisplaySurface>()
+{
+    egl_native_window_t::version = sizeof(egl_native_window_t);
+    egl_native_window_t::ident = 0;
+    egl_native_window_t::incRef = &EGLDisplaySurface::hook_incRef;
+    egl_native_window_t::decRef = &EGLDisplaySurface::hook_decRef;
+    egl_native_window_t::swapBuffers = &EGLDisplaySurface::hook_swapBuffers;
+    egl_native_window_t::setSwapRectangle = &EGLDisplaySurface::hook_setSwapRectangle;
+    egl_native_window_t::nextBuffer = &EGLDisplaySurface::hook_nextBuffer;
+    egl_native_window_t::connect = 0;
+    egl_native_window_t::disconnect = 0;
+
+    mFb[0].data = 0;
+    mFb[1].data = 0;
+    mBlitEngine = 0;
+    egl_native_window_t::fd = mapFrameBuffer();
+    if (egl_native_window_t::fd >= 0) {
+        mBlitEngine = copybit_init();
+        const float in2mm = 25.4f;
+        float refreshRate = 1000000000000000LLU / (
+                float( mInfo.upper_margin + mInfo.lower_margin + mInfo.yres )
+                * ( mInfo.left_margin  + mInfo.right_margin + mInfo.xres )
+                * mInfo.pixclock);
+
+        const GGLSurface& buffer = mFb[1 - mIndex];
+        egl_native_window_t::width  = buffer.width;
+        egl_native_window_t::height = buffer.height;
+        egl_native_window_t::stride = buffer.stride;
+        egl_native_window_t::format = buffer.format;
+        egl_native_window_t::base   = intptr_t(mFb[0].data);
+        egl_native_window_t::offset =
+            intptr_t(buffer.data) - egl_native_window_t::base;
+        egl_native_window_t::flags  = 0;
+        egl_native_window_t::xdpi = (mInfo.xres * in2mm) / mInfo.width;
+        egl_native_window_t::ydpi = (mInfo.yres * in2mm) / mInfo.height;
+        egl_native_window_t::fps  = refreshRate;
+        egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_FB;
+        // no error, set the magic word
+        egl_native_window_t::magic = 0x600913;
+    }
+    mSwapCount = -1;
+    mPageFlipCount = 0;
+}
+
+EGLDisplaySurface::~EGLDisplaySurface()
+{
+    magic = 0;
+    copybit_term(mBlitEngine);
+    mBlitEngine = 0;
+    close(egl_native_window_t::fd);
+    munmap(mFb[0].data, mSize);
+    if (!(mFlags & PAGE_FLIP))
+        free((void*)mFb[1].data);
+}
+
+void EGLDisplaySurface::hook_incRef(NativeWindowType window) {
+    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
+    that->incStrong(that);
+}
+void EGLDisplaySurface::hook_decRef(NativeWindowType window) {
+    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
+    that->decStrong(that);
+}
+uint32_t EGLDisplaySurface::hook_swapBuffers(NativeWindowType window) {
+    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
+    return that->swapBuffers();
+}
+uint32_t EGLDisplaySurface::hook_nextBuffer(NativeWindowType window) {
+    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
+    return that->nextBuffer();
+}
+void EGLDisplaySurface::hook_setSwapRectangle(NativeWindowType window,
+        int l, int t, int w, int h) {
+    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
+    that->setSwapRectangle(l, t, w, h);
+}
+
+void EGLDisplaySurface::setSwapRectangle(int l, int t, int w, int h)
+{
+    mInfo.reserved[0] = 0x54445055; // "UPDT";
+    mInfo.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
+    mInfo.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
+}
+
+uint32_t EGLDisplaySurface::swapBuffers()
+{
+    if (!(mFlags & PAGE_FLIP))
+        return 0;
+
+#define SHOW_FPS 0
+#if SHOW_FPS
+    nsecs_t now = systemTime();
+    if (mSwapCount == -1) {
+        mTime = now;
+        mSwapCount = 0;
+        mSleep = 0;
+    } else {
+        nsecs_t d = now-mTime;
+        if (d >= seconds(1)) {
+            double fps = (mSwapCount * double(seconds(1))) / double(d);
+            LOGD("%f fps, sleep=%d / frame",
+                    fps, (int)ns2us(mSleep / mSwapCount));
+            mSwapCount = 0;
+            mTime = now;
+            mSleep = 0;
+        } else {
+            mSwapCount++;
+        }
+    }
+#endif
+
+    // do the actual flip
+    mIndex = 1 - mIndex;
+    mInfo.activate = FB_ACTIVATE_VBL;
+    mInfo.yoffset = mIndex ? mInfo.yres : 0;
+    if (ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo) == -1) {
+        LOGE("FBIOPUT_VSCREENINFO failed");
+        return 0;
+    }
+
+    /*
+     * this is a monstrous hack: Because the h/w accelerator is not able
+     * to render directly into the framebuffer, we need to copy its
+     * internal framebuffer out to the fb.
+     * oem[0] is used to access the fd of internal fb.
+     * All this is needed only in standalone mode, in SurfaceFlinger mode
+     * we control where the GPU renders.
+     * We do this only if we have copybit, since this hack is needed only
+     * with msm7k.
+     */
+    if (egl_native_window_t::memory_type == NATIVE_MEMORY_TYPE_GPU && oem[0] && mBlitEngine) {
+        copybit_t *copybit = mBlitEngine;
+        copybit_rect_t sdrect = { 0, 0,
+                egl_native_window_t::width, egl_native_window_t::height };
+        copybit_image_t dst = {
+                egl_native_window_t::width,
+                egl_native_window_t::height,
+                egl_native_window_t::format,
+                egl_native_window_t::offset,
+                (void*)egl_native_window_t::base,
+                egl_native_window_t::fd
+        };
+        copybit_image_t src = {
+                egl_native_window_t::width,
+                egl_native_window_t::height,
+                egl_native_window_t::format, // XXX: use proper format
+                egl_native_window_t::offset,
+                (void*)egl_native_window_t::base,  // XXX: use proper base
+                egl_native_window_t::oem[0]
+        };
+        region_iterator it(Region(Rect(
+                egl_native_window_t::width, egl_native_window_t::height)));
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
+        copybit->stretch(copybit, &dst, &src, &sdrect, &sdrect, &it);
+    }
+
+    // update the address of the buffer to draw to next
+    const GGLSurface& buffer = mFb[1 - mIndex];
+    egl_native_window_t::offset =
+        intptr_t(buffer.data) - egl_native_window_t::base;
+
+#if SHOW_FPS
+    mSleep += systemTime()-now;
+#endif
+
+    mPageFlipCount++;
+
+    // We don't support screen-size changes for now
+    return 0;
+}
+
+int32_t EGLDisplaySurface::getPageFlipCount() const
+{
+    return mPageFlipCount;
+}
+
+uint32_t EGLDisplaySurface::nextBuffer()
+{
+    // update the address of the buffer to draw to next
+    const GGLSurface& buffer = mFb[mIndex];
+    egl_native_window_t::offset =
+        intptr_t(buffer.data) - egl_native_window_t::base;
+    return 0;
+}
+
+void EGLDisplaySurface::copyFrontToBack(const Region& copyback)
+{
+#if HAVE_ANDROID_OS
+    if (mBlitEngine) {
+        copybit_image_t dst = {
+                w:      egl_native_window_t::stride,
+                h:      egl_native_window_t::height,
+                format: egl_native_window_t::format,
+                offset: mFb[1-mIndex].data - mFb[0].data,
+                base:   (void*)egl_native_window_t::base,
+                fd:     egl_native_window_t::fd
+        };
+        copybit_image_t src = {
+                w:      egl_native_window_t::stride,
+                h:      egl_native_window_t::height,
+                format: egl_native_window_t::format,
+                offset: mFb[mIndex].data - mFb[0].data,
+                base:   (void*)egl_native_window_t::base,
+                fd:     egl_native_window_t::fd
+        };
+        region_iterator it(copyback);
+        mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
+    } else
+#endif
+    {
+        Region::iterator iterator(copyback);
+        if (iterator) {
+            Rect r;
+            uint8_t* const screen_src = mFb[  mIndex].data;
+            uint8_t* const screen_dst = mFb[1-mIndex].data;
+            const size_t bpp = bytesPerPixel(egl_native_window_t::format);
+            const size_t bpr = egl_native_window_t::stride * bpp;
+            while (iterator.iterate(&r)) {
+                ssize_t h = r.bottom - r.top;
+                if (h) {
+                    size_t size = (r.right - r.left) * bpp;
+                    size_t o = (r.left + egl_native_window_t::stride * r.top) * bpp;
+                    uint8_t* s = screen_src + o;
+                    uint8_t* d = screen_dst + o;
+                    if (size == bpr) {
+                        size *= h;
+                        h = 1;
+                    }
+                    do {
+                        memcpy(d, s, size);
+                        d += bpr;
+                        s += bpr;
+                    } while (--h > 0);
+                }
+            }
+        }
+    }
+}
+
+status_t EGLDisplaySurface::mapFrameBuffer()
+{
+    char const * const device_template[] = {
+            "/dev/graphics/fb%u",
+            "/dev/fb%u",
+            0 };
+    int fd = -1;
+    int i=0;
+    char name[64];
+    while ((fd==-1) && device_template[i]) {
+        snprintf(name, 64, device_template[i], 0);
+        fd = open(name, O_RDWR, 0);
+        i++;
+    }
+    if (fd < 0)
+        return -errno;
+
+    struct fb_fix_screeninfo finfo;
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+        return -errno;
+
+    struct fb_var_screeninfo info;
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+        return -errno;
+
+    info.reserved[0] = 0;
+    info.reserved[1] = 0;
+    info.reserved[2] = 0;
+    info.xoffset = 0;
+    info.yoffset = 0;
+    info.yres_virtual = info.yres * 2;
+    info.bits_per_pixel = 16;
+    /* Explicitly request 5/6/5 */
+    info.red.offset = 11;
+    info.red.length = 5;
+    info.green.offset = 5;
+    info.green.length = 6;
+    info.blue.offset = 0;
+    info.blue.length = 5;
+    info.transp.offset = 0;
+    info.transp.length = 0;
+    info.activate = FB_ACTIVATE_NOW;
+
+    uint32_t flags = PAGE_FLIP;
+    if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
+        info.yres_virtual = info.yres;
+        flags &= ~PAGE_FLIP;
+        LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
+    }
+
+    if (info.yres_virtual < info.yres * 2) {
+        info.yres_virtual = info.yres;
+        flags &= ~PAGE_FLIP;
+        LOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
+                info.yres_virtual, info.yres*2);
+    }
+
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
+        return -errno;
+
+    int refreshRate = 1000000000000000LLU /
+    (
+            uint64_t( info.upper_margin + info.lower_margin + info.yres )
+            * ( info.left_margin  + info.right_margin + info.xres )
+            * info.pixclock
+    );
+
+    if (refreshRate == 0) {
+        // bleagh, bad info from the driver
+        refreshRate = 60*1000;  // 60 Hz
+    }
+
+    if (int(info.width) <= 0 || int(info.height) <= 0) {
+        // the driver doesn't return that information
+        // default to 160 dpi
+        info.width  = 51;
+        info.height = 38;
+    }
+
+    float xdpi = (info.xres * 25.4f) / info.width;
+    float ydpi = (info.yres * 25.4f) / info.height;
+    float fps  = refreshRate / 1000.0f;
+
+    LOGI(   "using (fd=%d)\n"
+            "id           = %s\n"
+            "xres         = %d px\n"
+            "yres         = %d px\n"
+            "xres_virtual = %d px\n"
+            "yres_virtual = %d px\n"
+            "bpp          = %d\n"
+            "r            = %2u:%u\n"
+            "g            = %2u:%u\n"
+            "b            = %2u:%u\n",
+            fd,
+            finfo.id,
+            info.xres,
+            info.yres,
+            info.xres_virtual,
+            info.yres_virtual,
+            info.bits_per_pixel,
+            info.red.offset, info.red.length,
+            info.green.offset, info.green.length,
+            info.blue.offset, info.blue.length
+    );
+
+    LOGI(   "width        = %d mm (%f dpi)\n"
+            "height       = %d mm (%f dpi)\n"
+            "refresh rate = %.2f Hz\n",
+            info.width,  xdpi,
+            info.height, ydpi,
+            fps
+    );
+
+
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
+        return -errno;
+
+    if (finfo.smem_len <= 0)
+        return -errno;
+
+    /*
+     * Open and map the display.
+     */
+
+    void* buffer  = (uint16_t*) mmap(
+            0, finfo.smem_len,
+            PROT_READ | PROT_WRITE,
+            MAP_SHARED,
+            fd, 0);
+
+    if (buffer == MAP_FAILED)
+        return -errno;
+
+    // at least for now, always clear the fb
+    memset(buffer, 0, finfo.smem_len);
+
+    uint8_t* offscreen[2];
+    offscreen[0] = (uint8_t*)buffer;
+    if (flags & PAGE_FLIP) {
+        offscreen[1] = (uint8_t*)buffer + finfo.line_length*info.yres;
+    } else {
+        offscreen[1] = (uint8_t*)malloc(finfo.smem_len);
+        if (offscreen[1] == 0) {
+            munmap(buffer, finfo.smem_len);
+            return NO_MEMORY;
+        }
+    }
+
+    mFlags = flags;
+    mInfo = info;
+    mFinfo = finfo;
+    mSize = finfo.smem_len;
+    mIndex = 0;
+    for (int i=0 ; i<2 ; i++) {
+        mFb[i].version = sizeof(GGLSurface);
+        mFb[i].width   = info.xres;
+        mFb[i].height  = info.yres;
+        mFb[i].stride  = finfo.line_length / (info.bits_per_pixel >> 3);
+        mFb[i].data    = (GGLubyte*)(offscreen[i]);
+        mFb[i].format  = GGL_PIXEL_FORMAT_RGB_565;
+    }
+    return fd;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/EGLNativeWindowSurface.cpp
new file mode 100644
index 0000000..0b6afc0
--- /dev/null
+++ b/libs/ui/EGLNativeWindowSurface.cpp
@@ -0,0 +1,181 @@
+/* 
+**
+** 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 "EGLNativeWindowSurface"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <ui/SurfaceComposerClient.h>
+#include <ui/DisplayInfo.h>
+#include <ui/Rect.h>
+
+#include <GLES/egl.h>
+
+#include <pixelflinger/format.h>
+
+#include <ui/EGLNativeWindowSurface.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+EGLNativeWindowSurface::EGLNativeWindowSurface(const sp<Surface>& surface)
+    : EGLNativeSurface<EGLNativeWindowSurface>(),
+    mSurface(surface), mConnected(false)
+{
+    egl_native_window_t::magic = 0x600913;
+    egl_native_window_t::version = sizeof(egl_native_window_t);
+    egl_native_window_t::ident = 0;
+    egl_native_window_t::incRef = &EGLNativeWindowSurface::hook_incRef;
+    egl_native_window_t::decRef = &EGLNativeWindowSurface::hook_decRef;
+    egl_native_window_t::swapBuffers = &EGLNativeWindowSurface::hook_swapBuffers;
+    egl_native_window_t::nextBuffer = &EGLNativeWindowSurface::hook_nextBuffer;
+    egl_native_window_t::setSwapRectangle = &EGLNativeWindowSurface::hook_setSwapRectangle;
+    egl_native_window_t::connect = &EGLNativeWindowSurface::hook_connect;
+    egl_native_window_t::disconnect = &EGLNativeWindowSurface::hook_disconnect;
+    
+    DisplayInfo dinfo;
+    SurfaceComposerClient::getDisplayInfo(0, &dinfo);
+    egl_native_window_t::xdpi = dinfo.xdpi;
+    egl_native_window_t::ydpi = dinfo.ydpi;
+    egl_native_window_t::fps  = dinfo.fps;
+    egl_native_window_t::flags= EGL_NATIVES_FLAG_DESTROY_BACKBUFFER;
+}
+
+EGLNativeWindowSurface::~EGLNativeWindowSurface()
+{
+    disconnect();
+    mSurface.clear();
+    magic = 0;
+}
+
+void EGLNativeWindowSurface::hook_incRef(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    that->incStrong(that);
+}
+
+void EGLNativeWindowSurface::hook_decRef(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    that->decStrong(that);
+}
+
+void EGLNativeWindowSurface::hook_connect(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    that->connect();
+}
+
+void EGLNativeWindowSurface::hook_disconnect(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    that->disconnect();
+}
+
+uint32_t EGLNativeWindowSurface::hook_swapBuffers(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    return that->swapBuffers();
+}
+
+uint32_t EGLNativeWindowSurface::hook_nextBuffer(NativeWindowType window)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    return that->nextBuffer();
+}
+
+void EGLNativeWindowSurface::hook_setSwapRectangle(NativeWindowType window, int l, int t, int w, int h)
+{
+    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
+    that->setSwapRectangle(l, t, w, h);
+}
+
+void EGLNativeWindowSurface::setSwapRectangle(int l, int t, int w, int h)
+{
+    mSurface->setSwapRectangle(Rect(l, t, l+w, t+h));
+}
+
+uint32_t EGLNativeWindowSurface::swapBuffers()
+{
+    const int w = egl_native_window_t::width;
+    const int h = egl_native_window_t::height;
+    const sp<Surface>& surface(mSurface);
+    Surface::SurfaceInfo info;
+    surface->unlockAndPost();
+    surface->lock(&info);
+    // update the address of the buffer to draw to next
+    egl_native_window_t::base   = intptr_t(info.base);
+    egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
+    
+    // update size if it changed
+    if (w != int(info.w) || h != int(info.h)) {
+        egl_native_window_t::width  = info.w;
+        egl_native_window_t::height = info.h;
+        egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
+        egl_native_window_t::format = info.format;
+        return EGL_NATIVES_FLAG_SIZE_CHANGED;
+    }
+    return 0;
+}
+
+uint32_t EGLNativeWindowSurface::nextBuffer()
+{
+    const sp<Surface>& surface(mSurface);
+    Surface::SurfaceInfo info;
+    surface->nextBuffer(&info);
+    // update the address of the buffer to draw to next
+    egl_native_window_t::base   = intptr_t(info.base);
+    egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
+    return 0;
+}
+
+void EGLNativeWindowSurface::connect()
+{   
+    if (!mConnected) {
+        Surface::SurfaceInfo info;
+        mSurface->lock(&info);
+        mSurface->setSwapRectangle(Rect(info.w, info.h));
+        mConnected = true;
+
+        egl_native_window_t::width  = info.w;
+        egl_native_window_t::height = info.h;
+        egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
+        egl_native_window_t::format = info.format;
+        egl_native_window_t::base   = intptr_t(info.base);
+        egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
+        egl_native_window_t::memory_type = mSurface->getMemoryType();
+        egl_native_window_t::fd = 0;
+    }
+}
+
+void EGLNativeWindowSurface::disconnect()
+{
+    if (mConnected) {
+        mSurface->unlock();
+        mConnected = false;
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
new file mode 100644
index 0000000..f0c77ba
--- /dev/null
+++ b/libs/ui/EventHub.cpp
@@ -0,0 +1,743 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+// Handle events, like key input and vsync.
+//
+// The goal is to provide an optimized solution for Linux, not an
+// implementation that works well across all platforms.  We expect
+// events to arrive on file descriptors, so that we can use a select()
+// select() call to sleep.
+//
+// We can't select() on anything but network sockets in Windows, so we
+// provide an alternative implementation of waitEvent for that platform.
+//
+#define LOG_TAG "EventHub"
+
+//#define LOG_NDEBUG 0
+
+#include <ui/EventHub.h>
+#include <hardware/power.h>
+
+#include <cutils/properties.h>
+#include <utils/IServiceManager.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <utils.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "KeyLayoutMap.h"
+
+#include <string.h>
+#include <stdint.h>
+#include <dirent.h>
+#ifdef HAVE_INOTIFY
+# include <sys/inotify.h>
+#endif
+#ifdef HAVE_ANDROID_OS
+# include <sys/limits.h>        /* not part of Linux */
+#endif
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+
+/* this macro is used to tell if "bit" is set in "array"
+ * it selects a byte from the array, and does a boolean AND
+ * operation with a byte that only has the relevant bit set.
+ * eg. to check for the 12th bit, we do (array[1] & 1<<4)
+ */
+#define test_bit(bit, array)    (array[bit/8] & (1<<(bit%8)))
+
+#define ID_MASK  0x0000ffff
+#define SEQ_MASK 0x7fff0000
+#define SEQ_SHIFT 16
+#define id_to_index(id)         ((id&ID_MASK)+1)
+
+namespace android {
+
+static const char *WAKE_LOCK_ID = "KeyEvents";
+static const char *device_path = "/dev/input";
+
+/* return the larger integer */
+static inline int max(int v1, int v2)
+{
+    return (v1 > v2) ? v1 : v2;
+}
+
+EventHub::device_t::device_t(int32_t _id, const char* _path)
+    : id(_id), path(_path), classes(0)
+    , layoutMap(new KeyLayoutMap()), next(NULL) {
+}
+
+EventHub::device_t::~device_t() {
+    delete layoutMap;
+}
+
+EventHub::EventHub(void)
+    : mError(NO_INIT), mHaveFirstKeyboard(false), mFirstKeyboardId(0)
+    , mDevicesById(0), mNumDevicesById(0)
+    , mOpeningDevices(0), mClosingDevices(0)
+    , mDevices(0), mFDs(0), mFDCount(0)
+{
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+#ifdef EV_SW
+    memset(mSwitches, 0, sizeof(mSwitches));
+#endif
+}
+
+/*
+ * Clean up.
+ */
+EventHub::~EventHub(void)
+{
+    release_wake_lock(WAKE_LOCK_ID);
+    // we should free stuff here...
+}
+
+void EventHub::onFirstRef()
+{
+    mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
+}
+
+status_t EventHub::errorCheck() const
+{
+    return mError;
+}
+
+String8 EventHub::getDeviceName(int32_t deviceId) const
+{
+    AutoMutex _l(mLock);
+    device_t* device = getDevice(deviceId);
+    if (device == NULL) return String8();
+    return device->name;
+}
+
+uint32_t EventHub::getDeviceClasses(int32_t deviceId) const
+{
+    AutoMutex _l(mLock);
+    device_t* device = getDevice(deviceId);
+    if (device == NULL) return 0;
+    return device->classes;
+}
+
+int EventHub::getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
+        int* outMaxValue, int* outFlat, int* outFuzz) const
+{
+    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;
+    }
+    *outMinValue = info.minimum;
+    *outMaxValue = info.maximum;
+    *outFlat = info.flat;
+    *outFuzz = info.fuzz;
+    return 0;
+}
+
+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);
+        }
+    }
+#endif
+    return -1;
+}
+
+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+1)/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+1)/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+1)/8];
+    memset(key_bitmask, 0, sizeof(key_bitmask));
+    if (ioctl(mFDs[id_to_index(device->id)].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));
+        }
+        #endif
+        const size_t N = scanCodes.size();
+        for (size_t i=0; i<N && i<=KEY_MAX; i++) {
+            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 0;
+}
+
+EventHub::device_t* EventHub::getDevice(int32_t deviceId) const
+{
+    if (deviceId == 0) deviceId = mFirstKeyboardId;
+    int32_t id = deviceId & ID_MASK;
+    if (id >= mNumDevicesById || id < 0) return NULL;
+    device_t* dev = mDevicesById[id].device;
+    if (dev->id == deviceId) {
+        return dev;
+    }
+    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)
+{
+    *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;
+
+    // Note that we only allow one caller to getEvent(), so don't need
+    // to do locking here...  only when adding/removing devices.
+    
+    while(1) {
+
+        // First, 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;
+            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;
+            return true;
+        }
+
+        release_wake_lock(WAKE_LOCK_ID);
+
+        pollres = poll(mFDs, mFDCount, -1);
+
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+
+        if (pollres <= 0) {
+            if (errno != EINTR) {
+                LOGW("select failed (errno=%d)\n", errno);
+                usleep(100000);
+            }
+            continue;
+        }
+
+        //printf("poll %d, returned %d\n", mFDCount, pollres);
+        if(mFDs[0].revents & POLLIN) {
+            read_notify(mFDs[0].fd);
+        }
+        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;
+                    }
+                }
+            }
+        }
+    }
+}
+
+/*
+ * Open the platform-specific input device.
+ */
+bool EventHub::openPlatformInput(void)
+{
+    /*
+     * Open platform-specific input device(s).
+     */
+    int res;
+
+    mFDCount = 1;
+    mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
+    mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
+    mFDs[0].events = POLLIN;
+    mDevices[0] = NULL;
+#ifdef HAVE_INOTIFY
+    mFDs[0].fd = inotify_init();
+    res = inotify_add_watch(mFDs[0].fd, device_path, IN_DELETE | IN_CREATE);
+    if(res < 0) {
+        LOGE("could not add watch for %s, %s\n", device_path, strerror(errno));
+    }
+#else
+    /*
+     * The code in EventHub::getEvent assumes that mFDs[0] is an inotify fd.
+     * We allocate space for it and set it to something invalid.
+     */
+    mFDs[0].fd = -1;
+#endif
+
+    res = scan_dir(device_path);
+    if(res < 0) {
+        LOGE("scan dir failed for %s\n", device_path);
+        //open_device("/dev/input/event0");
+    }
+
+    return true;
+}
+
+// ----------------------------------------------------------------------------
+
+int EventHub::open_device(const char *deviceName)
+{
+    int version;
+    int fd;
+    struct pollfd *new_mFDs;
+    device_t **new_devices;
+    char **new_device_names;
+    char name[80];
+    char location[80];
+    char idstr[80];
+    struct input_id id;
+
+    LOGV("Opening device: %s", deviceName);
+
+    AutoMutex _l(mLock);
+    
+    fd = open(deviceName, O_RDWR);
+    if(fd < 0) {
+        LOGE("could not open %s, %s\n", deviceName, strerror(errno));
+        return -1;
+    }
+
+    if(ioctl(fd, EVIOCGVERSION, &version)) {
+        LOGE("could not get driver version for %s, %s\n", deviceName, strerror(errno));
+        return -1;
+    }
+    if(ioctl(fd, EVIOCGID, &id)) {
+        LOGE("could not get driver id for %s, %s\n", deviceName, strerror(errno));
+        return -1;
+    }
+    name[sizeof(name) - 1] = '\0';
+    location[sizeof(location) - 1] = '\0';
+    idstr[sizeof(idstr) - 1] = '\0';
+    if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
+        //fprintf(stderr, "could not get device name for %s, %s\n", deviceName, strerror(errno));
+        name[0] = '\0';
+    }
+    if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) {
+        //fprintf(stderr, "could not get location for %s, %s\n", deviceName, strerror(errno));
+        location[0] = '\0';
+    }
+    if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) {
+        //fprintf(stderr, "could not get idstring for %s, %s\n", deviceName, strerror(errno));
+        idstr[0] = '\0';
+    }
+
+    int devid = 0;
+    while (devid < mNumDevicesById) {
+        if (mDevicesById[devid].device == NULL) {
+            break;
+        }
+        devid++;
+    }
+    if (devid >= mNumDevicesById) {
+        device_ent* new_devids = (device_ent*)realloc(mDevicesById,
+                sizeof(mDevicesById[0]) * (devid + 1));
+        if (new_devids == NULL) {
+            LOGE("out of memory");
+            return -1;
+        }
+        mDevicesById = new_devids;
+        mNumDevicesById = devid+1;
+        mDevicesById[devid].device = NULL;
+        mDevicesById[devid].seq = 0;
+    }
+
+    mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;
+    if (mDevicesById[devid].seq == 0) {
+        mDevicesById[devid].seq = 1<<SEQ_SHIFT;
+    }
+
+    new_mFDs = (pollfd*)realloc(mFDs, sizeof(mFDs[0]) * (mFDCount + 1));
+    new_devices = (device_t**)realloc(mDevices, sizeof(mDevices[0]) * (mFDCount + 1));
+    if (new_mFDs == NULL || new_devices == NULL) {
+        LOGE("out of memory");
+        return -1;
+    }
+    mFDs = new_mFDs;
+    mDevices = new_devices;
+
+#if 0
+    LOGI("add device %d: %s\n", mFDCount, deviceName);
+    LOGI("  bus:      %04x\n"
+         "  vendor    %04x\n"
+         "  product   %04x\n"
+         "  version   %04x\n",
+        id.bustype, id.vendor, id.product, id.version);
+    LOGI("  name:     \"%s\"\n", name);
+    LOGI("  location: \"%s\"\n"
+         "  id:       \"%s\"\n", location, idstr);
+    LOGI("  version:  %d.%d.%d\n",
+        version >> 16, (version >> 8) & 0xff, version & 0xff);
+#endif
+
+    device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName);
+    if (device == NULL) {
+        LOGE("out of memory");
+        return -1;
+    }
+
+    mFDs[mFDCount].fd = fd;
+    mFDs[mFDCount].events = POLLIN;
+
+    // figure out the kinds of events the device reports
+    uint8_t key_bitmask[(KEY_MAX+1)/8];
+    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+1)/8); 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 (test_bit(BTN_MOUSE, key_bitmask)) {
+        uint8_t rel_bitmask[(REL_MAX+1)/8];
+        memset(rel_bitmask, 0, sizeof(rel_bitmask));
+        LOGV("Getting relative controllers...");
+        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;
+            }
+        }
+    }
+    if (test_bit(BTN_TOUCH, key_bitmask)) {
+        uint8_t abs_bitmask[(ABS_MAX+1)/8];
+        memset(abs_bitmask, 0, sizeof(abs_bitmask));
+        LOGV("Getting absolute controllers...");
+        if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0)
+        {
+            if (test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
+                device->classes |= CLASS_TOUCHSCREEN;
+            }
+        }
+    }
+
+#ifdef EV_SW
+    // figure out the switches this device reports
+    uint8_t sw_bitmask[(SW_MAX+1)/8];
+    memset(sw_bitmask, 0, sizeof(sw_bitmask));
+    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)) {
+                if (mSwitches[i] == 0) {
+                    mSwitches[i] = device->id;
+                }
+            }
+        }
+    }
+#endif
+
+    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);
+
+    if ((device->classes&CLASS_KEYBOARD) != 0) {
+        char devname[101];
+        char tmpfn[101];
+        char keylayoutFilename[300];
+
+        // a more descriptive name
+        ioctl(mFDs[mFDCount].fd, EVIOCGNAME(sizeof(devname)-1), devname);
+        devname[sizeof(devname)-1] = 0;
+        device->name = devname;
+
+        // replace all the spaces with underscores
+        strcpy(tmpfn, devname);
+        for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
+            *p = '_';
+
+        // find the .kl file we need for this device
+        const char* root = getenv("ANDROID_ROOT");
+        snprintf(keylayoutFilename, sizeof(keylayoutFilename),
+                 "%s/usr/keylayout/%s.kl", root, tmpfn);
+        bool defaultKeymap = false;
+        if (access(keylayoutFilename, R_OK)) {
+            snprintf(keylayoutFilename, sizeof(keylayoutFilename),
+                     "%s/usr/keylayout/%s", root, "qwerty.kl");
+            defaultKeymap = true;
+        }
+        device->layoutMap->load(keylayoutFilename);
+
+        // tell the world about the devname (the descriptive name)
+        int32_t publicID;
+        if (!mHaveFirstKeyboard && !defaultKeymap) {
+            publicID = 0;
+            // the built-in keyboard has a well-known device ID of 0,
+            // this device better not go away.
+            mHaveFirstKeyboard = true;
+            mFirstKeyboardId = device->id;
+        } else {
+            publicID = device->id;
+            // ensure mFirstKeyboardId is set to -something-.
+            if (mFirstKeyboardId == 0) {
+                mFirstKeyboardId = device->id;
+            }
+        }
+        char propName[100];
+        sprintf(propName, "hw.keyboards.%u.devname", publicID);
+        property_set(propName, devname);
+
+        LOGI("New keyboard: publicID=%d device->id=%d devname='%s propName='%s' keylayout='%s'\n",
+                publicID, device->id, devname, propName, keylayoutFilename);
+    }
+
+    LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n",
+         deviceName, device, mFDCount, devid, device->classes);
+
+    mDevicesById[devid].device = device;
+    device->next = mOpeningDevices;
+    mOpeningDevices = device;
+    mDevices[mFDCount] = device;
+
+    mFDCount++;
+    return 0;
+}
+
+int EventHub::close_device(const char *deviceName)
+{
+    AutoMutex _l(mLock);
+    
+    int i;
+    for(i = 1; i < mFDCount; i++) {
+        if(strcmp(mDevices[i]->path.string(), deviceName) == 0) {
+            //LOGD("remove device %d: %s\n", i, deviceName);
+            device_t* device = mDevices[i];
+            int count = mFDCount - i - 1;
+            int index = (device->id&ID_MASK);
+            mDevicesById[index].device = NULL;
+            memmove(mDevices + i, mDevices + i + 1, sizeof(mDevices[0]) * count);
+            memmove(mFDs + i, mFDs + i + 1, sizeof(mFDs[0]) * count);
+
+#ifdef EV_SW
+            for (int j=0; j<EV_SW; j++) {
+                if (mSwitches[j] == device->id) {
+                    mSwitches[j] = 0;
+                }
+            }
+#endif
+            
+            device->next = mClosingDevices;
+            mClosingDevices = device;
+
+            mFDCount--;
+
+            uint32_t publicID;
+            if (device->id == mFirstKeyboardId) {
+                LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
+                        device->path.string(), mFirstKeyboardId);
+                mFirstKeyboardId = 0;
+                publicID = 0;
+            } else {
+                publicID = device->id;
+            }
+            // clear the property
+            char propName[100];
+            sprintf(propName, "hw.keyboards.%u.devname", publicID);
+            property_set(propName, NULL);
+            return 0;
+        }
+    }
+    LOGE("remote device: %s not found\n", deviceName);
+    return -1;
+}
+
+int EventHub::read_notify(int nfd)
+{
+#ifdef HAVE_INOTIFY
+    int res;
+    char devname[PATH_MAX];
+    char *filename;
+    char event_buf[512];
+    int event_size;
+    int event_pos = 0;
+    struct inotify_event *event;
+
+    res = read(nfd, event_buf, sizeof(event_buf));
+    if(res < (int)sizeof(*event)) {
+        if(errno == EINTR)
+            return 0;
+        LOGW("could not get event, %s\n", strerror(errno));
+        return 1;
+    }
+    //printf("got %d bytes of event information\n", res);
+
+    strcpy(devname, device_path);
+    filename = devname + strlen(devname);
+    *filename++ = '/';
+
+    while(res >= (int)sizeof(*event)) {
+        event = (struct inotify_event *)(event_buf + event_pos);
+        //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
+        if(event->len) {
+            strcpy(filename, event->name);
+            if(event->mask & IN_CREATE) {
+                open_device(devname);
+            }
+            else {
+                close_device(devname);
+            }
+        }
+        event_size = sizeof(*event) + event->len;
+        res -= event_size;
+        event_pos += event_size;
+    }
+#endif
+    return 0;
+}
+
+
+int EventHub::scan_dir(const char *dirname)
+{
+    char devname[PATH_MAX];
+    char *filename;
+    DIR *dir;
+    struct dirent *de;
+    dir = opendir(dirname);
+    if(dir == NULL)
+        return -1;
+    strcpy(devname, dirname);
+    filename = devname + strlen(devname);
+    *filename++ = '/';
+    while((de = readdir(dir))) {
+        if(de->d_name[0] == '.' &&
+           (de->d_name[1] == '\0' ||
+            (de->d_name[1] == '.' && de->d_name[2] == '\0')))
+            continue;
+        strcpy(filename, de->d_name);
+        open_device(devname);
+    }
+    closedir(dir);
+    return 0;
+}
+
+}; // namespace android
diff --git a/libs/ui/EventRecurrence.cpp b/libs/ui/EventRecurrence.cpp
new file mode 100644
index 0000000..b436b50
--- /dev/null
+++ b/libs/ui/EventRecurrence.cpp
@@ -0,0 +1,484 @@
+/*
+ *  Copyright 2006 The Android Open Source Project
+ */
+
+#include <pim/EventRecurrence.h>
+#include <utils/String8.h>
+#include <stdio.h>
+#include <limits.h>
+
+namespace android {
+
+#define FAIL_HERE() do { \
+            printf("Parsing failed at line %d\n", __LINE__); \
+            return UNKNOWN_ERROR; \
+        } while(0)
+
+EventRecurrence::EventRecurrence()
+    :freq((freq_t)0),
+     until(),
+     count(0),
+     interval(0),
+     bysecond(0),
+     bysecondCount(0),
+     byminute(0),
+     byminuteCount(0),
+     byhour(0),
+     byhourCount(0),
+     byday(0),
+     bydayNum(0),
+     bydayCount(0),
+     bymonthday(0),
+     bymonthdayCount(0),
+     byyearday(0),
+     byyeardayCount(0),
+     byweekno(0),
+     byweeknoCount(0),
+     bymonth(0),
+     bymonthCount(0),
+     bysetpos(0),
+     bysetposCount(0),
+     wkst(0)
+{
+}
+
+EventRecurrence::~EventRecurrence()
+{
+    delete[] bysecond;
+    delete[] byminute;
+    delete[] byhour;
+    delete[] byday;
+    delete[] bydayNum;
+    delete[] byyearday;
+    delete[] bymonthday;
+    delete[] byweekno;
+    delete[] bymonth;
+    delete[] bysetpos;
+}
+
+enum LHS {
+    NONE_LHS = 0,
+    FREQ,
+    UNTIL,
+    COUNT,
+    INTERVAL,
+    BYSECOND,
+    BYMINUTE,
+    BYHOUR,
+    BYDAY,
+    BYMONTHDAY,
+    BYYEARDAY,
+    BYWEEKNO,
+    BYMONTH,
+    BYSETPOS,
+    WKST
+};
+
+struct LHSProc
+{
+    const char16_t* text;
+    size_t textSize;
+    uint32_t value;
+};
+
+const char16_t FREQ_text[] = { 'F', 'R', 'E', 'Q' };
+const char16_t UNTIL_text[] = { 'U', 'N', 'T', 'I', 'L' };
+const char16_t COUNT_text[] = { 'C', 'O', 'U', 'N', 'T' };
+const char16_t INTERVAL_text[] = { 'I', 'N', 'T', 'E', 'R', 'V', 'A', 'L'};
+const char16_t BYSECOND_text[] = { 'B', 'Y', 'S', 'E', 'C', 'O', 'N', 'D' };
+const char16_t BYMINUTE_text[] = { 'B', 'Y', 'M', 'I', 'N', 'U', 'T', 'E' };
+const char16_t BYHOUR_text[] = { 'B', 'Y', 'H', 'O', 'U', 'R' };
+const char16_t BYDAY_text[] = { 'B', 'Y', 'D', 'A', 'Y' };
+const char16_t BYMONTHDAY_text[] = { 'B','Y','M','O','N','T','H','D','A','Y' };
+const char16_t BYYEARDAY_text[] = { 'B','Y','Y','E','A','R','D','A','Y' };
+const char16_t BYWEEKNO_text[] = { 'B', 'Y', 'W', 'E', 'E', 'K', 'N', 'O' };
+const char16_t BYMONTH_text[] = { 'B', 'Y', 'M', 'O', 'N', 'T', 'H' };
+const char16_t BYSETPOS_text[] = { 'B', 'Y', 'S', 'E', 'T', 'P', 'O', 'S' };
+const char16_t WKST_text[] = { 'W', 'K', 'S', 'T' };
+
+#define SIZ(x) (sizeof(x)/sizeof(x[0]))
+
+const LHSProc LHSPROC[] = {
+    { FREQ_text, SIZ(FREQ_text), FREQ },
+    { UNTIL_text, SIZ(UNTIL_text), UNTIL },
+    { COUNT_text, SIZ(COUNT_text), COUNT },
+    { INTERVAL_text, SIZ(INTERVAL_text), INTERVAL },
+    { BYSECOND_text, SIZ(BYSECOND_text), BYSECOND },
+    { BYMINUTE_text, SIZ(BYMINUTE_text), BYMINUTE },
+    { BYHOUR_text, SIZ(BYHOUR_text), BYHOUR },
+    { BYDAY_text, SIZ(BYDAY_text), BYDAY },
+    { BYMONTHDAY_text, SIZ(BYMONTHDAY_text), BYMONTHDAY },
+    { BYYEARDAY_text, SIZ(BYYEARDAY_text), BYYEARDAY },
+    { BYWEEKNO_text, SIZ(BYWEEKNO_text), BYWEEKNO },
+    { BYMONTH_text, SIZ(BYMONTH_text), BYMONTH },
+    { BYSETPOS_text, SIZ(BYSETPOS_text), BYSETPOS },
+    { WKST_text, SIZ(WKST_text), WKST },
+    { NULL, 0, NONE_LHS },
+};
+
+const char16_t SECONDLY_text[] = { 'S','E','C','O','N','D','L','Y' };
+const char16_t MINUTELY_text[] = { 'M','I','N','U','T','E','L','Y' };
+const char16_t HOURLY_text[] = { 'H','O','U','R','L','Y' };
+const char16_t DAILY_text[] = { 'D','A','I','L','Y' };
+const char16_t WEEKLY_text[] = { 'W','E','E','K','L','Y' };
+const char16_t MONTHLY_text[] = { 'M','O','N','T','H','L','Y' };
+const char16_t YEARLY_text[] = { 'Y','E','A','R','L','Y' };
+
+typedef LHSProc FreqProc;
+
+const FreqProc FREQPROC[] = {
+    { SECONDLY_text, SIZ(SECONDLY_text), EventRecurrence::SECONDLY },
+    { MINUTELY_text, SIZ(MINUTELY_text), EventRecurrence::MINUTELY },
+    { HOURLY_text, SIZ(HOURLY_text), EventRecurrence::HOURLY },
+    { DAILY_text, SIZ(DAILY_text), EventRecurrence::DAILY },
+    { WEEKLY_text, SIZ(WEEKLY_text), EventRecurrence::WEEKLY },
+    { MONTHLY_text, SIZ(MONTHLY_text), EventRecurrence::MONTHLY },
+    { YEARLY_text, SIZ(YEARLY_text), EventRecurrence::YEARLY },
+    { NULL, 0, NONE_LHS },
+};
+
+const char16_t SU_text[] = { 'S','U' };
+const char16_t MO_text[] = { 'M','O' };
+const char16_t TU_text[] = { 'T','U' };
+const char16_t WE_text[] = { 'W','E' };
+const char16_t TH_text[] = { 'T','H' };
+const char16_t FR_text[] = { 'F','R' };
+const char16_t SA_text[] = { 'S','A' };
+
+const FreqProc WEEKDAYPROC[] = {
+    { SU_text, SIZ(SU_text), EventRecurrence::SU },
+    { MO_text, SIZ(MO_text), EventRecurrence::MO },
+    { TU_text, SIZ(TU_text), EventRecurrence::TU },
+    { WE_text, SIZ(WE_text), EventRecurrence::WE },
+    { TH_text, SIZ(TH_text), EventRecurrence::TH },
+    { FR_text, SIZ(FR_text), EventRecurrence::FR },
+    { SA_text, SIZ(SA_text), EventRecurrence::SA },
+    { NULL, 0, NONE_LHS },
+};
+
+// returns the index into LHSPROC for the match or -1 if not found
+inline static int
+match_proc(const LHSProc* p, const char16_t* str, size_t len)
+{
+    int i = 0;
+    while (p->text != NULL) {
+        if (p->textSize == len) {
+            if (0 == memcmp(p->text, str, len*sizeof(char16_t))) {
+                return i;
+            }
+        }
+        p++;
+        i++;
+    }
+    return -1;
+}
+
+// rangeMin and rangeMax are inclusive
+static status_t
+parse_int(const char16_t* str, size_t len, int* out,
+            int rangeMin, int rangeMax, bool zeroOK)
+{
+    char16_t c;
+    size_t i=0;
+
+    if (len == 0) {
+        FAIL_HERE();
+    }
+    bool negative = false;
+    c = str[0];
+    if (c == '-' ) {
+        negative = true;
+        i++;
+    }
+    else if (c == '+') {
+        i++;
+    }
+    int n = 0;
+    for (; i<len; i++) {
+        c = str[i];
+        if (c < '0' || c > '9') {
+            FAIL_HERE();
+        }
+        int prev = n;
+        n *= 10;
+        // the spec doesn't address how big these numbers can be,
+        // so we're not going to worry about not being able to represent
+        // INT_MIN, and if we're going to wrap, we'll just clamp to
+        // INT_MAX instead
+        if (n < prev) {
+            n = INT_MAX;
+        } else {
+            n += c - '0';
+        }
+    }
+    if (negative) {
+        n = -n;
+    }
+    if (n < rangeMin || n > rangeMax) {
+        FAIL_HERE();
+    }
+    if (!zeroOK && n == 0) {
+        FAIL_HERE();
+    }
+    *out = n;
+    return NO_ERROR;
+}
+
+static status_t
+parse_int_list(const char16_t* str, size_t len, int* countOut, int** listOut,
+          int rangeMin, int rangeMax, bool zeroOK,
+          status_t (*func)(const char16_t*,size_t,int*,int,int,bool)=parse_int)
+{
+    status_t err;
+
+    if (len == 0) {
+        *countOut = 0;
+        *listOut = NULL;
+        return NO_ERROR;
+    }
+
+    // make one pass through looking for commas so we know how big to make our
+    // out array.
+    int count = 1;
+    for (size_t i=0; i<len; i++) {
+        if (str[i] == ',') {
+            count++;
+        }
+    }
+
+    int* list = new int[count];
+    const char16_t* p = str;
+    int commaIndex = 0;
+    size_t i;
+
+    for (i=0; i<len; i++) {
+        if (str[i] == ',') {
+            err = func(p, (str+i-p), list+commaIndex, rangeMin,
+                    rangeMax, zeroOK);
+            if (err != NO_ERROR) {
+                goto bail;
+            }
+            commaIndex++;
+            p = str+i+1;
+        }
+    }
+
+    err = func(p, (str+i-p), list+commaIndex, rangeMin, rangeMax, zeroOK);
+    if (err != NO_ERROR) {
+        goto bail;
+    }
+    commaIndex++;
+
+    *countOut = count;
+    *listOut = list;
+
+    return NO_ERROR;
+
+bail:
+    delete[] list;
+    FAIL_HERE();
+}
+
+// the numbers here are small, so we pack them both into one value, and then
+// split it out later.  it lets us reuse all the comma separated list code.
+static status_t
+parse_byday(const char16_t* s, size_t len, int* out,
+            int rangeMin, int rangeMax, bool zeroOK)
+{
+    status_t err;
+    int n = 0;
+    const char16_t* p = s;
+    size_t plen = len;
+
+    if (len > 0) {
+        char16_t c = s[0];
+        if (c == '-' || c == '+' || (c >= '0' && c <= '9')) {
+            if (len > 1) {
+                size_t nlen = 0;
+                c = s[nlen];
+                while (nlen < len
+                        && (c == '-' || c == '+' || (c >= '0' && c <= '9'))) {
+                    c = s[nlen];
+                    nlen++;
+                }
+                if (nlen > 0) {
+                    nlen--;
+                    err = parse_int(s, nlen, &n, rangeMin, rangeMax, zeroOK);
+                    if (err != NO_ERROR) {
+                        FAIL_HERE();
+                    }
+                    p += nlen;
+                    plen -= nlen;
+                }
+            }
+        }
+
+        int index = match_proc(WEEKDAYPROC, p, plen);
+        if (index >= 0) {
+            *out = (0xffff0000 & WEEKDAYPROC[index].value)
+                    | (0x0000ffff & n);
+            return NO_ERROR;
+        }
+    }
+    return UNKNOWN_ERROR;
+}
+
+static void
+postprocess_byday(int count, int* byday, int** bydayNum)
+{
+    int* bdn = new int[count];
+    *bydayNum = bdn;
+    for (int i=0; i<count; i++) {
+        uint32_t v = byday[i];
+        int16_t num = v & 0x0000ffff;
+        byday[i] = v & 0xffff0000;  
+        // will sign extend:
+        bdn[i] = num;
+    }
+}
+
+#define PARSE_INT_LIST_CHECKED(name, rangeMin, rangeMax, zeroOK) \
+    if (name##Count != 0 || NO_ERROR != parse_int_list(s, slen, \
+                         &name##Count, &name, rangeMin, rangeMax, zeroOK)) { \
+        FAIL_HERE(); \
+    }
+status_t
+EventRecurrence::parse(const String16& str)
+{
+    char16_t const* work = str.string();
+    size_t len = str.size();
+
+    int lhsIndex = NONE_LHS;
+    int index;
+    
+    size_t start = 0;
+    for (size_t i=0; i<len; i++) {
+        char16_t c = work[i];
+        if (c != ';' && i == len-1) {
+            c = ';';
+            i++;
+        }
+        if (c == ';' || c == '=') {
+            if (i != start) {
+                const char16_t* s = work+start;
+                const size_t slen = i-start;
+
+                String8 thestring(String16(s, slen));
+
+                switch (c)
+                {
+                    case '=':
+                        if (lhsIndex == NONE_LHS) {
+                            lhsIndex = match_proc(LHSPROC, s, slen);
+                            if (lhsIndex >= 0) {
+                                break;
+                            }
+                        }
+                        FAIL_HERE();
+                    case ';':
+                    {
+                        switch (LHSPROC[lhsIndex].value)
+                        {
+                            case FREQ:
+                                if (this->freq != 0) {
+                                    FAIL_HERE();
+                                }
+                                index = match_proc(FREQPROC, s, slen);
+                                if (index >= 0) {
+                                    this->freq = (freq_t)FREQPROC[index].value;
+                                }
+                                break;
+                            case UNTIL:
+                                // XXX should check that this is a valid time
+                                until.setTo(String16(s, slen));
+                                break;
+                            case COUNT:
+                                if (count != 0
+                                     || NO_ERROR != parse_int(s, slen,
+                                             &count, INT_MIN, INT_MAX, true)) {
+                                    FAIL_HERE();
+                                }
+                                break;
+                            case INTERVAL:
+                                if (interval != 0
+                                     || NO_ERROR != parse_int(s, slen,
+                                         &interval, INT_MIN, INT_MAX, false)) {
+                                    FAIL_HERE();
+                                }
+                                break;
+                            case BYSECOND:
+                                PARSE_INT_LIST_CHECKED(bysecond, 0, 59, true)
+                                break;
+                            case BYMINUTE:
+                                PARSE_INT_LIST_CHECKED(byminute, 0, 59, true)
+                                break;
+                            case BYHOUR:
+                                PARSE_INT_LIST_CHECKED(byhour, 0, 23, true)
+                                break;
+                            case BYDAY:
+                                if (bydayCount != 0 || NO_ERROR != 
+                                        parse_int_list(s, slen, &bydayCount,
+                                              &byday, -53, 53, false,
+                                              parse_byday)) {
+                                    FAIL_HERE();
+                                }
+                                postprocess_byday(bydayCount, byday, &bydayNum);
+                                break;
+                            case BYMONTHDAY:
+                                PARSE_INT_LIST_CHECKED(bymonthday, -31, 31,
+                                                        false)
+                                break;
+                            case BYYEARDAY:
+                                PARSE_INT_LIST_CHECKED(byyearday, -366, 366,
+                                                        false)
+                                break;
+                            case BYWEEKNO:
+                                PARSE_INT_LIST_CHECKED(byweekno, -53, 53,
+                                                        false)
+                                break;
+                            case BYMONTH:
+                                PARSE_INT_LIST_CHECKED(bymonth, 1, 12, false)
+                                break;
+                            case BYSETPOS:
+                                PARSE_INT_LIST_CHECKED(bysetpos,
+                                                        INT_MIN, INT_MAX, true)
+                                break;
+                            case WKST:
+                                if (this->wkst != 0) {
+                                    FAIL_HERE();
+                                }
+                                index = match_proc(WEEKDAYPROC, s, slen);
+                                if (index >= 0) {
+                                    this->wkst = (int)WEEKDAYPROC[index].value;
+                                }
+                                break;
+                            default:
+                                FAIL_HERE();
+                        }
+                        lhsIndex = NONE_LHS;
+                        break;
+                    }
+                }
+
+                start = i+1;
+            }
+        }
+    }
+
+    // enforce that there was a FREQ
+    if (freq == 0) {
+        FAIL_HERE();
+    }
+
+    // default wkst to MO if it wasn't specified
+    if (wkst == 0) {
+        wkst = MO;
+    }
+
+    return NO_ERROR;
+}
+
+
+}; // namespace android
+
+
diff --git a/libs/ui/ICamera.cpp b/libs/ui/ICamera.cpp
new file mode 100644
index 0000000..420bb49
--- /dev/null
+++ b/libs/ui/ICamera.cpp
@@ -0,0 +1,204 @@
+/*
+**
+** 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.
+*/
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+
+#include <ui/ICamera.h>
+
+#define LOG_TAG "@@@@@@@@@@@ CAMERA @@@@@@@@@@@"
+#include <utils/Log.h>
+
+namespace android {
+
+enum {
+    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
+    SET_PREVIEW_DISPLAY,
+    SET_HAS_FRAME_CALLBACK,
+    START_PREVIEW,
+    STOP_PREVIEW,
+    AUTO_FOCUS,
+    TAKE_PICTURE,
+    SET_PARAMETERS,
+    GET_PARAMETERS
+};
+
+class BpCamera: public BpInterface<ICamera>
+{
+public:
+    BpCamera(const sp<IBinder>& impl)
+        : BpInterface<ICamera>(impl)
+    {
+    }
+
+    // disconnect from camera service
+    void disconnect()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(DISCONNECT, data, &reply);
+    }
+
+    // pass the buffered ISurface to the camera service
+    status_t setPreviewDisplay(const sp<ISurface>& surface)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        data.writeStrongBinder(surface->asBinder());
+        remote()->transact(SET_PREVIEW_DISPLAY, data, &reply);
+        return reply.readInt32();
+    }
+    
+    // tell the service whether to callback with each preview frame
+    void setHasFrameCallback(bool installed)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        data.writeInt32((int32_t)installed);
+        remote()->transact(SET_HAS_FRAME_CALLBACK, data, &reply);
+    }
+
+    // start preview mode, must call setPreviewDisplay first
+    status_t startPreview()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(START_PREVIEW, data, &reply);
+        return reply.readInt32();
+    }
+
+    // stop preview mode
+    void stopPreview()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(STOP_PREVIEW, data, &reply);
+    }
+
+    // auto focus
+    status_t autoFocus()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(AUTO_FOCUS, data, &reply);
+        status_t ret = reply.readInt32();
+        return ret;
+    }
+
+    // take a picture - returns an IMemory (ref-counted mmap)
+    status_t takePicture()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(TAKE_PICTURE, data, &reply);
+        status_t ret = reply.readInt32();
+        return ret;
+    }
+
+    // set preview/capture parameters - key/value pairs
+    status_t setParameters(const String8& params)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        data.writeString8(params);
+        remote()->transact(SET_PARAMETERS, data, &reply);
+        return reply.readInt32();
+    }
+
+    // get preview/capture parameters - key/value pairs
+    String8 getParameters() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(GET_PARAMETERS, data, &reply);
+        return reply.readString8();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnCamera::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case DISCONNECT: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            disconnect();
+            return NO_ERROR;
+        } break;
+        case SET_PREVIEW_DISPLAY: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
+            reply->writeInt32(setPreviewDisplay(surface));
+            return NO_ERROR;
+        } break;
+        case SET_HAS_FRAME_CALLBACK: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            bool installed = (bool)data.readInt32();
+            setHasFrameCallback(installed);
+            return NO_ERROR;
+        } break;
+        case START_PREVIEW: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(startPreview());
+            return NO_ERROR;
+        } break;
+        case STOP_PREVIEW: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            stopPreview();
+            return NO_ERROR;
+        } break;
+        case AUTO_FOCUS: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(autoFocus());
+            return NO_ERROR;
+        } break;
+        case TAKE_PICTURE: {
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(takePicture());
+            return NO_ERROR;
+        } break;
+        case SET_PARAMETERS: {
+            CHECK_INTERFACE(ICamera, data, reply);
+             String8 params(data.readString8());
+             reply->writeInt32(setParameters(params));
+            return NO_ERROR;
+         } break;
+        case GET_PARAMETERS: {
+            CHECK_INTERFACE(ICamera, data, reply);
+             reply->writeString8(getParameters());
+            return NO_ERROR;
+         } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp
new file mode 100644
index 0000000..3737034
--- /dev/null
+++ b/libs/ui/ICameraClient.cpp
@@ -0,0 +1,153 @@
+/*
+**
+** 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.
+*/
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/ICameraClient.h>
+
+namespace android {
+
+enum {
+    SHUTTER_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
+    RAW_CALLBACK,
+    JPEG_CALLBACK,
+    FRAME_CALLBACK,
+    ERROR_CALLBACK,
+    AUTOFOCUS_CALLBACK
+};
+
+class BpCameraClient: public BpInterface<ICameraClient>
+{
+public:
+    BpCameraClient(const sp<IBinder>& impl)
+        : BpInterface<ICameraClient>(impl)
+    {
+    }
+
+    // callback to let the app know the shutter has closed, ideal for playing the shutter sound
+    void shutterCallback()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        remote()->transact(SHUTTER_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app with picture data
+    void rawCallback(const sp<IMemory>& picture)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeStrongBinder(picture->asBinder());
+        remote()->transact(RAW_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app with picture data
+    void jpegCallback(const sp<IMemory>& picture)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeStrongBinder(picture->asBinder());
+        remote()->transact(JPEG_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app with video frame data
+    void frameCallback(const sp<IMemory>& frame)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeStrongBinder(frame->asBinder());
+        remote()->transact(FRAME_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app to report error
+    void errorCallback(status_t error)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeInt32(error);
+        remote()->transact(ERROR_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app to report autofocus completion
+    void autoFocusCallback(bool focused)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeInt32(focused);
+        remote()->transact(AUTOFOCUS_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnCameraClient::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case SHUTTER_CALLBACK: {
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            shutterCallback();
+            return NO_ERROR;
+        } break;
+        case RAW_CALLBACK: {
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            sp<IMemory> picture = interface_cast<IMemory>(data.readStrongBinder());
+            rawCallback(picture);
+            return NO_ERROR;
+        } break;
+        case JPEG_CALLBACK: {
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            sp<IMemory> picture = interface_cast<IMemory>(data.readStrongBinder());
+            jpegCallback(picture);
+            return NO_ERROR;
+        } break;
+        case FRAME_CALLBACK: {
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
+            frameCallback(frame);
+            return NO_ERROR;
+        } break;
+        case ERROR_CALLBACK: {
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            status_t error = data.readInt32();
+            errorCallback(error);
+            return NO_ERROR;
+        } break;
+        case AUTOFOCUS_CALLBACK: {
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            bool focused = (bool)data.readInt32();
+            autoFocusCallback(focused);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/libs/ui/ICameraService.cpp b/libs/ui/ICameraService.cpp
new file mode 100644
index 0000000..e5687fe
--- /dev/null
+++ b/libs/ui/ICameraService.cpp
@@ -0,0 +1,77 @@
+/*
+**
+** 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.
+*/
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+
+#include <ui/ICameraService.h>
+
+namespace android {
+
+class BpCameraService: public BpInterface<ICameraService>
+{
+public:
+    BpCameraService(const sp<IBinder>& impl)
+        : BpInterface<ICameraService>(impl)
+    {
+    }
+
+    // connect to camera service
+    virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
+        data.writeStrongBinder(cameraClient->asBinder());
+        remote()->transact(BnCameraService::CONNECT, data, &reply);
+        return interface_cast<ICamera>(reply.readStrongBinder());
+    }
+};
+
+IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnCameraService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case CONNECT: {
+            CHECK_INTERFACE(ICameraService, data, reply);
+            sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
+            sp<ICamera> camera = connect(cameraClient);
+            reply->writeStrongBinder(camera->asBinder());
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp
new file mode 100644
index 0000000..817f4d9
--- /dev/null
+++ b/libs/ui/ISurface.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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 <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+#include <utils/IMemory.h>
+
+#include <ui/ISurface.h>
+
+
+namespace android {
+
+enum {
+    REGISTER_BUFFERS = IBinder::FIRST_CALL_TRANSACTION,
+    UNREGISTER_BUFFERS,
+    POST_BUFFER, // one-way transaction
+};
+
+class BpSurface : public BpInterface<ISurface>
+{
+public:
+    BpSurface(const sp<IBinder>& impl)
+        : BpInterface<ISurface>(impl)
+    {
+    }
+
+    virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
+            PixelFormat format, const sp<IMemoryHeap>& heap)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        data.writeInt32(w);
+        data.writeInt32(h);
+        data.writeInt32(hstride);
+        data.writeInt32(vstride);
+        data.writeInt32(format);
+        data.writeStrongBinder(heap->asBinder());
+        remote()->transact(REGISTER_BUFFERS, data, &reply);
+        status_t result = reply.readInt32();
+        return result;
+    }
+
+    virtual void postBuffer(ssize_t offset)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        data.writeInt32(offset);
+        remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    virtual void unregisterBuffers()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        remote()->transact(UNREGISTER_BUFFERS, data, &reply);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnSurface::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case REGISTER_BUFFERS: {
+            CHECK_INTERFACE(ISurface, data, reply);
+            int w = data.readInt32();
+            int h = data.readInt32();
+            int hs= data.readInt32();
+            int vs= data.readInt32();
+            PixelFormat f = data.readInt32();
+            sp<IMemoryHeap> heap(interface_cast<IMemoryHeap>(data.readStrongBinder()));
+            status_t err = registerBuffers(w,h,hs,vs,f,heap);
+            reply->writeInt32(err);
+            return NO_ERROR;
+        } break;
+        case UNREGISTER_BUFFERS: {
+            CHECK_INTERFACE(ISurface, data, reply);
+            unregisterBuffers();
+            return NO_ERROR;
+        } break;
+        case POST_BUFFER: {
+            CHECK_INTERFACE(ISurface, data, reply);
+            ssize_t offset = data.readInt32();
+            postBuffer(offset);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
diff --git a/libs/ui/ISurfaceComposer.cpp b/libs/ui/ISurfaceComposer.cpp
new file mode 100644
index 0000000..0fea6f9
--- /dev/null
+++ b/libs/ui/ISurfaceComposer.cpp
@@ -0,0 +1,277 @@
+/*
+ * 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 <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+#include <utils/IMemory.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+
+#include <ui/ISurfaceComposer.h>
+#include <ui/DisplayInfo.h>
+
+// ---------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
+{
+public:
+    BpSurfaceComposer(const sp<IBinder>& impl)
+        : BpInterface<ISurfaceComposer>(impl)
+    {
+    }
+
+    virtual sp<ISurfaceFlingerClient> createConnection()
+    {
+        uint32_t n;
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
+        return interface_cast<ISurfaceFlingerClient>(reply.readStrongBinder());
+    }
+
+    virtual sp<IMemory> getCblk() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply);
+        return interface_cast<IMemory>(reply.readStrongBinder());
+    }
+
+    virtual void openGlobalTransaction()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::OPEN_GLOBAL_TRANSACTION, data, &reply);
+    }
+
+    virtual void closeGlobalTransaction()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::CLOSE_GLOBAL_TRANSACTION, data, &reply);
+    }
+
+    virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeInt32(dpy);
+        data.writeInt32(flags);
+        remote()->transact(BnSurfaceComposer::FREEZE_DISPLAY, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeInt32(dpy);
+        data.writeInt32(flags);
+        remote()->transact(BnSurfaceComposer::UNFREEZE_DISPLAY, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual int setOrientation(DisplayID dpy, int orientation)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeInt32(dpy);
+        data.writeInt32(orientation);
+        remote()->transact(BnSurfaceComposer::SET_ORIENTATION, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual void bootFinished()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
+    }
+
+    virtual status_t requestGPU(
+            const sp<IGPUCallback>& callback, gpu_info_t* gpu)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeStrongBinder(callback->asBinder());
+        remote()->transact(BnSurfaceComposer::REQUEST_GPU, data, &reply);
+        gpu->regs = interface_cast<IMemory>(reply.readStrongBinder());
+        gpu->count = reply.readInt32();
+
+        // FIXME: for now, we don't dynamically allocate the regions array
+        size_t maxCount = sizeof(gpu->regions)/sizeof(*gpu->regions);
+        if (gpu->count > maxCount)
+            return BAD_VALUE;
+
+        for (size_t i=0 ; i<gpu->count ; i++) {
+            gpu->regions[i].region = interface_cast<IMemory>(reply.readStrongBinder());
+            gpu->regions[i].reserved = reply.readInt32();
+        }
+        return reply.readInt32();
+    }
+
+    virtual status_t revokeGPU()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::REVOKE_GPU, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual void signal() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnSurfaceComposer::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    status_t err = BnInterface<ISurfaceComposer>::onTransact(code, data, reply, flags);
+    if (err == NO_ERROR)
+        return err;
+
+    CHECK_INTERFACE(ISurfaceComposer, data, reply);
+
+    switch(code) {
+        case CREATE_CONNECTION: {
+            sp<IBinder> b = createConnection()->asBinder();
+            reply->writeStrongBinder(b);
+        } break;
+        case OPEN_GLOBAL_TRANSACTION: {
+            openGlobalTransaction();
+        } break;
+        case CLOSE_GLOBAL_TRANSACTION: {
+            closeGlobalTransaction();
+        } break;
+        case SET_ORIENTATION: {
+            DisplayID dpy = data.readInt32();
+            int orientation = data.readInt32();
+            reply->writeInt32( setOrientation(dpy, orientation) );
+        } break;
+        case FREEZE_DISPLAY: {
+            DisplayID dpy = data.readInt32();
+            uint32_t flags = data.readInt32();
+            reply->writeInt32( freezeDisplay(dpy, flags) );
+        } break;
+        case UNFREEZE_DISPLAY: {
+            DisplayID dpy = data.readInt32();
+            uint32_t flags = data.readInt32();
+            reply->writeInt32( unfreezeDisplay(dpy, flags) );
+        } break;
+        case BOOT_FINISHED: {
+            bootFinished();
+        } break;
+        case REVOKE_GPU: {
+            reply->writeInt32( revokeGPU() );
+        } break;
+        case SIGNAL: {
+            signal();
+        } break;
+        case GET_CBLK: {
+            sp<IBinder> b = getCblk()->asBinder();
+            reply->writeStrongBinder(b);
+        } break;
+        case REQUEST_GPU: {
+            // TODO: this should be protected by a permission
+            gpu_info_t info;
+            sp<IGPUCallback> callback
+                = interface_cast<IGPUCallback>(data.readStrongBinder());
+            status_t res = requestGPU(callback, &info);
+
+            // FIXME: for now, we don't dynamically allocate the regions array
+            size_t maxCount = sizeof(info.regions)/sizeof(*info.regions);
+            if (info.count > maxCount)
+                return BAD_VALUE;
+
+            reply->writeStrongBinder(info.regs->asBinder());
+            reply->writeInt32(info.count);
+            for (size_t i=0 ; i<info.count ; i++) {
+                reply->writeStrongBinder(info.regions[i].region->asBinder());
+                reply->writeInt32(info.regions[i].reserved);
+            }
+            reply->writeInt32(res);
+        } break;
+        default:
+            return UNKNOWN_TRANSACTION;
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+enum {
+    // Note: BOOT_FINISHED must remain this value, it is called by ActivityManagerService.
+    GPU_LOST = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpGPUCallback : public BpInterface<IGPUCallback>
+{
+public:
+    BpGPUCallback(const sp<IBinder>& impl)
+        : BpInterface<IGPUCallback>(impl)
+    {
+    }
+
+    virtual void gpuLost()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGPUCallback::getInterfaceDescriptor());
+        remote()->transact(GPU_LOST, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(GPUCallback, "android.ui.IGPUCallback");
+
+status_t BnGPUCallback::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GPU_LOST: {
+            CHECK_INTERFACE(IGPUCallback, data, reply);
+            gpuLost();
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+};
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp
new file mode 100644
index 0000000..9444af7
--- /dev/null
+++ b/libs/ui/ISurfaceFlingerClient.cpp
@@ -0,0 +1,210 @@
+/*
+ * 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 <utils/Parcel.h>
+#include <utils/IMemory.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+
+#include <ui/ISurface.h>
+#include <ui/ISurfaceFlingerClient.h>
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+#include <private/ui/LayerState.h>
+
+// ---------------------------------------------------------------------------
+
+#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 void getControlBlocks(sp<IMemory>* ctl) const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        remote()->transact(GET_CBLK, data, &reply);
+        *ctl  = interface_cast<IMemory>(reply.readStrongBinder());
+    }
+
+    virtual sp<ISurface> createSurface( surface_data_t* params,
+                                        int pid,
+                                        DisplayID display,
+                                        uint32_t w,
+                                        uint32_t h,
+                                        PixelFormat format,
+                                        uint32_t flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
+        data.writeInt32(pid);
+        data.writeInt32(display);
+        data.writeInt32(w);
+        data.writeInt32(h);
+        data.writeInt32(format);
+        data.writeInt32(flags);
+        remote()->transact(CREATE_SURFACE, data, &reply);
+        params->readFromParcel(data);
+        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");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+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<IMemory> ctl;
+            getControlBlocks(&ctl);
+            reply->writeStrongBinder(ctl->asBinder());
+            return NO_ERROR;
+        } break;
+    }
+
+    // these must be checked
+     
+     IPCThreadState* ipc = IPCThreadState::self();
+     const int pid = ipc->getCallingPid();
+     const int self_pid    = getpid();
+     if (UNLIKELY(pid != self_pid)) {
+         // we're called from a different process, do the real check
+         if (!checkCallingPermission(
+                 String16("android.permission.ACCESS_SURFACE_FLINGER")))
+         {
+             const int uid = ipc->getCallingUid();
+             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();
+            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, 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();
+    type = parcel.readInt32();
+    heap[0] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
+    heap[1] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
+    return NO_ERROR;
+}
+
+status_t ISurfaceFlingerClient::surface_data_t::writeToParcel(Parcel* parcel) const
+{
+    parcel->writeInt32(token);
+    parcel->writeInt32(identity);
+    parcel->writeInt32(type);
+    parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder() : NULL);
+    parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder() : NULL);
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/ui/KeyCharacterMap.cpp
new file mode 100644
index 0000000..e891181
--- /dev/null
+++ b/libs/ui/KeyCharacterMap.cpp
@@ -0,0 +1,263 @@
+#define LOG_TAG "KeyCharacterMap"
+
+#include <ui/KeyCharacterMap.h>
+#include <cutils/properties.h>
+
+#include <utils/Log.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+
+struct Header
+{
+    char magic[8];
+    unsigned int endian;
+    unsigned int version;
+    unsigned int keycount;
+    unsigned char kbdtype;
+    char padding[11];
+};
+
+KeyCharacterMap::KeyCharacterMap()
+{
+}
+
+KeyCharacterMap::~KeyCharacterMap()
+{
+    free(m_keys);
+}
+
+unsigned short
+KeyCharacterMap::get(int keycode, int meta)
+{
+    Key* k = find_key(keycode);
+    if (k != NULL) {
+        return k->data[meta & META_MASK];
+    }
+    return 0;
+}
+
+unsigned short
+KeyCharacterMap::getNumber(int keycode)
+{
+    Key* k = find_key(keycode);
+    if (k != NULL) {
+        return k->number;
+    }
+    return 0;
+}
+
+unsigned short
+KeyCharacterMap::getMatch(int keycode, const unsigned short* chars,
+                          int charsize, uint32_t modifiers)
+{
+    Key* k = find_key(keycode);
+    modifiers &= 3; // ignore the SYM key because we don't have keymap entries for it
+    if (k != NULL) {
+        const uint16_t* data = k->data;
+        for (int j=0; j<charsize; j++) {
+            uint16_t c = chars[j];
+            for (int i=0; i<(META_MASK + 1); i++) {
+                if ((modifiers == 0) || ((modifiers & i) != 0)) {
+                    if (c == data[i]) {
+                        return c;
+                    }
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+unsigned short
+KeyCharacterMap::getDisplayLabel(int keycode)
+{
+    Key* k = find_key(keycode);
+    if (k != NULL) {
+        return k->display_label;
+    }
+    return 0;
+}
+
+bool
+KeyCharacterMap::getKeyData(int keycode, unsigned short *displayLabel,
+                            unsigned short *number, unsigned short* results)
+{
+    Key* k = find_key(keycode);
+    if (k != NULL) {
+        memcpy(results, k->data, sizeof(short)*(META_MASK + 1));
+        *number = k->number;
+        *displayLabel = k->display_label;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool
+KeyCharacterMap::find_char(uint16_t c, uint32_t* key, uint32_t* mods)
+{
+    uint32_t N = m_keyCount;
+    for (int j=0; j<(META_MASK + 1); j++) {
+        Key const* keys = m_keys;
+        for (uint32_t i=0; i<N; i++) {
+            if (keys->data[j] == c) {
+                *key = keys->keycode;
+                *mods = j;
+                return true;
+            }
+            keys++;
+        }
+    }
+    return false;
+}
+
+bool
+KeyCharacterMap::getEvents(uint16_t* chars, size_t len,
+                           Vector<int32_t>* keys, Vector<uint32_t>* modifiers)
+{
+    for (size_t i=0; i<len; i++) {
+        uint32_t k, mods;
+        if (find_char(chars[i], &k, &mods)) {
+            keys->add(k);
+            modifiers->add(mods);
+        } else {
+            return false;
+        }
+    }
+    return true;
+}
+
+KeyCharacterMap::Key*
+KeyCharacterMap::find_key(int keycode)
+{
+    Key* keys = m_keys;
+    int low = 0;
+    int high = m_keyCount - 1;
+    int mid;
+    int n;
+    while (low <= high) {
+        mid = (low + high) / 2;
+        n = keys[mid].keycode;
+        if (keycode < n) {
+            high = mid - 1;
+        } else if (keycode > n) {
+            low = mid + 1;
+        } else {
+            return keys + mid;
+        }
+    }
+    return NULL;
+}
+
+KeyCharacterMap*
+KeyCharacterMap::load(int id)
+{
+    KeyCharacterMap* rv = NULL;
+    char path[PATH_MAX];
+    char propName[100];
+    char dev[PROPERTY_VALUE_MAX];
+    char tmpfn[PROPERTY_VALUE_MAX];
+    int err;
+    const char* root = getenv("ANDROID_ROOT");
+
+    sprintf(propName, "hw.keyboards.%u.devname", id);
+    err = property_get(propName, dev, "");
+    if (err > 0) {
+        // replace all the spaces with underscores
+        strcpy(tmpfn, dev);
+        for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
+            *p = '_';
+        snprintf(path, sizeof(path), "%s/usr/keychars/%s.kcm.bin", root, tmpfn);
+        //LOGD("load: dev='%s' path='%s'\n", dev, path);
+        rv = try_file(path);
+        if (rv != NULL) {
+            return rv;
+        }
+        LOGW("Error loading keycharmap file '%s'. %s='%s'", path, propName, dev);
+    } else {
+        LOGW("No keyboard for id %d", id);
+    }
+
+    snprintf(path, sizeof(path), "%s/usr/keychars/qwerty.kcm.bin", root);
+    rv = try_file(path);
+    if (rv == NULL) {
+        LOGE("Can't find any keycharmaps (also tried %s)", path);
+        return NULL;
+    }
+    LOGW("Using default keymap: %s", path);
+
+    return rv;
+}
+
+KeyCharacterMap*
+KeyCharacterMap::try_file(const char* filename)
+{
+    KeyCharacterMap* rv = NULL;
+    Key* keys;
+    int fd;
+    off_t filesize;
+    Header header;
+    int err;
+    
+    fd = open(filename, O_RDONLY);
+    if (fd == -1) {
+        LOGW("Can't open keycharmap file");
+        return NULL;
+    }
+
+    filesize = lseek(fd, 0, SEEK_END);
+    lseek(fd, 0, SEEK_SET);
+
+    // validate the header
+    if (filesize <= (off_t)sizeof(header)) {
+        LOGW("Bad keycharmap - filesize=%d\n", (int)filesize);
+        goto cleanup1;
+    }
+
+    err = read(fd, &header, sizeof(header));
+    if (err == -1) {
+        LOGW("Error reading keycharmap file");
+        goto cleanup1;
+    }
+
+    if (0 != memcmp(header.magic, "keychar", 8)) {
+        LOGW("Bad keycharmap magic token");
+        goto cleanup1;
+    }
+    if (header.endian != 0x12345678) {
+        LOGW("Bad keycharmap endians");
+        goto cleanup1;
+    }
+    if ((header.version & 0xff) != 2) {
+        LOGW("Only support keycharmap version 2 (got 0x%08x)", header.version);
+        goto cleanup1;
+    }
+    if (filesize < (off_t)(sizeof(Header)+(sizeof(Key)*header.keycount))) {
+        LOGW("Bad keycharmap file size\n");
+        goto cleanup1;
+    }
+
+    // read the key data
+    keys = (Key*)malloc(sizeof(Key)*header.keycount);
+    err = read(fd, keys, sizeof(Key)*header.keycount);
+    if (err == -1) {
+        LOGW("Error reading keycharmap file");
+        free(keys);
+        goto cleanup1;
+    }
+
+    // return the object
+    rv = new KeyCharacterMap;
+    rv->m_keyCount = header.keycount;
+    rv->m_keys = keys;
+    rv->m_type = header.kbdtype;
+
+cleanup1:
+    close(fd);
+
+    return rv;
+}
diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/ui/KeyLayoutMap.cpp
new file mode 100644
index 0000000..15ae54c
--- /dev/null
+++ b/libs/ui/KeyLayoutMap.cpp
@@ -0,0 +1,235 @@
+#define LOG_TAG "KeyLayoutMap"
+
+#include "KeyLayoutMap.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <utils/String8.h>
+#include <stdlib.h>
+#include <ui/KeycodeLabels.h>
+#include <utils/Log.h>
+
+namespace android {
+
+KeyLayoutMap::KeyLayoutMap()
+    :m_status(NO_INIT),
+     m_keys()
+{
+}
+
+KeyLayoutMap::~KeyLayoutMap()
+{
+}
+
+static String8
+next_token(char const** p, int *line)
+{
+    bool begun = false;
+    const char* begin = *p;
+    const char* end = *p;
+    while (true) {
+        if (*end == '\n') {
+            (*line)++;
+        }
+        switch (*end)
+        {
+            case '#':
+                if (begun) {
+                    *p = end;
+                    return String8(begin, end-begin);
+                } else {
+                    do {
+                        begin++;
+                        end++;
+                    } while (*begin != '\0' && *begin != '\n');
+                }
+            case '\0':
+            case ' ':
+            case '\n':
+            case '\r':
+            case '\t':
+                if (begun || (*end == '\0')) {
+                    *p = end;
+                    return String8(begin, end-begin);
+                } else {
+                    begin++;
+                    end++;
+                    break;
+                }
+            default:
+                end++;
+                begun = true;
+        }
+    }
+}
+
+static int32_t
+token_to_value(const char *literal, const KeycodeLabel *list)
+{
+    while (list->literal) {
+        if (0 == strcmp(literal, list->literal)) {
+            return list->value;
+        }
+        list++;
+    }
+    return list->value;
+}
+
+status_t
+KeyLayoutMap::load(const char* filename)
+{
+    int fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        LOGE("error opening file=%s err=%s\n", filename, strerror(errno));
+        m_status = errno;
+        return errno;
+    }
+
+    off_t len = lseek(fd, 0, SEEK_END);
+    off_t errlen = lseek(fd, 0, SEEK_SET);
+    if (len < 0 || errlen < 0) {
+        close(fd);
+        LOGE("error seeking file=%s err=%s\n", filename, strerror(errno));
+        m_status = errno;
+        return errno;
+    }
+
+    char* buf = (char*)malloc(len+1);
+    if (read(fd, buf, len) != len) {
+        LOGE("error reading file=%s err=%s\n", filename, strerror(errno));
+        m_status = errno != 0 ? errno : ((int)NOT_ENOUGH_DATA);
+        return errno != 0 ? errno : ((int)NOT_ENOUGH_DATA);
+    }
+    errno = 0;
+    buf[len] = '\0';
+
+    int32_t scancode = -1;
+    int32_t keycode = -1;
+    uint32_t flags = 0;
+    uint32_t tmp;
+    char* end;
+    status_t err = NO_ERROR;
+    int line = 1;
+    char const* p = buf;
+    enum { BEGIN, SCANCODE, KEYCODE, FLAG } state = BEGIN;
+    while (true) {
+        String8 token = next_token(&p, &line);
+        if (*p == '\0') {
+            break;
+        }
+        switch (state)
+        {
+            case BEGIN:
+                if (token == "key") {
+                    state = SCANCODE;
+                } else {
+                    LOGE("%s:%d: expected key, got '%s'\n", filename, line,
+                            token.string());
+                    err = BAD_VALUE;
+                    goto done;
+                }
+                break;
+            case SCANCODE:
+                scancode = strtol(token.string(), &end, 0);
+                if (*end != '\0') {
+                    LOGE("%s:%d: expected scancode (a number), got '%s'\n",
+                            filename, line, token.string());
+                    goto done;
+                }
+                //LOGI("%s:%d: got scancode %d\n", filename, line, scancode );
+                state = KEYCODE;
+                break;
+            case KEYCODE:
+                keycode = token_to_value(token.string(), KEYCODES);
+                //LOGI("%s:%d: got keycode %d for %s\n", filename, line, keycode, token.string() );
+                if (keycode == 0) {
+                    LOGE("%s:%d: expected keycode, got '%s'\n",
+                            filename, line, token.string());
+                    goto done;
+                }
+                state = FLAG;
+                break;
+            case FLAG:
+                if (token == "key") {
+                    if (scancode != -1) {
+                        //LOGI("got key decl scancode=%d keycode=%d"
+                        //       " flags=0x%08x\n", scancode, keycode, flags);
+                        Key k = { keycode, flags };
+                        m_keys.add(scancode, k);
+                        state = SCANCODE;
+                        scancode = -1;
+                        keycode = -1;
+                        flags = 0;
+                        break;
+                    }
+                }
+                tmp = token_to_value(token.string(), FLAGS);
+                //LOGI("%s:%d: got flags %x for %s\n", filename, line, tmp, token.string() );
+                if (tmp == 0) {
+                    LOGE("%s:%d: expected flag, got '%s'\n",
+                            filename, line, token.string());
+                    goto done;
+                }
+                flags |= tmp;
+                break;
+        }
+    }
+    if (state == FLAG && scancode != -1 ) {
+        //LOGI("got key decl scancode=%d keycode=%d"
+        //       " flags=0x%08x\n", scancode, keycode, flags);
+        Key k = { keycode, flags };
+        m_keys.add(scancode, k);
+    }
+
+done:
+    free(buf);
+    close(fd);
+
+    m_status = err;
+    return err;
+}
+
+status_t
+KeyLayoutMap::map(int32_t scancode, int32_t *keycode, uint32_t *flags) const
+{
+    if (m_status != NO_ERROR) {
+        return m_status;
+    }
+
+    ssize_t index = m_keys.indexOfKey(scancode);
+    if (index < 0) {
+        //LOGW("couldn't map scancode=%d\n", scancode);
+        return NAME_NOT_FOUND;
+    }
+
+    const Key& k = m_keys.valueAt(index);
+
+    *keycode = k.keycode;
+    *flags = k.flags;
+
+    //LOGD("mapped scancode=%d to keycode=%d flags=0x%08x\n", scancode,
+    //        keycode, flags);
+
+    return NO_ERROR;
+}
+
+status_t
+KeyLayoutMap::findScancodes(int32_t keycode, Vector<int32_t>* outScancodes) const
+{
+    if (m_status != NO_ERROR) {
+        return m_status;
+    }
+    
+    const size_t N = m_keys.size();
+    for (size_t i=0; i<N; i++) {
+        if (m_keys.valueAt(i).keycode == keycode) {
+            outScancodes->add(m_keys.keyAt(i));
+        }
+    }
+    
+    return NO_ERROR;
+}
+
+};
diff --git a/libs/ui/KeyLayoutMap.h b/libs/ui/KeyLayoutMap.h
new file mode 100644
index 0000000..43f84ce
--- /dev/null
+++ b/libs/ui/KeyLayoutMap.h
@@ -0,0 +1,31 @@
+#ifndef KEYLAYOUTMAP_H
+#define KEYLAYOUTMAP_H
+
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+class KeyLayoutMap
+{
+public:
+    KeyLayoutMap();
+    ~KeyLayoutMap();
+
+    status_t load(const char* filename);
+
+    status_t map(int32_t scancode, int32_t *keycode, uint32_t *flags) const;
+    status_t findScancodes(int32_t keycode, Vector<int32_t>* outScancodes) const;
+
+private:
+    struct Key {
+        int32_t keycode;
+        uint32_t flags;
+    };
+
+    status_t m_status;
+    KeyedVector<int32_t,Key> m_keys;
+};
+
+};
+
+#endif // KEYLAYOUTMAP_H
diff --git a/libs/ui/LayerState.cpp b/libs/ui/LayerState.cpp
new file mode 100644
index 0000000..0b6374b
--- /dev/null
+++ b/libs/ui/LayerState.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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 <utils/Errors.h>
+#include <utils/Parcel.h>
+#include <private/ui/LayerState.h>
+
+namespace android {
+
+status_t layer_state_t::write(Parcel& output) const
+{
+    size_t size = sizeof(layer_state_t);
+
+    //output.writeStrongBinder(surface->asBinder());
+    //size -= sizeof(surface);
+
+    transparentRegion.write(output);
+    size -= sizeof(transparentRegion);
+    
+    output.write(this, size);
+    
+    return NO_ERROR;
+}
+
+status_t layer_state_t::read(const Parcel& input)
+{
+    size_t size = sizeof(layer_state_t);
+
+    //surface = interface_cast<ISurface>(input.readStrongBinder());
+    //size -= sizeof(surface);
+
+    transparentRegion.read(input);
+    size -= sizeof(transparentRegion);
+
+    input.read(this, size);
+    
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/libs/ui/MODULE_LICENSE_APACHE2 b/libs/ui/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/ui/MODULE_LICENSE_APACHE2
diff --git a/libs/ui/NOTICE b/libs/ui/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/libs/ui/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
new file mode 100644
index 0000000..605c8ae
--- /dev/null
+++ b/libs/ui/PixelFormat.cpp
@@ -0,0 +1,66 @@
+/*
+ * 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 <ui/PixelFormat.h>
+#include <pixelflinger/format.h>
+
+namespace android {
+
+ssize_t bytesPerPixel(PixelFormat format)
+{
+    PixelFormatInfo info;
+    status_t err = getPixelFormatInfo(format, &info);
+    return (err < 0) ? err : info.bytesPerPixel;
+}
+
+ssize_t bitsPerPixel(PixelFormat format)
+{
+    PixelFormatInfo info;
+    status_t err = getPixelFormatInfo(format, &info);
+    return (err < 0) ? err : info.bitsPerPixel;
+}
+
+status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info)
+{
+    if (format < 0)
+        return BAD_VALUE;
+
+    if (info->version != sizeof(PixelFormatInfo))
+        return INVALID_OPERATION;
+
+    size_t numEntries;
+    const GGLFormat *i = gglGetPixelFormatTable(&numEntries) + format;
+    bool valid = uint32_t(format) < numEntries;
+    if (!valid) {
+        return BAD_INDEX;
+    }
+
+    info->format = format;
+    info->bytesPerPixel = i->size;
+    info->bitsPerPixel  = i->bitsPerPixel;
+    info->h_alpha       = i->ah;
+    info->l_alpha       = i->al;
+    info->h_red         = i->rh;
+    info->l_red         = i->rl;
+    info->h_green       = i->gh;
+    info->l_green       = i->gl;
+    info->h_blue        = i->bh;
+    info->l_blue        = i->bl;
+    return NO_ERROR;
+}
+
+}; // namespace android
+
diff --git a/libs/ui/Point.cpp b/libs/ui/Point.cpp
new file mode 100644
index 0000000..438d49f
--- /dev/null
+++ b/libs/ui/Point.cpp
@@ -0,0 +1,11 @@
+/*
+ *  Point.cpp
+ *  Android
+ *
+ *  Created on 11/16/2006.
+ *  Copyright 2005 The Android Open Source Project
+ *
+ */
+
+#include <ui/Point.h>
+
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
new file mode 100644
index 0000000..99e68bb
--- /dev/null
+++ b/libs/ui/Rect.cpp
@@ -0,0 +1,86 @@
+/*
+ *  Rect.cpp
+ *  Android
+ *
+ *  Created on 10/14/05.
+ *  Copyright 2005 The Android Open Source Project
+ *
+ */
+
+#include <ui/Rect.h>
+
+namespace android {
+
+inline int min(int a, int b) {
+    return (a<b) ? a : b;
+}
+
+inline int max(int a, int b) {
+    return (a>b) ? a : b;
+}
+
+void Rect::makeInvalid() {
+    left = 0;
+    top = 0;
+    right = -1;
+    bottom = -1;
+}
+
+bool Rect::operator < (const Rect& rhs) const
+{
+    if (top<rhs.top) {
+        return true;
+    } else if (top == rhs.top) {
+        if (left < rhs.left) {
+            return true;
+        } else if (left == rhs.left) {
+            if (bottom<rhs.bottom) {
+                return true;
+            } else if (bottom == rhs.bottom) {
+                if (right<rhs.right) {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+Rect& Rect::offsetTo(int x, int y)
+{
+    right -= left - x;
+    bottom -= top - y;
+    left = x;
+    top = y;
+    return *this;
+}
+
+Rect& Rect::offsetBy(int x, int y)
+{
+    left += x;
+    top  += y;
+    right+= x;
+    bottom+=y;
+    return *this;
+}
+
+Rect Rect::operator + (const Point& rhs) const
+{
+    return Rect(left+rhs.x, top+rhs.y, right+rhs.x, bottom+rhs.y); 
+}
+
+Rect Rect::operator - (const Point& rhs) const
+{
+    return Rect(left-rhs.x, top-rhs.y, right-rhs.x, bottom-rhs.y); 
+}
+
+bool Rect::intersect(const Rect& with, Rect* result) const
+{
+    result->left    = max(left, with.left);
+    result->top     = max(top, with.top);
+    result->right   = min(right, with.right);
+    result->bottom  = min(bottom, with.bottom);
+    return !(result->isEmpty());
+}
+
+}; // namespace android
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
new file mode 100644
index 0000000..3e07f2b
--- /dev/null
+++ b/libs/ui/Region.cpp
@@ -0,0 +1,315 @@
+/*
+ * 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 "Region"
+
+#include <stdio.h>
+#include <utils/Atomic.h>
+#include <utils/Debug.h>
+#include <utils/String8.h>
+#include <ui/Region.h>
+#include <corecg/SkRegion.h>
+#include <corecg/SkRect.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+Region::Region()
+{
+}
+
+Region::Region(const Region& rhs)
+    : mRegion(rhs.mRegion)
+{
+}
+
+Region::Region(const SkRegion& rhs)
+    : mRegion(rhs)
+{
+}
+
+Region::~Region()
+{
+}
+
+Region::Region(const Rect& rhs)
+{
+    set(rhs);
+}
+
+Region::Region(const Parcel& parcel)
+{
+    read(parcel);
+}
+
+Region::Region(const void* buffer)
+{
+    read(buffer);
+}
+
+Region& Region::operator = (const Region& rhs)
+{
+    mRegion = rhs.mRegion;
+    return *this;
+}
+
+const SkRegion& Region::toSkRegion() const
+{
+    return mRegion;
+}
+
+Rect Region::bounds() const
+{
+    const SkIRect& b(mRegion.getBounds());
+    return Rect(b.fLeft, b.fTop, b.fRight, b.fBottom);
+}
+
+void Region::clear()
+{
+    mRegion.setEmpty();
+}
+
+void Region::set(const Rect& r)
+{
+    SkIRect ir;
+    ir.set(r.left, r.top, r.right, r.bottom);
+    mRegion.setRect(ir);
+}
+
+// ----------------------------------------------------------------------------
+
+Region& Region::orSelf(const Rect& r)
+{
+    SkIRect ir;
+    ir.set(r.left, r.top, r.right, r.bottom);
+    mRegion.op(ir, SkRegion::kUnion_Op);
+    return *this;
+}
+
+Region& Region::andSelf(const Rect& r)
+{
+    SkIRect ir;
+    ir.set(r.left, r.top, r.right, r.bottom);
+    mRegion.op(ir, SkRegion::kIntersect_Op);
+    return *this;
+}
+
+// ----------------------------------------------------------------------------
+
+Region& Region::orSelf(const Region& rhs) {
+    mRegion.op(rhs.mRegion, SkRegion::kUnion_Op);
+    return *this;
+}
+
+Region& Region::andSelf(const Region& rhs) {
+    mRegion.op(rhs.mRegion, SkRegion::kIntersect_Op);
+    return *this;
+}
+
+Region& Region::subtractSelf(const Region& rhs) {
+    mRegion.op(rhs.mRegion, SkRegion::kDifference_Op);
+    return *this;
+}
+
+Region& Region::translateSelf(int x, int y) {
+    if (x|y) mRegion.translate(x, y);
+    return *this;
+}
+
+Region Region::merge(const Region& rhs) const {
+    Region result;
+    result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kUnion_Op);
+    return result;
+}
+
+Region Region::intersect(const Region& rhs) const {
+    Region result;
+    result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kIntersect_Op);
+    return result;
+}
+
+Region Region::subtract(const Region& rhs) const {
+    Region result;
+    result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kDifference_Op);
+    return result;
+}
+
+Region Region::translate(int x, int y) const {
+    Region result;
+    mRegion.translate(x, y, &result.mRegion);
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+
+Region& Region::orSelf(const Region& rhs, int dx, int dy) {
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    mRegion.op(r, SkRegion::kUnion_Op);
+    return *this;
+}
+
+Region& Region::andSelf(const Region& rhs, int dx, int dy) {
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    mRegion.op(r, SkRegion::kIntersect_Op);
+    return *this;
+}
+
+Region& Region::subtractSelf(const Region& rhs, int dx, int dy) {
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    mRegion.op(r, SkRegion::kDifference_Op);
+    return *this;
+}
+
+Region Region::merge(const Region& rhs, int dx, int dy) const {
+    Region result;
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    result.mRegion.op(mRegion, r, SkRegion::kUnion_Op);
+    return result;
+}
+
+Region Region::intersect(const Region& rhs, int dx, int dy) const {
+    Region result;
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    result.mRegion.op(mRegion, r, SkRegion::kIntersect_Op);
+    return result;
+}
+
+Region Region::subtract(const Region& rhs, int dx, int dy) const {
+    Region result;
+    SkRegion r(rhs.mRegion);
+    r.translate(dx, dy);
+    result.mRegion.op(mRegion, r, SkRegion::kDifference_Op);
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+
+Region::iterator::iterator(const Region& r)
+    : mIt(r.mRegion)
+{
+}
+
+int Region::iterator::iterate(Rect* rect)
+{
+    if (mIt.done())
+        return 0;
+    const SkIRect& r(mIt.rect());
+    rect->left  = r.fLeft;
+    rect->top   = r.fTop;
+    rect->right = r.fRight;
+    rect->bottom= r.fBottom;
+    mIt.next();
+    return 1;
+}
+
+// ----------------------------------------------------------------------------
+
+// we write a 4byte size ahead of the actual region, so we know how much we'll need for reading
+
+status_t Region::write(Parcel& parcel) const
+{
+    int32_t size = mRegion.flatten(NULL);
+    parcel.writeInt32(size);
+    mRegion.flatten(parcel.writeInplace(size));
+    return NO_ERROR;
+}
+
+status_t Region::read(const Parcel& parcel)
+{
+    size_t size = parcel.readInt32();
+    mRegion.unflatten(parcel.readInplace(size));
+    return NO_ERROR;
+}
+
+ssize_t Region::write(void* buffer, size_t size) const
+{
+    size_t sizeNeeded = mRegion.flatten(NULL);
+    if (sizeNeeded > size) return NO_MEMORY;
+    return mRegion.flatten(buffer);
+}
+
+ssize_t Region::read(const void* buffer)
+{
+    return mRegion.unflatten(buffer);
+}
+
+ssize_t Region::writeEmpty(void* buffer, size_t size)
+{
+    if (size < 4) return NO_MEMORY;
+    // this needs to stay in sync with SkRegion
+    *static_cast<int32_t*>(buffer) = -1;
+    return 4;
+}
+
+bool Region::isEmpty(void* buffer)
+{
+    // this needs to stay in sync with SkRegion
+    return *static_cast<int32_t*>(buffer) == -1;
+}
+
+size_t Region::rects(Vector<Rect>& rectList) const
+{
+    rectList.clear();
+    if (!isEmpty()) {
+        SkRegion::Iterator iterator(mRegion);
+        while( !iterator.done() ) {
+            const SkIRect& ir(iterator.rect());
+            rectList.push(Rect(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom));
+            iterator.next();
+        }
+    }
+    return rectList.size();
+}
+
+void Region::dump(String8& out, const char* what, uint32_t flags) const
+{
+    (void)flags;
+    Vector<Rect> r;
+    rects(r);
+    
+    size_t SIZE = 256;
+    char buffer[SIZE];
+    
+    snprintf(buffer, SIZE, "  Region %s (this=%p, count=%d)\n", what, this, r.size());
+    out.append(buffer);
+    for (size_t i=0 ; i<r.size() ; i++) {
+        snprintf(buffer, SIZE, "    [%3d, %3d, %3d, %3d]\n",
+            r[i].left, r[i].top,r[i].right,r[i].bottom);
+        out.append(buffer);
+    }
+}
+
+void Region::dump(const char* what, uint32_t flags) const
+{
+    (void)flags;
+    Vector<Rect> r;
+    rects(r);
+    LOGD("  Region %s (this=%p, count=%d)\n", what, this, r.size());
+    for (size_t i=0 ; i<r.size() ; i++) {
+        LOGD("    [%3d, %3d, %3d, %3d]\n",
+            r[i].left, r[i].top,r[i].right,r[i].bottom);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
new file mode 100644
index 0000000..0a9aaad
--- /dev/null
+++ b/libs/ui/Surface.cpp
@@ -0,0 +1,261 @@
+/*
+ * 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 "Surface"
+
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IMemory.h>
+#include <utils/Log.h>
+
+#include <ui/ISurface.h>
+#include <ui/Surface.h>
+#include <ui/SurfaceComposerClient.h>
+#include <ui/Rect.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+Surface::Surface(const sp<SurfaceComposerClient>& client, 
+        const sp<ISurface>& surface,
+        const ISurfaceFlingerClient::surface_data_t& data,
+        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
+        bool owner)
+    : mClient(client), mSurface(surface), mMemoryType(data.type),
+      mToken(data.token), mIdentity(data.identity),
+      mFormat(format), mFlags(flags), mOwner(owner)
+{
+    mSwapRectangle.makeInvalid();
+    mSurfaceHeapBase[0] = 0;
+    mSurfaceHeapBase[1] = 0;
+    mHeap[0] = data.heap[0]; 
+    mHeap[1] = data.heap[1];
+}
+
+Surface::Surface(Surface const* rhs)
+    : mOwner(false)
+{
+    mToken   = rhs->mToken;
+    mIdentity= rhs->mIdentity;
+    mClient  = rhs->mClient;
+    mSurface = rhs->mSurface;
+    mHeap[0] = rhs->mHeap[0];
+    mHeap[1] = rhs->mHeap[1];
+    mMemoryType = rhs->mMemoryType;
+    mFormat  = rhs->mFormat;
+    mFlags   = rhs->mFlags;
+    mSurfaceHeapBase[0] = rhs->mSurfaceHeapBase[0];
+    mSurfaceHeapBase[1] = rhs->mSurfaceHeapBase[1];
+    mSwapRectangle.makeInvalid();
+}
+
+Surface::~Surface()
+{
+    if (mOwner && mToken>=0 && mClient!=0) {
+        mClient->destroySurface(mToken);
+    }
+    mClient.clear();
+    mSurface.clear();
+    mHeap[0].clear();
+    mHeap[1].clear();
+    IPCThreadState::self()->flushCommands();
+}
+
+sp<Surface> Surface::dup() const
+{
+    Surface const * r = this;
+    if (this && mOwner) {
+        // the only reason we need to do this is because of Java's garbage
+        // collector: because we're creating a copy of the Surface
+        // instead of a reference, we can garantee that when our last
+        // reference goes away, the real surface will be deleted.
+        // Without this hack (the code is correct too), we'd have to
+        // wait for a GC for the surface to go away.
+        r = new Surface(this);        
+    }
+    return const_cast<Surface*>(r);
+}
+
+status_t Surface::nextBuffer(SurfaceInfo* info) {
+    return mClient->nextBuffer(this, info);
+}
+
+status_t Surface::lock(SurfaceInfo* info, bool blocking) {
+    return Surface::lock(info, NULL, blocking);
+}
+
+status_t Surface::lock(SurfaceInfo* info, Region* dirty, bool blocking) {
+    if (heapBase(0) == 0) return INVALID_OPERATION;
+    if (heapBase(1) == 0) return INVALID_OPERATION;
+    return mClient->lockSurface(this, info, dirty, blocking);
+}
+
+status_t Surface::unlockAndPost() {
+    if (heapBase(0) == 0) return INVALID_OPERATION;
+    if (heapBase(1) == 0) return INVALID_OPERATION;
+    return mClient->unlockAndPostSurface(this);
+}
+
+status_t Surface::unlock() {
+    if (heapBase(0) == 0) return INVALID_OPERATION;
+    if (heapBase(1) == 0) return INVALID_OPERATION;
+    return mClient->unlockSurface(this);
+}
+
+status_t Surface::setLayer(int32_t layer) {
+    return mClient->setLayer(this, layer);
+}
+status_t Surface::setPosition(int32_t x, int32_t y) {
+    return mClient->setPosition(this, x, y);
+}
+status_t Surface::setSize(uint32_t w, uint32_t h) {
+    return mClient->setSize(this, w, h);
+}
+status_t Surface::hide() {
+    return mClient->hide(this);
+}
+status_t Surface::show(int32_t layer) {
+    return mClient->show(this, layer);
+}
+status_t Surface::freeze() {
+    return mClient->freeze(this);
+}
+status_t Surface::unfreeze() {
+    return mClient->unfreeze(this);
+}
+status_t Surface::setFlags(uint32_t flags, uint32_t mask) {
+    return mClient->setFlags(this, flags, mask);
+}
+status_t Surface::setTransparentRegionHint(const Region& transparent) {
+    return mClient->setTransparentRegionHint(this, transparent);
+}
+status_t Surface::setAlpha(float alpha) {
+    return mClient->setAlpha(this, alpha);
+}
+status_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+    return mClient->setMatrix(this, dsdx, dtdx, dsdy, dtdy);
+}
+status_t Surface::setFreezeTint(uint32_t tint) {
+    return mClient->setFreezeTint(this, tint);
+}
+
+Region Surface::dirtyRegion() const  {
+    return mDirtyRegion; 
+}
+void Surface::setDirtyRegion(const Region& region) const {
+    mDirtyRegion = region;
+}
+const Rect& Surface::swapRectangle() const {
+    return mSwapRectangle;
+}
+void Surface::setSwapRectangle(const Rect& r) {
+    mSwapRectangle = r;
+}
+
+sp<Surface> Surface::readFromParcel(Parcel* parcel)
+{
+    sp<SurfaceComposerClient> client;
+    ISurfaceFlingerClient::surface_data_t data;
+    sp<IBinder> clientBinder= parcel->readStrongBinder();
+    sp<ISurface> surface    = interface_cast<ISurface>(parcel->readStrongBinder());
+    data.heap[0]            = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
+    data.heap[1]            = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
+    data.type               = parcel->readInt32();
+    data.token              = parcel->readInt32();
+    data.identity           = parcel->readInt32();
+    PixelFormat format      = parcel->readInt32();
+    uint32_t flags          = parcel->readInt32();
+
+    if (clientBinder != NULL)
+        client = SurfaceComposerClient::clientForConnection(clientBinder);
+
+    return new Surface(client, surface, data, 0, 0, format, flags, false);
+}
+
+status_t Surface::writeToParcel(const sp<Surface>& surface, Parcel* parcel)
+{
+    uint32_t flags=0;
+    uint32_t format=0;
+    SurfaceID token = -1;
+    uint32_t identity = 0;
+    sp<SurfaceComposerClient> client;
+    sp<ISurface> sur;
+    sp<IMemoryHeap> heap[2];
+    int type = 0;
+    if (surface->isValid()) {
+        token = surface->mToken;
+        identity = surface->mIdentity;
+        client = surface->mClient;
+        sur = surface->mSurface;
+        heap[0] = surface->mHeap[0];
+        heap[1] = surface->mHeap[1];
+        type = surface->mMemoryType;
+        format = surface->mFormat;
+        flags = surface->mFlags;
+    }
+    parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
+    parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
+    parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder()  : NULL);
+    parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder()  : NULL);
+    parcel->writeInt32(type);
+    parcel->writeInt32(token);
+    parcel->writeInt32(identity);
+    parcel->writeInt32(format);
+    parcel->writeInt32(flags);
+    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();
+}
+
+void* Surface::heapBase(int i) const 
+{
+    void* heapBase = mSurfaceHeapBase[i];
+    // map lazily so it doesn't get mapped in clients that don't need it
+    if (heapBase == 0) {
+        const sp<IMemoryHeap>& heap(mHeap[i]);
+        if (heap != 0) {
+            heapBase = static_cast<uint8_t*>(heap->base());
+            if (heapBase == MAP_FAILED) {
+                heapBase = NULL;
+                LOGE("Couldn't map Surface's heap (binder=%p, heap=%p)",
+                        heap->asBinder().get(), heap.get());
+            }
+            mSurfaceHeapBase[i] = heapBase;
+        }
+    }
+    return heapBase;
+}
+
+}; // namespace android
+
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
new file mode 100644
index 0000000..9354a7a
--- /dev/null
+++ b/libs/ui/SurfaceComposerClient.cpp
@@ -0,0 +1,1026 @@
+/*
+ * 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 "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/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+#include <utils/IMemory.h>
+#include <utils/Log.h>
+
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+#include <ui/ISurface.h>
+#include <ui/SurfaceComposerClient.h>
+#include <ui/DisplayInfo.h>
+#include <ui/Rect.h>
+#include <ui/Point.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+#include <private/ui/SurfaceFlingerSynchro.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include <utils/BpBinder.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 {
+
+// ---------------------------------------------------------------------------
+
+// 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<IMemory>                                          gServerCblkMemory;
+static volatile surface_flinger_cblk_t*                     gServerCblk;
+
+const sp<ISurfaceComposer>& _get_surface_manager()
+{
+    if (gSurfaceManager != 0) {
+        return gSurfaceManager;
+    }
+
+    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
+        }
+    } while(binder == 0);
+    sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
+
+    Mutex::Autolock _l(gLock);
+    if (gSurfaceManager == 0) {
+        gSurfaceManager = sc;
+    }
+    return gSurfaceManager;
+}
+
+static volatile surface_flinger_cblk_t const * get_cblk()
+{
+    if (gServerCblk == 0) {
+        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        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->pointer();
+            LOGE_IF(gServerCblk==0, "Can't get server control block address");
+        }
+    }
+    return gServerCblk;
+}
+
+// ---------------------------------------------------------------------------
+
+static void copyBlt(const GGLSurface& dst,
+        const GGLSurface& src, const Region& reg)
+{
+    Region::iterator iterator(reg);
+    if (iterator) {
+        // NOTE: dst and src must be the same format
+        Rect r;
+        const size_t bpp = bytesPerPixel(src.format);
+        const size_t dbpr = dst.stride * bpp;
+        const size_t sbpr = src.stride * bpp;
+        while (iterator.iterate(&r)) {
+            ssize_t h = r.bottom - r.top;
+            if (h) {
+                size_t size = (r.right - r.left) * bpp;
+                uint8_t* s = src.data + (r.left + src.stride * r.top) * bpp;
+                uint8_t* d = dst.data + (r.left + dst.stride * r.top) * bpp;
+                if (dbpr==sbpr && size==sbpr) {
+                    size *= h;
+                    h = 1;
+                }
+                do {
+                    memcpy(d, s, size);
+                    d += dbpr;
+                    s += sbpr;
+                } while (--h > 0);
+            }
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+surface_flinger_cblk_t::surface_flinger_cblk_t()
+{
+}
+
+// ---------------------------------------------------------------------------
+
+per_client_cblk_t::per_client_cblk_t()
+{
+}
+
+// these functions are used by the clients
+inline status_t per_client_cblk_t::validate(size_t i) const {
+    if (uint32_t(i) >= NUM_LAYERS_MAX)
+        return BAD_INDEX;
+    if (layers[i].swapState & eInvalidSurface)
+        return NO_MEMORY;
+    return NO_ERROR;
+}
+
+int32_t per_client_cblk_t::lock_layer(size_t i, uint32_t flags)
+{
+    int32_t index;
+    uint32_t state;
+    int timeout = 0;
+    status_t result;
+    layer_cblk_t * const layer = layers + i;
+    const bool blocking = flags & BLOCKING;
+    const bool inspect  = flags & INSPECT;
+
+    do {
+        state = layer->swapState;
+
+        if (UNLIKELY((state&(eFlipRequested|eNextFlipPending)) == eNextFlipPending)) {
+            LOGE("eNextFlipPending set but eFlipRequested not set, "
+                 "layer=%d (lcblk=%p), state=%08x",
+                 int(i), layer, int(state));
+            return INVALID_OPERATION;
+        }
+
+        if (UNLIKELY(state&eLocked)) {
+            LOGE("eLocked set when entering lock_layer(), "
+                 "layer=%d (lcblk=%p), state=%08x",
+                 int(i), layer, int(state));
+            return WOULD_BLOCK;
+        }
+
+
+	    if (state & (eFlipRequested | eNextFlipPending | eResizeRequested
+                        | eInvalidSurface))
+        {
+	        int32_t resizeIndex;
+	        Mutex::Autolock _l(lock);
+	            // might block for a very short amount of time
+	            // will never cause the server to block (trylock())
+
+	        goto start_loop_here;
+
+	        // We block the client if:
+	        // eNextFlipPending:  we've used both buffers already, so we need to
+	        //                    wait for one to become availlable.
+	        // eResizeRequested:  the buffer we're going to acquire is being
+	        //                    resized. Block until it is done.
+	        // eFlipRequested && eBusy: the buffer we're going to acquire is
+	        //                    currently in use by the server.
+	        // eInvalidSurface:   this is a special case, we don't block in this
+	        //                    case, we just return an error.
+
+	        while((state & (eNextFlipPending|eInvalidSurface)) ||
+	              (state & ((resizeIndex) ? eResizeBuffer1 : eResizeBuffer0)) ||
+	              ((state & (eFlipRequested|eBusy)) == (eFlipRequested|eBusy)) )
+	        {
+	            if (state & eInvalidSurface)
+	                return NO_MEMORY;
+
+	            if (!blocking)
+	                return WOULD_BLOCK;
+
+                timeout = 0;
+                result = cv.waitRelative(lock, seconds(1));
+	            if (__builtin_expect(result!=NO_ERROR, false)) {
+                    const int newState = layer->swapState;
+                    LOGW(   "lock_layer timed out (is the CPU pegged?) "
+                            "layer=%d, lcblk=%p, state=%08x (was %08x)",
+                            int(i), layer, newState, int(state));
+                    timeout = newState != int(state);
+                }
+
+	        start_loop_here:
+	            state = layer->swapState;
+	            resizeIndex = (state&eIndex) ^ ((state&eFlipRequested)>>1);
+	        }
+
+            LOGW_IF(timeout,
+                    "lock_layer() timed out but didn't appear to need "
+                    "to be locked and we recovered "
+                    "(layer=%d, lcblk=%p, state=%08x)",
+                    int(i), layer, int(state));
+	    }
+
+	    // eFlipRequested is not set and cannot be set by another thread: it's
+	    // safe to use the first buffer without synchronization.
+
+        // Choose the index depending on eFlipRequested.
+        // When it's set, choose the 'other' buffer.
+        index = (state&eIndex) ^ ((state&eFlipRequested)>>1);
+
+	    // make sure this buffer is valid
+	    if (layer->surface[index].bits_offset < 0) {
+	        return status_t(layer->surface[index].bits_offset);
+	    }
+
+        if (inspect) {
+            // we just want to inspect this layer. don't lock it.
+            goto done;
+        }
+
+	    // last thing before we're done, we need to atomically lock the state
+    } while (android_atomic_cmpxchg(state, state|eLocked, &(layer->swapState)));
+
+    VERBOSE("locked layer=%d (lcblk=%p), buffer=%d, state=0x%08x",
+         int(i), layer, int(index), int(state));
+
+    // store the index of the locked buffer (for client use only)
+    layer->flags &= ~eBufferIndex;
+    layer->flags |= ((index << eBufferIndexShift) & eBufferIndex);
+
+done:
+    return index;
+}
+
+uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i)
+{
+    // atomically set eFlipRequested and clear eLocked and optionnaly
+    // set eNextFlipPending if eFlipRequested was already set
+
+    layer_cblk_t * const layer = layers + i;
+    int32_t oldvalue, newvalue;
+    do {
+        oldvalue = layer->swapState;
+            // get current value
+
+        newvalue = oldvalue & ~eLocked;
+            // clear eLocked
+
+        newvalue |= eFlipRequested;
+            // set eFlipRequested
+
+        if (oldvalue & eFlipRequested)
+            newvalue |= eNextFlipPending;
+            // if eFlipRequested was alread set, set eNextFlipPending
+
+    } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState)));
+
+    VERBOSE("request pageflip for layer=%d, buffer=%d, state=0x%08x",
+            int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift),
+            int(newvalue));
+
+    // from this point, the server can kick in at anytime and use the first
+    // buffer, so we cannot use it anymore, and we must use the 'other'
+    // buffer instead (or wait if it is not availlable yet, see lock_layer).
+
+    return newvalue;
+}
+
+void per_client_cblk_t::unlock_layer(size_t i)
+{
+    layer_cblk_t * const layer = layers + i;
+    android_atomic_and(~eLocked, &layer->swapState);
+}
+
+// ---------------------------------------------------------------------------
+
+static inline int compare_type( const layer_state_t& lhs,
+                                const layer_state_t& rhs) {
+    if (lhs.surface < rhs.surface)  return -1;
+    if (lhs.surface > rhs.surface)  return 1;
+    return 0;
+}
+
+SurfaceComposerClient::SurfaceComposerClient()
+{
+    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    if (sm == 0) {
+        _init(0, 0);
+        return;
+    }
+
+    _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));
+}
+
+void SurfaceComposerClient::_init(
+        const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
+{
+    VERBOSE("Creating client %p, conn %p", this, conn.get());
+
+    mSignalServer = 0;
+    mPrebuiltLayerState = 0;
+    mTransactionOpen = 0;
+    mStatus = NO_ERROR;
+    mControl = 0;
+
+    mClient = conn;
+    if (mClient == 0) {
+        mStatus = NO_INIT;
+        return;
+    }
+
+    mClient->getControlBlocks(&mControlMemory);
+    mSignalServer = new SurfaceFlingerSynchro(sm);
+    mControl = static_cast<per_client_cblk_t *>(mControlMemory->pointer());
+}
+
+SurfaceComposerClient::~SurfaceComposerClient()
+{
+    VERBOSE("Destroying client %p, conn %p", this, mClient.get());
+    dispose();
+}
+
+status_t SurfaceComposerClient::initCheck() const
+{
+    return mStatus;
+}
+
+status_t SurfaceComposerClient::validateSurface(
+        per_client_cblk_t const* cblk, Surface const * surface)
+{
+    SurfaceID index = surface->ID();
+    if (cblk == 0) {
+        LOGE("cblk is null (surface id=%d, identity=%u)",
+                index, surface->getIdentity());
+        return NO_INIT;
+    }
+
+    status_t err = cblk->validate(index);
+    if (err != NO_ERROR) {
+        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
+                index, surface->getIdentity(), err, strerror(-err));
+        return err;
+    }
+
+    if (surface->getIdentity() != uint32_t(cblk->layers[index].identity)) {
+        LOGE("using an invalid surface id=%d, identity=%u should be %d",
+                index, surface->getIdentity(), cblk->layers[index].identity);
+        return NO_INIT;
+    }
+
+    return NO_ERROR;
+}
+
+sp<IBinder> SurfaceComposerClient::connection() const
+{
+    return (mClient != 0) ? mClient->asBinder() : 0;
+}
+
+sp<SurfaceComposerClient>
+SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
+{
+    sp<SurfaceComposerClient> client;
+
+    { // scope for lock
+        Mutex::Autolock _l(gLock);
+        client = gActiveConnections.valueFor(conn);
+    }
+
+    if (client == 0) {
+        // Need to make a new client.
+        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        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;
+}
+
+void SurfaceComposerClient::dispose()
+{
+    // this can be called more than once.
+
+    sp<IMemory>                 controlMemory;
+    sp<ISurfaceFlingerClient>   client;
+    sp<IMemoryHeap>             surfaceHeap;
+
+    {
+        Mutex::Autolock _lg(gLock);
+        Mutex::Autolock _lm(mLock);
+
+        delete mSignalServer;
+        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;
+        surfaceHeap = mSurfaceHeap;
+        mControlMemory.clear();
+        mSurfaceHeap.clear();
+        mControl = 0;
+        mStatus = NO_INIT;
+    }
+}
+
+status_t SurfaceComposerClient::getDisplayInfo(
+        DisplayID dpy, DisplayInfo* info)
+{
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+        return BAD_VALUE;
+
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
+
+    info->w              = dcblk->w;
+    info->h              = dcblk->h;
+    info->orientation    = dcblk->orientation;
+    info->xdpi           = dcblk->xdpi;
+    info->ydpi           = dcblk->ydpi;
+    info->fps            = dcblk->fps;
+    info->density        = dcblk->density;
+    return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
+}
+
+ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
+{
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+        return BAD_VALUE;
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
+    return dcblk->w;
+}
+
+ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
+{
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+        return BAD_VALUE;
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
+    return dcblk->h;
+}
+
+ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
+{
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+        return BAD_VALUE;
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    volatile display_cblk_t const * dcblk = cblk->displays + dpy;
+    return dcblk->orientation;
+}
+
+ssize_t SurfaceComposerClient::getNumberOfDisplays()
+{
+    volatile surface_flinger_cblk_t const * cblk = get_cblk();
+    uint32_t connected = cblk->connected;
+    int n = 0;
+    while (connected) {
+        if (connected&1) n++;
+        connected >>= 1;
+    }
+    return n;
+}
+
+sp<Surface> SurfaceComposerClient::createSurface(
+        int pid,
+        DisplayID display,
+        uint32_t w,
+        uint32_t h,
+        PixelFormat format,
+        uint32_t flags)
+{
+    sp<Surface> result;
+    if (mStatus == NO_ERROR) {
+        ISurfaceFlingerClient::surface_data_t data;
+        sp<ISurface> surface = mClient->createSurface(&data, pid,
+                display, w, h, format, flags);
+        if (surface != 0) {
+            if (uint32_t(data.token) < NUM_LAYERS_MAX) {
+                result = new Surface(this, surface, data, w, h, format, flags);
+            }
+        }
+    }
+    return result;
+}
+
+status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
+{
+    if (mStatus != NO_ERROR)
+        return mStatus;
+
+    // it's okay to destroy a surface while a transaction is open,
+    // (transactions really are a client-side concept)
+    // however, this indicates probably a misuse of the API or a bug
+    // in the client code.
+    LOGW_IF(mTransactionOpen,
+         "Destroying surface while a transaction is open. "
+         "Client %p: destroying surface %d, mTransactionOpen=%d",
+         this, sid, mTransactionOpen);
+
+    status_t err = mClient->destroySurface(sid);
+    return err;
+}
+
+status_t SurfaceComposerClient::nextBuffer(Surface* surface,
+                        Surface::SurfaceInfo* info)
+{
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface);
+    if (err != NO_ERROR)
+        return err;
+
+    int32_t backIdx = surface->mBackbufferIndex;
+    layer_cblk_t* const lcblk = &(cblk->layers[index]);
+    const surface_info_t* const front = lcblk->surface + (1-backIdx);
+        info->w      = front->w;
+        info->h      = front->h;
+        info->format = front->format;
+        info->base   = surface->heapBase(1-backIdx);
+        info->bits   = reinterpret_cast<void*>(intptr_t(info->base) + front->bits_offset);
+        info->bpr    = front->bpr;
+
+    return 0;
+}
+
+status_t SurfaceComposerClient::lockSurface(
+        Surface* surface,
+        Surface::SurfaceInfo* other,
+        Region* dirty,
+        bool blocking)
+{
+    Mutex::Autolock _l(surface->getLock());
+
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface);
+    if (err != NO_ERROR)
+        return err;
+
+    int32_t backIdx = cblk->lock_layer(size_t(index),
+            per_client_cblk_t::BLOCKING);
+    if (backIdx >= 0) {
+        surface->mBackbufferIndex = backIdx;
+        layer_cblk_t* const lcblk = &(cblk->layers[index]);
+        const surface_info_t* const back = lcblk->surface + backIdx;
+        const surface_info_t* const front = lcblk->surface + (1-backIdx);
+            other->w      = back->w;
+            other->h      = back->h;
+            other->format = back->format;
+            other->base   = surface->heapBase(backIdx);
+            other->bits   = reinterpret_cast<void*>(intptr_t(other->base) + back->bits_offset);
+            other->bpr    = back->bpr;
+
+        const Rect bounds(other->w, other->h);
+        Region newDirtyRegion;
+
+        if (back->flags & surface_info_t::eBufferDirty) {
+            /* it is safe to write *back here, because we're guaranteed
+             * SurfaceFlinger is not touching it (since it just granted
+             * access to us) */
+            const_cast<surface_info_t*>(back)->flags &=
+                    ~surface_info_t::eBufferDirty;
+
+            // content is meaningless in this case and the whole surface
+            // needs to be redrawn.
+
+            newDirtyRegion.set(bounds);
+            if (dirty) {
+                *dirty = newDirtyRegion;
+            }
+
+            //if (bytesPerPixel(other->format) == 4) {
+            //    android_memset32(
+            //        (uint32_t*)other->bits, 0xFF00FF00, other->h * other->bpr);
+            //} else {
+            //    android_memset16( // fill with green
+            //        (uint16_t*)other->bits, 0x7E0, other->h * other->bpr);
+            //}
+        }
+        else
+        {
+            if (dirty) {
+                dirty->andSelf(Region(bounds));
+                newDirtyRegion = *dirty;
+            } else {
+                newDirtyRegion.set(bounds);
+            }
+
+            Region copyback;
+            if (!(lcblk->flags & eNoCopyBack)) {
+                const Region previousDirtyRegion(surface->dirtyRegion());
+                copyback = previousDirtyRegion.subtract(newDirtyRegion);
+            }
+
+            if (!copyback.isEmpty()) {
+                // copy front to back
+                GGLSurface cb;
+                    cb.version = sizeof(GGLSurface);
+                    cb.width = back->w;
+                    cb.height = back->h;
+                    cb.stride = back->stride;
+                    cb.data = (GGLubyte*)surface->heapBase(backIdx);
+                    cb.data += back->bits_offset;
+                    cb.format = back->format;
+
+                GGLSurface t;
+                    t.version = sizeof(GGLSurface);
+                    t.width = front->w;
+                    t.height = front->h;
+                    t.stride = front->stride;
+                    t.data = (GGLubyte*)surface->heapBase(1-backIdx);
+                    t.data += front->bits_offset;
+                    t.format = front->format;
+
+                //const Region copyback(lcblk->region + 1-backIdx);
+                copyBlt(cb, t, copyback);
+            }
+        }
+
+        // update dirty region
+        surface->setDirtyRegion(newDirtyRegion);
+    }
+    return (backIdx < 0) ? status_t(backIdx) : status_t(NO_ERROR);
+}
+
+void SurfaceComposerClient::_signal_server()
+{
+    mSignalServer->signal();
+}
+
+void SurfaceComposerClient::_send_dirty_region(
+        layer_cblk_t* lcblk, const Region& dirty)
+{
+    const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
+    flat_region_t* flat_region = lcblk->region + index;
+    status_t err = dirty.write(flat_region, sizeof(flat_region_t));
+    if (err < NO_ERROR) {
+        // region doesn't fit, use the bounds
+        const Region reg(dirty.bounds());
+        reg.write(flat_region, sizeof(flat_region_t));
+    }
+}
+
+status_t SurfaceComposerClient::unlockAndPostSurface(Surface* surface)
+{
+    Mutex::Autolock _l(surface->getLock());
+
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface);
+    if (err != NO_ERROR)
+        return err;
+
+    Region dirty(surface->dirtyRegion());
+    const Rect& swapRect(surface->swapRectangle());
+    if (swapRect.isValid()) {
+        dirty.set(swapRect);
+    }
+
+    // transmit the dirty region
+    layer_cblk_t* const lcblk = &(cblk->layers[index]);
+    _send_dirty_region(lcblk, dirty);
+    uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
+    if (!(newstate & eNextFlipPending))
+        _signal_server();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::unlockSurface(Surface* surface)
+{
+    Mutex::Autolock _l(surface->getLock());
+
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface);
+    if (err != NO_ERROR)
+        return err;
+
+    layer_cblk_t* const lcblk = &(cblk->layers[index]);
+    cblk->unlock_layer(size_t(index));
+    return NO_ERROR;
+}
+
+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
+            }
+        }
+    }
+}
+
+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);
+    if (N == 1) {
+        clients[0]->closeTransaction();
+    } else {
+        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        sm->openGlobalTransaction();
+        for (size_t i=0; i<N; i++) {
+            clients[i]->closeTransaction();
+        }
+        sm->closeGlobalTransaction();
+    }
+}
+
+status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    return sm->freezeDisplay(dpy, flags);
+}
+
+status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    return sm->unfreezeDisplay(dpy, flags);
+}
+
+int SurfaceComposerClient::setOrientation(DisplayID dpy, int orientation)
+{
+    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    return sm->setOrientation(dpy, orientation);
+}
+
+status_t SurfaceComposerClient::openTransaction()
+{
+    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()",
+                this, mTransactionOpen);
+        return INVALID_OPERATION;
+    }
+
+    if (mTransactionOpen >= 2) {
+        mTransactionOpen--;
+        return NO_ERROR;
+    }
+
+    mTransactionOpen = 0;
+    const ssize_t count = mStates.size();
+    if (count) {
+        mClient->setState(count, mStates.array());
+        mStates.clear();
+    }
+    return NO_ERROR;
+}
+
+layer_state_t* SurfaceComposerClient::_get_state_l(const sp<Surface>& surface)
+{
+    SurfaceID index = surface->ID();
+    per_client_cblk_t* const cblk = mControl;
+    status_t err = validateSurface(cblk, surface.get());
+    if (err != NO_ERROR)
+        return 0;
+
+    // API usage error, do nothing.
+    if (mTransactionOpen<=0) {
+        LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
+                this, int(index), mTransactionOpen);
+        return 0;
+    }
+
+    // use mPrebuiltLayerState just to find out if we already have it
+    layer_state_t& dummy = *mPrebuiltLayerState;
+    dummy.surface = index;
+    ssize_t i = mStates.indexOf(dummy);
+    if (i < 0) {
+        // we don't have it, add an initialized layer_state to our list
+        i = mStates.add(dummy);
+    }
+    return mStates.editArray() + i;
+}
+
+layer_state_t* SurfaceComposerClient::_lockLayerState(const sp<Surface>& surface)
+{
+    layer_state_t* s;
+    mLock.lock();
+    s = _get_state_l(surface);
+    if (!s) mLock.unlock();
+    return s;
+}
+
+void SurfaceComposerClient::_unlockLayerState()
+{
+    mLock.unlock();
+}
+
+status_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t y)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::ePositionChanged;
+    s->x = x;
+    s->y = y;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eSizeChanged;
+    s->w = w;
+    s->h = h;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eLayerChanged;
+    s->z = z;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::hide(Surface* surface)
+{
+    return setFlags(surface, ISurfaceComposer::eLayerHidden,
+            ISurfaceComposer::eLayerHidden);
+}
+
+status_t SurfaceComposerClient::show(Surface* surface, int32_t)
+{
+    return setFlags(surface, 0, ISurfaceComposer::eLayerHidden);
+}
+
+status_t SurfaceComposerClient::freeze(Surface* surface)
+{
+    return setFlags(surface, ISurfaceComposer::eLayerFrozen,
+            ISurfaceComposer::eLayerFrozen);
+}
+
+status_t SurfaceComposerClient::unfreeze(Surface* surface)
+{
+    return setFlags(surface, 0, ISurfaceComposer::eLayerFrozen);
+}
+
+status_t SurfaceComposerClient::setFlags(Surface* surface,
+        uint32_t flags, uint32_t mask)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eVisibilityChanged;
+    s->flags &= ~mask;
+    s->flags |= (flags & mask);
+    s->mask |= mask;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+
+status_t SurfaceComposerClient::setTransparentRegionHint(
+        Surface* surface, const Region& transparentRegion)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eTransparentRegionChanged;
+    s->transparentRegion = transparentRegion;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eAlphaChanged;
+    s->alpha = alpha;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setMatrix(
+        Surface* surface,
+        float dsdx, float dtdx,
+        float dsdy, float dtdy )
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eMatrixChanged;
+    layer_state_t::matrix22_t matrix;
+    matrix.dsdx = dsdx;
+    matrix.dtdx = dtdx;
+    matrix.dsdy = dsdy;
+    matrix.dtdy = dtdy;
+    s->matrix = matrix;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+status_t SurfaceComposerClient::setFreezeTint(Surface* surface, uint32_t tint)
+{
+    layer_state_t* s = _lockLayerState(surface);
+    if (!s) return BAD_INDEX;
+    s->what |= ISurfaceComposer::eFreezeTintChanged;
+    s->tint = tint;
+    _unlockLayerState();
+    return NO_ERROR;
+}
+
+}; // namespace android
+
diff --git a/libs/ui/SurfaceFlingerSynchro.cpp b/libs/ui/SurfaceFlingerSynchro.cpp
new file mode 100644
index 0000000..5cd9755
--- /dev/null
+++ b/libs/ui/SurfaceFlingerSynchro.cpp
@@ -0,0 +1,123 @@
+/*
+ * 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 "SurfaceFlingerSynchro"
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+
+#include <private/ui/SurfaceFlingerSynchro.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+SurfaceFlingerSynchro::Barrier::Barrier()
+    : state(CLOSED) { 
+}
+
+SurfaceFlingerSynchro::Barrier::~Barrier() { 
+}
+
+void SurfaceFlingerSynchro::Barrier::open() {
+    asm volatile ("":::"memory");
+    Mutex::Autolock _l(lock);
+    state = OPENED;
+    cv.broadcast();
+}
+
+void SurfaceFlingerSynchro::Barrier::close() {
+    Mutex::Autolock _l(lock);
+    state = CLOSED;
+}
+
+void SurfaceFlingerSynchro::Barrier::waitAndClose() 
+{
+    Mutex::Autolock _l(lock);
+    while (state == CLOSED) {
+        // we're about to wait, flush the binder command buffer
+        IPCThreadState::self()->flushCommands();
+        cv.wait(lock);
+    }
+    state = CLOSED;
+}
+
+status_t SurfaceFlingerSynchro::Barrier::waitAndClose(nsecs_t timeout) 
+{
+    Mutex::Autolock _l(lock);
+    while (state == CLOSED) {
+        // we're about to wait, flush the binder command buffer
+        IPCThreadState::self()->flushCommands();
+        int err = cv.waitRelative(lock, timeout);
+        if (err != 0)
+            return err;
+    }
+    state = CLOSED;
+    return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+
+SurfaceFlingerSynchro::SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger)
+    : mSurfaceComposer(flinger)
+{
+}
+
+SurfaceFlingerSynchro::SurfaceFlingerSynchro()
+{
+}
+
+SurfaceFlingerSynchro::~SurfaceFlingerSynchro()
+{
+}
+
+status_t SurfaceFlingerSynchro::signal()
+{
+    mSurfaceComposer->signal();
+    return NO_ERROR;
+}
+
+status_t SurfaceFlingerSynchro::wait()
+{
+    mBarrier.waitAndClose();
+    return NO_ERROR;
+}
+
+status_t SurfaceFlingerSynchro::wait(nsecs_t timeout)
+{
+    if (timeout == 0)
+        return SurfaceFlingerSynchro::wait();
+    return mBarrier.waitAndClose(timeout);
+}
+
+void SurfaceFlingerSynchro::open()
+{
+    mBarrier.open();
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/libs/ui/Time.cpp b/libs/ui/Time.cpp
new file mode 100644
index 0000000..c98667f
--- /dev/null
+++ b/libs/ui/Time.cpp
@@ -0,0 +1,199 @@
+#include <utils/TimeUtils.h>
+#include <stdio.h>
+#include <cutils/tztime.h>
+
+namespace android {
+
+static void
+dump(const Time& t)
+{
+    #ifdef HAVE_TM_GMTOFF
+        long tm_gmtoff = t.t.tm_gmtoff;
+    #else
+        long tm_gmtoff = 0;
+    #endif
+    printf("%04d-%02d-%02d %02d:%02d:%02d (%d,%ld,%d,%d)\n",
+            t.t.tm_year+1900, t.t.tm_mon+1, t.t.tm_mday,
+            t.t.tm_hour, t.t.tm_min, t.t.tm_sec,
+            t.t.tm_isdst, tm_gmtoff, t.t.tm_wday, t.t.tm_yday);
+}
+
+Time::Time()
+{
+    t.tm_sec = 0;
+    t.tm_min = 0;
+    t.tm_hour = 0;
+    t.tm_mday = 0;
+    t.tm_mon = 0;
+    t.tm_year = 0;
+    t.tm_wday = 0;
+    t.tm_yday = 0;
+    t.tm_isdst = -1; // we don't know, so let the C library determine
+    #ifdef HAVE_TM_GMTOFF
+        t.tm_gmtoff = 0;
+    #endif
+}
+
+
+#define COMPARE_FIELD(field) do { \
+        int diff = a.t.field - b.t.field; \
+        if (diff != 0) return diff; \
+    } while(0)
+
+int
+Time::compare(Time& a, Time& b)
+{
+    if (0 == strcmp(a.timezone, b.timezone)) {
+        // if the timezones are the same, we can easily compare the two
+        // times.  Otherwise, convert to milliseconds and compare that.
+        // This requires that object be normalized.
+        COMPARE_FIELD(tm_year);
+        COMPARE_FIELD(tm_mon);
+        COMPARE_FIELD(tm_mday);
+        COMPARE_FIELD(tm_hour);
+        COMPARE_FIELD(tm_min);
+        COMPARE_FIELD(tm_sec);
+        return 0;
+    } else {
+        int64_t am = a.toMillis(false /* use isDst */);
+        int64_t bm = b.toMillis(false /* use isDst */);
+        int64_t diff = am-bm;
+        return (diff < 0) ? -1 : ((diff > 0) ? 1 : 0);
+    }
+}
+
+static const int DAYS_PER_MONTH[] = {
+                        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+                    };
+
+static inline int days_this_month(int year, int month)
+{
+    int n = DAYS_PER_MONTH[month];
+    if (n != 28) {
+        return n;
+    } else {
+        int y = year;
+        return ((y%4)==0&&((y%100)!=0||(y%400)==0)) ? 29 : 28;
+    }
+}
+
+void 
+Time::switchTimezone(const char* timezone)
+{
+    time_t seconds = mktime_tz(&(this->t), this->timezone);
+    localtime_tz(&seconds, &(this->t), timezone);
+}
+
+String8 
+Time::format(const char *format) const
+{
+    char buf[257];
+    int n = strftime(buf, 257, format, &(this->t));
+    if (n > 0) {
+        return String8(buf);
+    } else {
+        return String8();
+    }
+}
+
+static inline short
+tochar(int n)
+{
+    return (n >= 0 && n <= 9) ? ('0'+n) : ' ';
+}
+
+static inline short
+next_char(int *m, int k)
+{
+    int n = *m / k;
+    *m = *m % k;
+    return tochar(n);
+}
+
+void
+Time::format2445(short* buf, bool hasTime) const
+{
+    int n;
+
+    n = t.tm_year+1900;
+    buf[0] = next_char(&n, 1000);
+    buf[1] = next_char(&n, 100);
+    buf[2] = next_char(&n, 10);
+    buf[3] = tochar(n);
+
+    n = t.tm_mon+1;
+    buf[4] = next_char(&n, 10);
+    buf[5] = tochar(n);
+
+    n = t.tm_mday;
+    buf[6] = next_char(&n, 10);
+    buf[7] = tochar(n);
+
+    if (hasTime) {
+      buf[8] = 'T';
+
+      n = t.tm_hour;
+      buf[9] = next_char(&n, 10);
+      buf[10] = tochar(n);
+      
+      n = t.tm_min;
+      buf[11] = next_char(&n, 10);
+      buf[12] = tochar(n);
+      
+      n = t.tm_sec;
+      buf[13] = next_char(&n, 10);
+      buf[14] = tochar(n);
+      bool inUtc = strcmp("UTC", timezone) == 0;
+      if (inUtc) {
+          buf[15] = 'Z';
+      }
+    }
+}
+
+String8 
+Time::toString() const
+{
+    String8 str;
+    char* s = str.lockBuffer(150);
+    #ifdef HAVE_TM_GMTOFF
+        long tm_gmtoff = t.tm_gmtoff;
+    #else
+        long tm_gmtoff = 0;
+    #endif
+    sprintf(s, "%04d%02d%02dT%02d%02d%02d%s(%d,%d,%ld,%d,%d)", 
+            t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min,
+            t.tm_sec, timezone, t.tm_wday, t.tm_yday, tm_gmtoff, t.tm_isdst,
+            (int)(((Time*)this)->toMillis(false /* use isDst */)/1000));
+    str.unlockBuffer();
+    return str;
+}
+
+void 
+Time::setToNow()
+{
+    time_t seconds;
+    time(&seconds);
+    localtime_tz(&seconds, &(this->t), this->timezone);
+}
+
+int64_t 
+Time::toMillis(bool ignoreDst)
+{
+    if (ignoreDst) {
+        this->t.tm_isdst = -1;
+    }
+    int64_t r = mktime_tz(&(this->t), this->timezone);
+    if (r == -1)
+        return -1;
+    return r * 1000;
+}
+
+void 
+Time::set(int64_t millis)
+{
+    time_t seconds = millis / 1000;
+    localtime_tz(&seconds, &(this->t), this->timezone);
+}
+
+}; // namespace android
+
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
new file mode 100644
index 0000000..4a68dc1
--- /dev/null
+++ b/libs/utils/Android.mk
@@ -0,0 +1,148 @@
+# 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)
+
+# libutils is a little unique: It's built twice, once for the host
+# and once for the device.
+
+commonSources:= \
+	Asset.cpp \
+	AssetDir.cpp \
+	AssetManager.cpp \
+	BufferedTextOutput.cpp \
+	CallStack.cpp \
+	Debug.cpp \
+	FileMap.cpp \
+	RefBase.cpp \
+	ResourceTypes.cpp \
+	SharedBuffer.cpp \
+	Static.cpp \
+	StopWatch.cpp \
+	String8.cpp \
+	String16.cpp \
+	SystemClock.cpp \
+	TextOutput.cpp \
+	Threads.cpp \
+	TimerProbe.cpp \
+	Timers.cpp \
+	VectorImpl.cpp \
+    ZipFileCRO.cpp \
+	ZipFileRO.cpp \
+	ZipUtils.cpp \
+	misc.cpp \
+	ported.cpp \
+	LogSocket.cpp
+
+#
+# The cpp files listed here do not belong in the device
+# build.  Consult with the swetland before even thinking about
+# putting them in commonSources.
+#
+# They're used by the simulator runtime and by host-side tools like
+# aapt and the simulator front-end.
+#
+hostSources:= \
+	InetAddress.cpp \
+	Pipe.cpp \
+	Socket.cpp \
+	ZipEntry.cpp \
+	ZipFile.cpp
+
+# For the host
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(commonSources) $(hostSources)
+
+ifeq ($(HOST_OS),linux)
+# Use the futex based mutex and condition variable
+# implementation from android-arm because it's shared mem safe
+	LOCAL_SRC_FILES += \
+		futex_synchro.c \
+		executablepath_linux.cpp
+endif
+ifeq ($(HOST_OS),darwin)
+	LOCAL_SRC_FILES += \
+		executablepath_darwin.cpp
+endif
+
+LOCAL_MODULE:= libutils
+
+LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
+LOCAL_C_INCLUDES += external/zlib
+
+ifeq ($(HOST_OS),windows)
+ifeq ($(strip $(USE_CYGWIN),),)
+# Under MinGW, ctype.h doesn't need multi-byte support
+LOCAL_CFLAGS += -DMB_CUR_MAX=1
+endif
+endif
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+
+# we have the common sources, plus some device-specific stuff
+LOCAL_SRC_FILES:= \
+	$(commonSources) \
+	Binder.cpp \
+	BpBinder.cpp \
+	IInterface.cpp \
+	IMemory.cpp \
+	IPCThreadState.cpp \
+	MemoryDealer.cpp \
+    MemoryBase.cpp \
+    MemoryHeapBase.cpp \
+    MemoryHeapPmem.cpp \
+	Parcel.cpp \
+	ProcessState.cpp \
+	IPermissionController.cpp \
+	IServiceManager.cpp \
+	Unicode.cpp
+
+ifeq ($(TARGET_SIMULATOR),true)
+LOCAL_SRC_FILES += $(hostSources)
+endif
+
+ifeq ($(TARGET_OS),linux)
+# Use the futex based mutex and condition variable
+# implementation from android-arm because it's shared mem safe
+LOCAL_SRC_FILES += futex_synchro.c
+LOCAL_LDLIBS += -lrt -ldl
+endif
+
+LOCAL_C_INCLUDES += \
+		external/zlib \
+		external/icu4c/common
+LOCAL_LDLIBS += -lpthread
+
+LOCAL_SHARED_LIBRARIES := \
+	libz \
+	liblog \
+	libcutils
+
+LOCAL_MODULE:= libutils
+
+#LOCAL_CFLAGS+=
+#LOCAL_LDFLAGS:=
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
new file mode 100644
index 0000000..91203dd
--- /dev/null
+++ b/libs/utils/Asset.cpp
@@ -0,0 +1,813 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Provide access to a read-only asset.
+//
+
+#define LOG_TAG "asset"
+//#define NDEBUG 0
+
+#include <utils/Asset.h>
+#include <utils/Atomic.h>
+#include <utils/FileMap.h>
+#include <utils/ZipUtils.h>
+#include <utils/ZipFileRO.h>
+#include <utils/Log.h>
+
+#include <string.h>
+#include <memory.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+static volatile int32_t gCount = 0;
+
+int32_t Asset::getGlobalCount()
+{
+    return gCount;
+}
+
+Asset::Asset(void)
+    : mAccessMode(ACCESS_UNKNOWN)
+{
+    int count = android_atomic_inc(&gCount)+1;
+    //LOGI("Creating Asset %p #%d\n", this, count);
+}
+
+Asset::~Asset(void)
+{
+    int count = android_atomic_dec(&gCount);
+    //LOGI("Destroying Asset in %p #%d\n", this, count);
+}
+
+/*
+ * Create a new Asset from a file on disk.  There is a fair chance that
+ * the file doesn't actually exist.
+ *
+ * We can use "mode" to decide how we want to go about it.
+ */
+/*static*/ Asset* Asset::createFromFile(const char* fileName, AccessMode mode)
+{
+    _FileAsset* pAsset;
+    status_t result;
+    off_t length;
+    int fd;
+
+    fd = open(fileName, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return NULL;
+
+    /*
+     * Under Linux, the lseek fails if we actually opened a directory.  To
+     * be correct we should test the file type explicitly, but since we
+     * always open things read-only it doesn't really matter, so there's
+     * no value in incurring the extra overhead of an fstat() call.
+     */
+    length = lseek(fd, 0, SEEK_END);
+    if (length < 0) {
+        ::close(fd);
+        return NULL;
+    }
+    (void) lseek(fd, 0, SEEK_SET);
+
+    pAsset = new _FileAsset;
+    result = pAsset->openChunk(fileName, fd, 0, length);
+    if (result != NO_ERROR) {
+        delete pAsset;
+        return NULL;
+    }
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+
+/*
+ * Create a new Asset from a compressed file on disk.  There is a fair chance
+ * that the file doesn't actually exist.
+ *
+ * We currently support gzip files.  We might want to handle .bz2 someday.
+ */
+/*static*/ Asset* Asset::createFromCompressedFile(const char* fileName,
+    AccessMode mode)
+{
+    _CompressedAsset* pAsset;
+    status_t result;
+    off_t fileLen;
+    bool scanResult;
+    long offset;
+    int method;
+    long uncompressedLen, compressedLen;
+    int fd;
+
+    fd = open(fileName, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return NULL;
+
+    fileLen = lseek(fd, 0, SEEK_END);
+    if (fileLen < 0) {
+        ::close(fd);
+        return NULL;
+    }
+    (void) lseek(fd, 0, SEEK_SET);
+
+    /* want buffered I/O for the file scan; must dup so fclose() is safe */
+    FILE* fp = fdopen(dup(fd), "rb");
+    if (fp == NULL) {
+        ::close(fd);
+        return NULL;
+    }
+
+    unsigned long crc32;
+    scanResult = ZipUtils::examineGzip(fp, &method, &uncompressedLen,
+                    &compressedLen, &crc32);
+    offset = ftell(fp);
+    fclose(fp);
+    if (!scanResult) {
+        LOGD("File '%s' is not in gzip format\n", fileName);
+        ::close(fd);
+        return NULL;
+    }
+
+    pAsset = new _CompressedAsset;
+    result = pAsset->openChunk(fd, offset, method, uncompressedLen,
+                compressedLen);
+    if (result != NO_ERROR) {
+        delete pAsset;
+        return NULL;
+    }
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+
+#if 0
+/*
+ * Create a new Asset from part of an open file.
+ */
+/*static*/ Asset* Asset::createFromFileSegment(int fd, off_t offset,
+    size_t length, AccessMode mode)
+{
+    _FileAsset* pAsset;
+    status_t result;
+
+    pAsset = new _FileAsset;
+    result = pAsset->openChunk(NULL, fd, offset, length);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+/*
+ * Create a new Asset from compressed data in an open file.
+ */
+/*static*/ Asset* Asset::createFromCompressedData(int fd, off_t offset,
+    int compressionMethod, size_t uncompressedLen, size_t compressedLen,
+    AccessMode mode)
+{
+    _CompressedAsset* pAsset;
+    status_t result;
+
+    pAsset = new _CompressedAsset;
+    result = pAsset->openChunk(fd, offset, compressionMethod,
+                uncompressedLen, compressedLen);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+#endif
+
+/*
+ * Create a new Asset from a memory mapping.
+ */
+/*static*/ Asset* Asset::createFromUncompressedMap(FileMap* dataMap,
+    AccessMode mode)
+{
+    _FileAsset* pAsset;
+    status_t result;
+
+    pAsset = new _FileAsset;
+    result = pAsset->openChunk(dataMap);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+/*
+ * Create a new Asset from compressed data in a memory mapping.
+ */
+/*static*/ Asset* Asset::createFromCompressedMap(FileMap* dataMap,
+    int method, size_t uncompressedLen, AccessMode mode)
+{
+    _CompressedAsset* pAsset;
+    status_t result;
+
+    pAsset = new _CompressedAsset;
+    result = pAsset->openChunk(dataMap, method, uncompressedLen);
+    if (result != NO_ERROR)
+        return NULL;
+
+    pAsset->mAccessMode = mode;
+    return pAsset;
+}
+
+
+/*
+ * Do generic seek() housekeeping.  Pass in the offset/whence values from
+ * the seek request, along with the current chunk offset and the chunk
+ * length.
+ *
+ * Returns the new chunk offset, or -1 if the seek is illegal.
+ */
+off_t Asset::handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn)
+{
+    off_t newOffset;
+
+    switch (whence) {
+    case SEEK_SET:
+        newOffset = offset;
+        break;
+    case SEEK_CUR:
+        newOffset = curPosn + offset;
+        break;
+    case SEEK_END:
+        newOffset = maxPosn + offset;
+        break;
+    default:
+        LOGW("unexpected whence %d\n", whence);
+        // this was happening due to an off_t size mismatch
+        assert(false);
+        return (off_t) -1;
+    }
+
+    if (newOffset < 0 || newOffset > maxPosn) {
+        LOGW("seek out of range: want %ld, end=%ld\n",
+            (long) newOffset, (long) maxPosn);
+        return (off_t) -1;
+    }
+
+    return newOffset;
+}
+
+
+/*
+ * ===========================================================================
+ *      _FileAsset
+ * ===========================================================================
+ */
+
+/*
+ * Constructor.
+ */
+_FileAsset::_FileAsset(void)
+    : mStart(0), mLength(0), mOffset(0), mFp(NULL), mFileName(NULL), mMap(NULL), mBuf(NULL)
+{
+}
+
+/*
+ * Destructor.  Release resources.
+ */
+_FileAsset::~_FileAsset(void)
+{
+    close();
+}
+
+/*
+ * Operate on a chunk of an uncompressed file.
+ *
+ * Zero-length chunks are allowed.
+ */
+status_t _FileAsset::openChunk(const char* fileName, int fd, off_t offset, size_t length)
+{
+    assert(mFp == NULL);    // no reopen
+    assert(mMap == NULL);
+    assert(fd >= 0);
+    assert(offset >= 0);
+
+    /*
+     * Seek to end to get file length.
+     */
+    off_t fileLength;
+    fileLength = lseek(fd, 0, SEEK_END);
+    if (fileLength == (off_t) -1) {
+        // probably a bad file descriptor
+        LOGD("failed lseek (errno=%d)\n", errno);
+        return UNKNOWN_ERROR;
+    }
+
+    if ((off_t) (offset + length) > fileLength) {
+        LOGD("start (%ld) + len (%ld) > end (%ld)\n",
+            (long) offset, (long) length, (long) fileLength);
+        return BAD_INDEX;
+    }
+
+    /* after fdopen, the fd will be closed on fclose() */
+    mFp = fdopen(fd, "rb");
+    if (mFp == NULL)
+        return UNKNOWN_ERROR;
+
+    mStart = offset;
+    mLength = length;
+    assert(mOffset == 0);
+
+    /* seek the FILE* to the start of chunk */
+    if (fseek(mFp, mStart, SEEK_SET) != 0) {
+        assert(false);
+    }
+
+    mFileName = fileName != NULL ? strdup(fileName) : NULL;
+    
+    return NO_ERROR;
+}
+
+/*
+ * Create the chunk from the map.
+ */
+status_t _FileAsset::openChunk(FileMap* dataMap)
+{
+    assert(mFp == NULL);    // no reopen
+    assert(mMap == NULL);
+    assert(dataMap != NULL);
+
+    mMap = dataMap;
+    mStart = -1;            // not used
+    mLength = dataMap->getDataLength();
+    assert(mOffset == 0);
+
+    return NO_ERROR;
+}
+
+/*
+ * Read a chunk of data.
+ */
+ssize_t _FileAsset::read(void* buf, size_t count)
+{
+    size_t maxLen;
+    size_t actual;
+
+    assert(mOffset >= 0 && mOffset <= mLength);
+
+    if (getAccessMode() == ACCESS_BUFFER) {
+        /*
+         * On first access, read or map the entire file.  The caller has
+         * requested buffer access, either because they're going to be
+         * using the buffer or because what they're doing has appropriate
+         * performance needs and access patterns.
+         */
+        if (mBuf == NULL)
+            getBuffer(false);
+    }
+
+    /* adjust count if we're near EOF */
+    maxLen = mLength - mOffset;
+    if (count > maxLen)
+        count = maxLen;
+
+    if (!count)
+        return 0;
+
+    if (mMap != NULL) {
+        /* copy from mapped area */
+        //printf("map read\n");
+        memcpy(buf, (char*)mMap->getDataPtr() + mOffset, count);
+        actual = count;
+    } else if (mBuf != NULL) {
+        /* copy from buffer */
+        //printf("buf read\n");
+        memcpy(buf, (char*)mBuf + mOffset, count);
+        actual = count;
+    } else {
+        /* read from the file */
+        //printf("file read\n");
+        if (ftell(mFp) != mStart + mOffset) {
+            LOGE("Hosed: %ld != %ld+%ld\n",
+                ftell(mFp), (long) mStart, (long) mOffset);
+            assert(false);
+        }
+
+        /*
+         * This returns 0 on error or eof.  We need to use ferror() or feof()
+         * to tell the difference, but we don't currently have those on the
+         * device.  However, we know how much data is *supposed* to be in the
+         * file, so if we don't read the full amount we know something is
+         * hosed.
+         */
+        actual = fread(buf, 1, count, mFp);
+        if (actual == 0)        // something failed -- I/O error?
+            return -1;
+
+        assert(actual == count);
+    }
+
+    mOffset += actual;
+    return actual;
+}
+
+/*
+ * Seek to a new position.
+ */
+off_t _FileAsset::seek(off_t offset, int whence)
+{
+    off_t newPosn;
+    long actualOffset;
+
+    // compute new position within chunk
+    newPosn = handleSeek(offset, whence, mOffset, mLength);
+    if (newPosn == (off_t) -1)
+        return newPosn;
+
+    actualOffset = (long) (mStart + newPosn);
+
+    if (mFp != NULL) {
+        if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)
+            return (off_t) -1;
+    }
+
+    mOffset = actualOffset - mStart;
+    return mOffset;
+}
+
+/*
+ * Close the asset.
+ */
+void _FileAsset::close(void)
+{
+    if (mMap != NULL) {
+        mMap->release();
+        mMap = NULL;
+    }
+    if (mBuf != NULL) {
+        delete[] mBuf;
+        mBuf = NULL;
+    }
+
+    if (mFileName != NULL) {
+        free(mFileName);
+        mFileName = NULL;
+    }
+    
+    if (mFp != NULL) {
+        // can only be NULL when called from destructor
+        // (otherwise we would never return this object)
+        fclose(mFp);
+        mFp = NULL;
+    }
+}
+
+/*
+ * Return a read-only pointer to a buffer.
+ *
+ * We can either read the whole thing in or map the relevant piece of
+ * the source file.  Ideally a map would be established at a higher
+ * level and we'd be using a different object, but we didn't, so we
+ * deal with it here.
+ */
+const void* _FileAsset::getBuffer(bool wordAligned)
+{
+    /* subsequent requests just use what we did previously */
+    if (mBuf != NULL)
+        return mBuf;
+    if (mMap != NULL) {
+        if (!wordAligned) {
+            return  mMap->getDataPtr();
+        }
+        return ensureAlignment(mMap);
+    }
+
+    assert(mFp != NULL);
+
+    if (mLength < kReadVsMapThreshold) {
+        unsigned char* buf;
+        long allocLen;
+
+        /* zero-length files are allowed; not sure about zero-len allocs */
+        /* (works fine with gcc + x86linux) */
+        allocLen = mLength;
+        if (mLength == 0)
+            allocLen = 1;
+
+        buf = new unsigned char[allocLen];
+        if (buf == NULL) {
+            LOGE("alloc of %ld bytes failed\n", (long) allocLen);
+            return NULL;
+        }
+
+        LOGV("Asset %p allocating buffer size %d (smaller than threshold)", this, (int)allocLen);
+        if (mLength > 0) {
+            long oldPosn = ftell(mFp);
+            fseek(mFp, mStart, SEEK_SET);
+            if (fread(buf, 1, mLength, mFp) != (size_t) mLength) {
+                LOGE("failed reading %ld bytes\n", (long) mLength);
+                delete[] buf;
+                return NULL;
+            }
+            fseek(mFp, oldPosn, SEEK_SET);
+        }
+
+        LOGV(" getBuffer: loaded into buffer\n");
+
+        mBuf = buf;
+        return mBuf;
+    } else {
+        FileMap* map;
+
+        map = new FileMap;
+        if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) {
+            map->release();
+            return NULL;
+        }
+
+        LOGV(" getBuffer: mapped\n");
+
+        mMap = map;
+        if (!wordAligned) {
+            return  mMap->getDataPtr();
+        }
+        return ensureAlignment(mMap);
+    }
+}
+
+int _FileAsset::openFileDescriptor(off_t* outStart, off_t* outLength) const
+{
+    if (mMap != NULL) {
+        const char* fname = mMap->getFileName();
+        if (fname == NULL) {
+            fname = mFileName;
+        }
+        if (fname == NULL) {
+            return -1;
+        }
+        *outStart = mMap->getDataOffset();
+        *outLength = mMap->getDataLength();
+        return open(fname, O_RDONLY | O_BINARY);
+    }
+    if (mFileName == NULL) {
+        return -1;
+    }
+    *outStart = mStart;
+    *outLength = mLength;
+    return open(mFileName, O_RDONLY | O_BINARY);
+}
+
+const void* _FileAsset::ensureAlignment(FileMap* map)
+{
+    void* data = map->getDataPtr();
+    if ((((size_t)data)&0x3) == 0) {
+        // We can return this directly if it is aligned on a word
+        // boundary.
+        return data;
+    }
+    // If not aligned on a word boundary, then we need to copy it into
+    // our own buffer.
+    LOGV("Copying FileAsset %p to buffer size %d to make it aligned.", this, (int)mLength);
+    unsigned char* buf = new unsigned char[mLength];
+    if (buf == NULL) {
+        LOGE("alloc of %ld bytes failed\n", (long) mLength);
+        return NULL;
+    }
+    memcpy(buf, data, mLength);
+    mBuf = buf;
+    return buf;
+}
+
+/*
+ * ===========================================================================
+ *      _CompressedAsset
+ * ===========================================================================
+ */
+
+/*
+ * Constructor.
+ */
+_CompressedAsset::_CompressedAsset(void)
+    : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0),
+      mMap(NULL), mFd(-1), mBuf(NULL)
+{
+}
+
+/*
+ * Destructor.  Release resources.
+ */
+_CompressedAsset::~_CompressedAsset(void)
+{
+    close();
+}
+
+/*
+ * Open a chunk of compressed data inside a file.
+ *
+ * This currently just sets up some values and returns.  On the first
+ * read, we expand the entire file into a buffer and return data from it.
+ */
+status_t _CompressedAsset::openChunk(int fd, off_t offset,
+    int compressionMethod, size_t uncompressedLen, size_t compressedLen)
+{
+    assert(mFd < 0);        // no re-open
+    assert(mMap == NULL);
+    assert(fd >= 0);
+    assert(offset >= 0);
+    assert(compressedLen > 0);
+
+    if (compressionMethod != ZipFileRO::kCompressDeflated) {
+        assert(false);
+        return UNKNOWN_ERROR;
+    }
+
+    mStart = offset;
+    mCompressedLen = compressedLen;
+    mUncompressedLen = uncompressedLen;
+    assert(mOffset == 0);
+    mFd = fd;
+    assert(mBuf == NULL);
+
+    return NO_ERROR;
+}
+
+/*
+ * Open a chunk of compressed data in a mapped region.
+ *
+ * Nothing is expanded until the first read call.
+ */
+status_t _CompressedAsset::openChunk(FileMap* dataMap, int compressionMethod,
+    size_t uncompressedLen)
+{
+    assert(mFd < 0);        // no re-open
+    assert(mMap == NULL);
+    assert(dataMap != NULL);
+
+    if (compressionMethod != ZipFileRO::kCompressDeflated) {
+        assert(false);
+        return UNKNOWN_ERROR;
+    }
+
+    mMap = dataMap;
+    mStart = -1;        // not used
+    mCompressedLen = dataMap->getDataLength();
+    mUncompressedLen = uncompressedLen;
+    assert(mOffset == 0);
+
+    return NO_ERROR;
+}
+
+/*
+ * Read data from a chunk of compressed data.
+ *
+ * [For now, that's just copying data out of a buffer.]
+ */
+ssize_t _CompressedAsset::read(void* buf, size_t count)
+{
+    size_t maxLen;
+    size_t actual;
+
+    assert(mOffset >= 0 && mOffset <= mUncompressedLen);
+
+    // TODO: if mAccessMode == ACCESS_STREAMING, use zlib more cleverly
+
+    if (mBuf == NULL) {
+        if (getBuffer(false) == NULL)
+            return -1;
+    }
+    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;
+}
+
+/*
+ * Handle a seek request.
+ *
+ * If we're working in a streaming mode, this is going to be fairly
+ * expensive, because it requires plowing through a bunch of compressed
+ * data.
+ */
+off_t _CompressedAsset::seek(off_t offset, int whence)
+{
+    off_t newPosn;
+
+    // compute new position within chunk
+    newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
+    if (newPosn == (off_t) -1)
+        return newPosn;
+
+    mOffset = newPosn;
+    return mOffset;
+}
+
+/*
+ * Close the asset.
+ */
+void _CompressedAsset::close(void)
+{
+    if (mMap != NULL) {
+        mMap->release();
+        mMap = NULL;
+    }
+    if (mBuf != NULL) {
+        delete[] mBuf;
+        mBuf = NULL;
+    }
+
+    if (mFd > 0) {
+        ::close(mFd);
+        mFd = -1;
+    }
+}
+
+/*
+ * Get a pointer to a read-only buffer of data.
+ *
+ * The first time this is called, we expand the compressed data into a
+ * buffer.
+ */
+const void* _CompressedAsset::getBuffer(bool wordAligned)
+{
+    unsigned char* buf = NULL;
+
+    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.
+     */
+    buf = new unsigned char[mUncompressedLen];
+    if (buf == NULL) {
+        LOGW("alloc %ld bytes failed\n", (long) mUncompressedLen);
+        goto bail;
+    }
+
+    if (mMap != NULL) {
+        if (!ZipFileRO::inflateBuffer(buf, mMap->getDataPtr(),
+                mUncompressedLen, mCompressedLen))
+            goto bail;
+    } else {
+        assert(mFd >= 0);
+
+        /*
+         * Seek to the start of the compressed data.
+         */
+        if (lseek(mFd, mStart, SEEK_SET) != mStart)
+            goto bail;
+
+        /*
+         * Expand the data into it.
+         */
+        if (!ZipUtils::inflateToBuffer(mFd, buf, mUncompressedLen,
+                mCompressedLen))
+            goto bail;
+    }
+
+    /* success! */
+    mBuf = buf;
+    buf = NULL;
+
+bail:
+    delete[] buf;
+    return mBuf;
+}
+
diff --git a/libs/utils/AssetDir.cpp b/libs/utils/AssetDir.cpp
new file mode 100644
index 0000000..c5f664e
--- /dev/null
+++ b/libs/utils/AssetDir.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Provide access to a virtual directory in "asset space".  Most of the
+// implementation is in the header file or in friend functions in
+// AssetManager.
+//
+#include <utils/AssetDir.h>
+
+using namespace android;
+
+
+/*
+ * Find a matching entry in a vector of FileInfo.  Because it's sorted, we
+ * can use a binary search.
+ *
+ * Assumes the vector is sorted in ascending order.
+ */
+/*static*/ int AssetDir::FileInfo::findEntry(const SortedVector<FileInfo>* pVector,
+    const String8& fileName)
+{
+    FileInfo tmpInfo;
+
+    tmpInfo.setFileName(fileName);
+    return pVector->indexOf(tmpInfo);
+
+#if 0  // don't need this after all (uses 1/2 compares of SortedVector though)
+    int lo, hi, cur;
+
+    lo = 0;
+    hi = pVector->size() -1;
+    while (lo <= hi) {
+        int cmp;
+
+        cur = (hi + lo) / 2;
+        cmp = strcmp(pVector->itemAt(cur).getFileName(), fileName);
+        if (cmp == 0) {
+            /* match, bail */
+            return cur;
+        } else if (cmp < 0) {
+            /* too low */
+            lo = cur + 1;
+        } else {
+            /* too high */
+            hi = cur -1;
+        }
+    }
+
+    return -1;
+#endif
+}
+
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
new file mode 100644
index 0000000..447b801
--- /dev/null
+++ b/libs/utils/AssetManager.cpp
@@ -0,0 +1,1637 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Provide access to read-only assets.
+//
+
+#define LOG_TAG "asset"
+//#define LOG_NDEBUG 0
+
+#include <utils/AssetManager.h>
+#include <utils/AssetDir.h>
+#include <utils/Asset.h>
+#include <utils/Atomic.h>
+#include <utils/String8.h>
+#include <utils/ResourceTypes.h>
+#include <utils/String8.h>
+#include <utils/ZipFileRO.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <utils/threads.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Names for default app, locale, and vendor.  We might want to change
+ * these to be an actual locale, e.g. always use en-US as the default.
+ */
+static const char* kDefaultLocale = "default";
+static const char* kDefaultVendor = "default";
+static const char* kAssetsRoot = "assets";
+static const char* kAppZipName = NULL; //"classes.jar";
+static const char* kSystemAssets = "framework/framework-res.apk";
+
+static const char* kExcludeExtension = ".EXCLUDE";
+
+static Asset* const kExcludedAsset = (Asset*) 0xd000000d;
+
+static volatile int32_t gCount = 0;
+
+
+/*
+ * ===========================================================================
+ *      AssetManager
+ * ===========================================================================
+ */
+
+int32_t AssetManager::getGlobalCount()
+{
+    return gCount;
+}
+
+AssetManager::AssetManager(CacheMode cacheMode)
+    : mLocale(NULL), mVendor(NULL),
+      mResources(NULL), mConfig(new ResTable_config),
+      mCacheMode(cacheMode), mCacheValid(false)
+{
+    int count = android_atomic_inc(&gCount)+1;
+    //LOGI("Creating AssetManager %p #%d\n", this, count);
+    memset(mConfig, 0, sizeof(ResTable_config));
+}
+
+AssetManager::~AssetManager(void)
+{
+    int count = android_atomic_dec(&gCount);
+    //LOGI("Destroying AssetManager in %p #%d\n", this, count);
+
+    delete mConfig;
+    delete mResources;
+
+    // don't have a String class yet, so make sure we clean up
+    delete[] mLocale;
+    delete[] mVendor;
+}
+
+bool AssetManager::addAssetPath(const String8& path, void** cookie)
+{
+    AutoMutex _l(mLock);
+
+    asset_path ap;
+
+    String8 realPath(path);
+    if (kAppZipName) {
+        realPath.appendPath(kAppZipName);
+    }
+    ap.type = ::getFileType(realPath.string());
+    if (ap.type == kFileTypeRegular) {
+        ap.path = realPath;
+    } else {
+        ap.path = path;
+        ap.type = ::getFileType(path.string());
+        if (ap.type != kFileTypeDirectory && ap.type != kFileTypeRegular) {
+            LOGW("Asset path %s is neither a directory nor file (type=%d).",
+                 path.string(), (int)ap.type);
+            return false;
+        }
+    }
+
+    // Skip if we have it already.
+    for (size_t i=0; i<mAssetPaths.size(); i++) {
+        if (mAssetPaths[i].path == ap.path) {
+            if (cookie) {
+                *cookie = (void*)(i+1);
+            }
+            return true;
+        }
+    }
+    
+    LOGV("In %p Asset %s path: %s", this,
+         ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string());
+
+    mAssetPaths.add(ap);
+
+    // new paths are always added at the end
+    if (cookie) {
+        *cookie = (void*)mAssetPaths.size();
+    }
+
+    return true;
+}
+
+bool AssetManager::addDefaultAssets()
+{
+    const char* root = getenv("ANDROID_ROOT");
+    LOG_ALWAYS_FATAL_IF(root == NULL, "ANDROID_ROOT not set");
+
+    String8 path(root);
+    path.appendPath(kSystemAssets);
+
+    return addAssetPath(path, NULL);
+}
+
+void* AssetManager::nextAssetPath(void* cookie) const
+{
+    AutoMutex _l(mLock);
+    size_t next = ((size_t)cookie)+1;
+    return next > mAssetPaths.size() ? NULL : (void*)next;
+}
+
+String8 AssetManager::getAssetPath(void* cookie) const
+{
+    AutoMutex _l(mLock);
+    const size_t which = ((size_t)cookie)-1;
+    if (which < mAssetPaths.size()) {
+        return mAssetPaths[which].path;
+    }
+    return String8();
+}
+
+/*
+ * Set the current locale.  Use NULL to indicate no locale.
+ *
+ * Close and reopen Zip archives as appropriate, and reset cached
+ * information in the locale-specific sections of the tree.
+ */
+void AssetManager::setLocale(const char* locale)
+{
+    AutoMutex _l(mLock);
+    setLocaleLocked(locale);
+}
+
+void AssetManager::setLocaleLocked(const char* locale)
+{
+    if (mLocale != NULL) {
+        /* previously set, purge cached data */
+        purgeFileNameCacheLocked();
+        //mZipSet.purgeLocale();
+        delete[] mLocale;
+    }
+    mLocale = strdupNew(locale);
+    
+    updateResourceParamsLocked();
+}
+
+/*
+ * Set the current vendor.  Use NULL to indicate no vendor.
+ *
+ * Close and reopen Zip archives as appropriate, and reset cached
+ * information in the vendor-specific sections of the tree.
+ */
+void AssetManager::setVendor(const char* vendor)
+{
+    AutoMutex _l(mLock);
+
+    if (mVendor != NULL) {
+        /* previously set, purge cached data */
+        purgeFileNameCacheLocked();
+        //mZipSet.purgeVendor();
+        delete[] mVendor;
+    }
+    mVendor = strdupNew(vendor);
+}
+
+void AssetManager::setConfiguration(const ResTable_config& config, const char* locale)
+{
+    AutoMutex _l(mLock);
+    *mConfig = config;
+    if (locale) {
+        setLocaleLocked(locale);
+    } else if (config.language[0] != 0) {
+        char spec[9];
+        spec[0] = config.language[0];
+        spec[1] = config.language[1];
+        if (config.country[0] != 0) {
+            spec[2] = '_';
+            spec[3] = config.country[0];
+            spec[4] = config.country[1];
+            spec[5] = 0;
+        } else {
+            spec[3] = 0;
+        }
+        setLocaleLocked(spec);
+    } else {
+        updateResourceParamsLocked();
+    }
+}
+
+/*
+ * Open an asset.
+ *
+ * The data could be;
+ *  - In a file on disk (assetBase + fileName).
+ *  - In a compressed file on disk (assetBase + fileName.gz).
+ *  - In a Zip archive, uncompressed or compressed.
+ *
+ * It can be in a number of different directories and Zip archives.
+ * The search order is:
+ *  - [appname]
+ *    - locale + vendor
+ *    - "default" + vendor
+ *    - locale + "default"
+ *    - "default + "default"
+ *  - "common"
+ *    - (same as above)
+ *
+ * To find a particular file, we have to try up to eight paths with
+ * all three forms of data.
+ *
+ * We should probably reject requests for "illegal" filenames, e.g. those
+ * with illegal characters or "../" backward relative paths.
+ */
+Asset* AssetManager::open(const char* fileName, AccessMode mode)
+{
+    AutoMutex _l(mLock);
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    String8 assetName(kAssetsRoot);
+    assetName.appendPath(fileName);
+
+    /*
+     * For each top-level asset path, search for the asset.
+     */
+
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        LOGV("Looking for asset '%s' in '%s'\n",
+                assetName.string(), mAssetPaths.itemAt(i).path.string());
+        Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));
+        if (pAsset != NULL) {
+            return pAsset != kExcludedAsset ? pAsset : NULL;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Open a non-asset file as if it were an asset.
+ *
+ * The "fileName" is the partial path starting from the application
+ * name.
+ */
+Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode)
+{
+    AutoMutex _l(mLock);
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    /*
+     * For each top-level asset path, search for the asset.
+     */
+
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        LOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
+        Asset* pAsset = openNonAssetInPathLocked(
+            fileName, mode, mAssetPaths.itemAt(i));
+        if (pAsset != NULL) {
+            return pAsset != kExcludedAsset ? pAsset : NULL;
+        }
+    }
+
+    return NULL;
+}
+
+Asset* AssetManager::openNonAsset(void* cookie, const char* fileName, AccessMode mode)
+{
+    const size_t which = ((size_t)cookie)-1;
+
+    AutoMutex _l(mLock);
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    if (which < mAssetPaths.size()) {
+        LOGV("Looking for non-asset '%s' in '%s'\n", fileName,
+                mAssetPaths.itemAt(which).path.string());
+        Asset* pAsset = openNonAssetInPathLocked(
+            fileName, mode, mAssetPaths.itemAt(which));
+        if (pAsset != NULL) {
+            return pAsset != kExcludedAsset ? pAsset : NULL;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Get the type of a file in the asset namespace.
+ *
+ * This currently only works for regular files.  All others (including
+ * directories) will return kFileTypeNonexistent.
+ */
+FileType AssetManager::getFileType(const char* fileName)
+{
+    Asset* pAsset = NULL;
+
+    /*
+     * Open the asset.  This is less efficient than simply finding the
+     * file, but it's not too bad (we don't uncompress or mmap data until
+     * the first read() call).
+     */
+    pAsset = open(fileName, Asset::ACCESS_STREAMING);
+    delete pAsset;
+
+    if (pAsset == NULL)
+        return kFileTypeNonexistent;
+    else
+        return kFileTypeRegular;
+}
+
+const ResTable* AssetManager::getResTable(bool required) const
+{
+    ResTable* rt = mResources;
+    if (rt) {
+        return rt;
+    }
+
+    // Iterate through all asset packages, collecting resources from each.
+
+    AutoMutex _l(mLock);
+
+    if (mResources != NULL) {
+        return mResources;
+    }
+
+    if (required) {
+        LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+    }
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        const_cast<AssetManager*>(this)->loadFileNameCacheLocked();
+
+    const size_t N = mAssetPaths.size();
+    for (size_t i=0; i<N; i++) {
+        Asset* ass = NULL;
+        bool shared = true;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        LOGV("Looking for resource asset in '%s'\n", ap.path.string());
+        if (ap.type != kFileTypeDirectory) {
+            ass = const_cast<AssetManager*>(this)->
+                mZipSet.getZipResourceTable(ap.path);
+            if (ass == NULL) {
+                LOGV("loading resource table %s\n", ap.path.string());
+                ass = const_cast<AssetManager*>(this)->
+                    openNonAssetInPathLocked("resources.arsc",
+                                             Asset::ACCESS_BUFFER,
+                                             ap);
+                if (ass != NULL && ass != kExcludedAsset) {
+                    ass = const_cast<AssetManager*>(this)->
+                        mZipSet.setZipResourceTable(ap.path, ass);
+                }
+            }
+        } else {
+            LOGV("loading resource table %s\n", ap.path.string());
+            Asset* ass = const_cast<AssetManager*>(this)->
+                openNonAssetInPathLocked("resources.arsc",
+                                         Asset::ACCESS_BUFFER,
+                                         ap);
+            shared = false;
+        }
+        if (ass != NULL && ass != kExcludedAsset) {
+            if (rt == NULL) {
+                mResources = rt = new ResTable();
+                updateResourceParamsLocked();
+            }
+            LOGV("Installing resource asset %p in to table %p\n", ass, mResources);
+            rt->add(ass, (void*)(i+1), !shared);
+
+            if (!shared) {
+                delete ass;
+            }
+        }
+    }
+
+    if (required && !rt) LOGW("Unable to find resources file resources.arsc");
+    if (!rt) {
+        mResources = rt = new ResTable();
+    }
+    return rt;
+}
+
+void AssetManager::updateResourceParamsLocked() const
+{
+    ResTable* res = mResources;
+    if (!res) {
+        return;
+    }
+
+    size_t llen = mLocale ? strlen(mLocale) : 0;
+    mConfig->language[0] = 0;
+    mConfig->language[1] = 0;
+    mConfig->country[0] = 0;
+    mConfig->country[1] = 0;
+    if (llen >= 2) {
+        mConfig->language[0] = mLocale[0];
+        mConfig->language[1] = mLocale[1];
+    }
+    if (llen >= 5) {
+        mConfig->country[0] = mLocale[3];
+        mConfig->country[1] = mLocale[4];
+    }
+    mConfig->size = sizeof(*mConfig);
+
+    res->setParameters(mConfig);
+}
+
+const ResTable& AssetManager::getResources(bool required) const
+{
+    const ResTable* rt = getResTable(required);
+    return *rt;
+}
+
+bool AssetManager::isUpToDate()
+{
+    AutoMutex _l(mLock);
+    return mZipSet.isUpToDate();
+}
+
+void AssetManager::getLocales(Vector<String8>* locales) const
+{
+    ResTable* res = mResources;
+    if (res != NULL) {
+        res->getLocales(locales);
+    }
+}
+
+/*
+ * Open a non-asset file as if it were an asset, searching for it in the
+ * specified app.
+ *
+ * Pass in a NULL values for "appName" if the common app directory should
+ * be used.
+ */
+Asset* AssetManager::openNonAssetInPathLocked(const char* fileName, AccessMode mode,
+    const asset_path& ap)
+{
+    Asset* pAsset = NULL;
+
+    /* look at the filesystem on disk */
+    if (ap.type == kFileTypeDirectory) {
+        String8 path(ap.path);
+        path.appendPath(fileName);
+
+        pAsset = openAssetFromFileLocked(path, mode);
+
+        if (pAsset == NULL) {
+            /* try again, this time with ".gz" */
+            path.append(".gz");
+            pAsset = openAssetFromFileLocked(path, mode);
+        }
+
+        if (pAsset != NULL) {
+            //printf("FOUND NA '%s' on disk\n", fileName);
+            pAsset->setAssetSource(path);
+        }
+
+    /* look inside the zip file */
+    } else {
+        String8 path(fileName);
+
+        /* check the appropriate Zip file */
+        ZipFileRO* pZip;
+        ZipEntryRO entry;
+
+        pZip = getZipFileLocked(ap);
+        if (pZip != NULL) {
+            //printf("GOT zip, checking NA '%s'\n", (const char*) path);
+            entry = pZip->findEntryByName(path.string());
+            if (entry != NULL) {
+                //printf("FOUND NA in Zip file for %s\n", appName ? appName : kAppCommon);
+                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
+            }
+        }
+
+        if (pAsset != NULL) {
+            /* create a "source" name, for debug/display */
+            pAsset->setAssetSource(
+                    createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()), String8(""),
+                                                String8(fileName)));
+        }
+    }
+
+    return pAsset;
+}
+
+/*
+ * Open an asset, searching for it in the directory hierarchy for the
+ * specified app.
+ *
+ * Pass in a NULL values for "appName" if the common app directory should
+ * be used.
+ */
+Asset* AssetManager::openInPathLocked(const char* fileName, AccessMode mode,
+    const asset_path& ap)
+{
+    Asset* pAsset = NULL;
+
+    /*
+     * Try various combinations of locale and vendor.
+     */
+    if (mLocale != NULL && mVendor != NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, mVendor);
+    if (pAsset == NULL && mVendor != NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, mVendor);
+    if (pAsset == NULL && mLocale != NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, mLocale, NULL);
+    if (pAsset == NULL)
+        pAsset = openInLocaleVendorLocked(fileName, mode, ap, NULL, NULL);
+
+    return pAsset;
+}
+
+/*
+ * Open an asset, searching for it in the directory hierarchy for the
+ * specified locale and vendor.
+ *
+ * We also search in "app.jar".
+ *
+ * Pass in NULL values for "appName", "locale", and "vendor" if the
+ * defaults should be used.
+ */
+Asset* AssetManager::openInLocaleVendorLocked(const char* fileName, AccessMode mode,
+    const asset_path& ap, const char* locale, const char* vendor)
+{
+    Asset* pAsset = NULL;
+
+    if (ap.type == kFileTypeDirectory) {
+        if (mCacheMode == CACHE_OFF) {
+            /* look at the filesystem on disk */
+            String8 path(createPathNameLocked(ap, locale, vendor));
+            path.appendPath(fileName);
+    
+            String8 excludeName(path);
+            excludeName.append(kExcludeExtension);
+            if (::getFileType(excludeName.string()) != kFileTypeNonexistent) {
+                /* say no more */
+                //printf("+++ excluding '%s'\n", (const char*) excludeName);
+                return kExcludedAsset;
+            }
+    
+            pAsset = openAssetFromFileLocked(path, mode);
+    
+            if (pAsset == NULL) {
+                /* try again, this time with ".gz" */
+                path.append(".gz");
+                pAsset = openAssetFromFileLocked(path, mode);
+            }
+    
+            if (pAsset != NULL)
+                pAsset->setAssetSource(path);
+        } else {
+            /* find in cache */
+            String8 path(createPathNameLocked(ap, locale, vendor));
+            path.appendPath(fileName);
+    
+            AssetDir::FileInfo tmpInfo;
+            bool found = false;
+    
+            String8 excludeName(path);
+            excludeName.append(kExcludeExtension);
+    
+            if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) {
+                /* go no farther */
+                //printf("+++ Excluding '%s'\n", (const char*) excludeName);
+                return kExcludedAsset;
+            }
+
+            /*
+             * File compression extensions (".gz") don't get stored in the
+             * name cache, so we have to try both here.
+             */
+            if (mCache.indexOf(path) != NAME_NOT_FOUND) {
+                found = true;
+                pAsset = openAssetFromFileLocked(path, mode);
+                if (pAsset == NULL) {
+                    /* try again, this time with ".gz" */
+                    path.append(".gz");
+                    pAsset = openAssetFromFileLocked(path, mode);
+                }
+            }
+
+            if (pAsset != NULL)
+                pAsset->setAssetSource(path);
+
+            /*
+             * Don't continue the search into the Zip files.  Our cached info
+             * said it was a file on disk; to be consistent with openDir()
+             * we want to return the loose asset.  If the cached file gets
+             * removed, we fail.
+             *
+             * The alternative is to update our cache when files get deleted,
+             * or make some sort of "best effort" promise, but for now I'm
+             * taking the hard line.
+             */
+            if (found) {
+                if (pAsset == NULL)
+                    LOGD("Expected file not found: '%s'\n", path.string());
+                return pAsset;
+            }
+        }
+    }
+
+    /*
+     * Either it wasn't found on disk or on the cached view of the disk.
+     * Dig through the currently-opened set of Zip files.  If caching
+     * is disabled, the Zip file may get reopened.
+     */
+    if (pAsset == NULL && ap.type == kFileTypeRegular) {
+        String8 path;
+
+        path.appendPath((locale != NULL) ? locale : kDefaultLocale);
+        path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
+        path.appendPath(fileName);
+
+        /* check the appropriate Zip file */
+        ZipFileRO* pZip;
+        ZipEntryRO entry;
+
+        pZip = getZipFileLocked(ap);
+        if (pZip != NULL) {
+            //printf("GOT zip, checking '%s'\n", (const char*) path);
+            entry = pZip->findEntryByName(path.string());
+            if (entry != NULL) {
+                //printf("FOUND in Zip file for %s/%s-%s\n",
+                //    appName, locale, vendor);
+                pAsset = openAssetFromZipLocked(pZip, entry, mode, path);
+            }
+        }
+
+        if (pAsset != NULL) {
+            /* create a "source" name, for debug/display */
+            pAsset->setAssetSource(createZipSourceNameLocked(ZipSet::getPathName(ap.path.string()),
+                                                             String8(""), String8(fileName)));
+        }
+    }
+
+    return pAsset;
+}
+
+/*
+ * Create a "source name" for a file from a Zip archive.
+ */
+String8 AssetManager::createZipSourceNameLocked(const String8& zipFileName,
+    const String8& dirName, const String8& fileName)
+{
+    String8 sourceName("zip:");
+    sourceName.append(zipFileName);
+    sourceName.append(":");
+    if (dirName.length() > 0) {
+        sourceName.appendPath(dirName);
+    }
+    sourceName.appendPath(fileName);
+    return sourceName;
+}
+
+/*
+ * Create a path to a loose asset (asset-base/app/locale/vendor).
+ */
+String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* locale,
+    const char* vendor)
+{
+    String8 path(ap.path);
+    path.appendPath((locale != NULL) ? locale : kDefaultLocale);
+    path.appendPath((vendor != NULL) ? vendor : kDefaultVendor);
+    return path;
+}
+
+/*
+ * Create a path to a loose asset (asset-base/app/rootDir).
+ */
+String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* rootDir)
+{
+    String8 path(ap.path);
+    if (rootDir != NULL) path.appendPath(rootDir);
+    return path;
+}
+
+/*
+ * Return a pointer to one of our open Zip archives.  Returns NULL if no
+ * matching Zip file exists.
+ *
+ * Right now we have 2 possible Zip files (1 each in app/"common").
+ *
+ * If caching is set to CACHE_OFF, to get the expected behavior we
+ * need to reopen the Zip file on every request.  That would be silly
+ * and expensive, so instead we just check the file modification date.
+ *
+ * Pass in NULL values for "appName", "locale", and "vendor" if the
+ * generics should be used.
+ */
+ZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap)
+{
+    LOGV("getZipFileLocked() in %p\n", this);
+
+    return mZipSet.getZip(ap.path);
+}
+
+/*
+ * Try to open an asset from a file on disk.
+ *
+ * If the file is compressed with gzip, we seek to the start of the
+ * deflated data and pass that in (just like we would for a Zip archive).
+ *
+ * For uncompressed data, we may already have an mmap()ed version sitting
+ * around.  If so, we want to hand that to the Asset instead.
+ *
+ * This returns NULL if the file doesn't exist, couldn't be opened, or
+ * claims to be a ".gz" but isn't.
+ */
+Asset* AssetManager::openAssetFromFileLocked(const String8& pathName,
+    AccessMode mode)
+{
+    Asset* pAsset = NULL;
+
+    if (strcasecmp(pathName.getPathExtension().string(), ".gz") == 0) {
+        //printf("TRYING '%s'\n", (const char*) pathName);
+        pAsset = Asset::createFromCompressedFile(pathName.string(), mode);
+    } else {
+        //printf("TRYING '%s'\n", (const char*) pathName);
+        pAsset = Asset::createFromFile(pathName.string(), mode);
+    }
+
+    return pAsset;
+}
+
+/*
+ * Given an entry in a Zip archive, create a new Asset object.
+ *
+ * If the entry is uncompressed, we may want to create or share a
+ * slice of shared memory.
+ */
+Asset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile,
+    const ZipEntryRO entry, AccessMode mode, const String8& entryName)
+{
+    Asset* pAsset = NULL;
+
+    // TODO: look for previously-created shared memory slice?
+    int method;
+    long uncompressedLen;
+
+    //printf("USING Zip '%s'\n", pEntry->getFileName());
+
+    //pZipFile->getEntryInfo(entry, &method, &uncompressedLen, &compressedLen,
+    //    &offset);
+    if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,
+            NULL, NULL))
+    {
+        LOGW("getEntryInfo failed\n");
+        return NULL;
+    }
+
+    FileMap* dataMap = pZipFile->createEntryFileMap(entry);
+    if (dataMap == NULL) {
+        LOGW("create map from entry failed\n");
+        return NULL;
+    }
+
+    if (method == ZipFileRO::kCompressStored) {
+        pAsset = Asset::createFromUncompressedMap(dataMap, mode);
+        LOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
+                dataMap->getFileName(), mode, pAsset);
+    } else {
+        pAsset = Asset::createFromCompressedMap(dataMap, method,
+            uncompressedLen, mode);
+        LOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
+                dataMap->getFileName(), mode, pAsset);
+    }
+    if (pAsset == NULL) {
+        /* unexpected */
+        LOGW("create from segment failed\n");
+    }
+
+    return pAsset;
+}
+
+
+
+/*
+ * Open a directory in the asset namespace.
+ *
+ * An "asset directory" is simply the combination of all files in all
+ * locations, with ".gz" stripped for loose files.  With app, locale, and
+ * vendor defined, we have 8 directories and 2 Zip archives to scan.
+ *
+ * Pass in "" for the root dir.
+ */
+AssetDir* AssetManager::openDir(const char* dirName)
+{
+    AutoMutex _l(mLock);
+
+    AssetDir* pDir = NULL;
+    SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
+
+    LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+    assert(dirName != NULL);
+
+    //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
+
+    if (mCacheMode != CACHE_OFF && !mCacheValid)
+        loadFileNameCacheLocked();
+
+    pDir = new AssetDir;
+
+    /*
+     * Scan the various directories, merging what we find into a single
+     * vector.  We want to scan them in reverse priority order so that
+     * the ".EXCLUDE" processing works correctly.  Also, if we decide we
+     * want to remember where the file is coming from, we'll get the right
+     * version.
+     *
+     * We start with Zip archives, then do loose files.
+     */
+    pMergedInfo = new SortedVector<AssetDir::FileInfo>;
+
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        if (ap.type == kFileTypeRegular) {
+            LOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+            scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
+        } else {
+            LOGV("Adding directory %s from dir %s", dirName, ap.path.string());
+            scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);
+        }
+    }
+
+#if 0
+    printf("FILE LIST:\n");
+    for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
+        printf(" %d: (%d) '%s'\n", i,
+            pMergedInfo->itemAt(i).getFileType(),
+            (const char*) pMergedInfo->itemAt(i).getFileName());
+    }
+#endif
+
+    pDir->setFileList(pMergedInfo);
+    return pDir;
+}
+
+/*
+ * Scan the contents of the specified directory and merge them into the
+ * "pMergedInfo" vector, removing previous entries if we find "exclude"
+ * directives.
+ *
+ * Returns "false" if we found nothing to contribute.
+ */
+bool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const asset_path& ap, const char* rootDir, const char* dirName)
+{
+    SortedVector<AssetDir::FileInfo>* pContents;
+    String8 path;
+
+    assert(pMergedInfo != NULL);
+
+    //printf("scanAndMergeDir: %s %s %s %s\n", appName, locale, vendor,dirName);
+
+    if (mCacheValid) {
+        int i, start, count;
+
+        pContents = new SortedVector<AssetDir::FileInfo>;
+
+        /*
+         * Get the basic partial path and find it in the cache.  That's
+         * the start point for the search.
+         */
+        path = createPathNameLocked(ap, rootDir);
+        if (dirName[0] != '\0')
+            path.appendPath(dirName);
+
+        start = mCache.indexOf(path);
+        if (start == NAME_NOT_FOUND) {
+            //printf("+++ not found in cache: dir '%s'\n", (const char*) path);
+            delete pContents;
+            return false;
+        }
+
+        /*
+         * The match string looks like "common/default/default/foo/bar/".
+         * The '/' on the end ensures that we don't match on the directory
+         * itself or on ".../foo/barfy/".
+         */
+        path.append("/");
+
+        count = mCache.size();
+
+        /*
+         * Pick out the stuff in the current dir by examining the pathname.
+         * It needs to match the partial pathname prefix, and not have a '/'
+         * (fssep) anywhere after the prefix.
+         */
+        for (i = start+1; i < count; i++) {
+            if (mCache[i].getFileName().length() > path.length() &&
+                strncmp(mCache[i].getFileName().string(), path.string(), path.length()) == 0)
+            {
+                const char* name = mCache[i].getFileName().string();
+                // XXX THIS IS BROKEN!  Looks like we need to store the full
+                // path prefix separately from the file path.
+                if (strchr(name + path.length(), '/') == NULL) {
+                    /* grab it, reducing path to just the filename component */
+                    AssetDir::FileInfo tmp = mCache[i];
+                    tmp.setFileName(tmp.getFileName().getPathLeaf());
+                    pContents->add(tmp);
+                }
+            } else {
+                /* no longer in the dir or its subdirs */
+                break;
+            }
+
+        }
+    } else {
+        path = createPathNameLocked(ap, rootDir);
+        if (dirName[0] != '\0')
+            path.appendPath(dirName);
+        pContents = scanDirLocked(path);
+        if (pContents == NULL)
+            return false;
+    }
+
+    // if we wanted to do an incremental cache fill, we would do it here
+
+    /*
+     * Process "exclude" directives.  If we find a filename that ends with
+     * ".EXCLUDE", we look for a matching entry in the "merged" set, and
+     * remove it if we find it.  We also delete the "exclude" entry.
+     */
+    int i, count, exclExtLen;
+
+    count = pContents->size();
+    exclExtLen = strlen(kExcludeExtension);
+    for (i = 0; i < count; i++) {
+        const char* name;
+        int nameLen;
+
+        name = pContents->itemAt(i).getFileName().string();
+        nameLen = strlen(name);
+        if (nameLen > exclExtLen &&
+            strcmp(name + (nameLen - exclExtLen), kExcludeExtension) == 0)
+        {
+            String8 match(name, nameLen - exclExtLen);
+            int matchIdx;
+
+            matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);
+            if (matchIdx > 0) {
+                LOGV("Excluding '%s' [%s]\n",
+                    pMergedInfo->itemAt(matchIdx).getFileName().string(),
+                    pMergedInfo->itemAt(matchIdx).getSourceName().string());
+                pMergedInfo->removeAt(matchIdx);
+            } else {
+                //printf("+++ no match on '%s'\n", (const char*) match);
+            }
+
+            LOGD("HEY: size=%d removing %d\n", (int)pContents->size(), i);
+            pContents->removeAt(i);
+            i--;        // adjust "for" loop
+            count--;    //  and loop limit
+        }
+    }
+
+    mergeInfoLocked(pMergedInfo, pContents);
+
+    delete pContents;
+
+    return true;
+}
+
+/*
+ * Scan the contents of the specified directory, and stuff what we find
+ * into a newly-allocated vector.
+ *
+ * Files ending in ".gz" will have their extensions removed.
+ *
+ * We should probably think about skipping files with "illegal" names,
+ * e.g. illegal characters (/\:) or excessive length.
+ *
+ * Returns NULL if the specified directory doesn't exist.
+ */
+SortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& path)
+{
+    SortedVector<AssetDir::FileInfo>* pContents = NULL;
+    DIR* dir;
+    struct dirent* entry;
+    FileType fileType;
+
+    LOGV("Scanning dir '%s'\n", path.string());
+
+    dir = opendir(path.string());
+    if (dir == NULL)
+        return NULL;
+
+    pContents = new SortedVector<AssetDir::FileInfo>;
+
+    while (1) {
+        entry = readdir(dir);
+        if (entry == NULL)
+            break;
+
+        if (strcmp(entry->d_name, ".") == 0 ||
+            strcmp(entry->d_name, "..") == 0)
+            continue;
+
+#ifdef _DIRENT_HAVE_D_TYPE
+        if (entry->d_type == DT_REG)
+            fileType = kFileTypeRegular;
+        else if (entry->d_type == DT_DIR)
+            fileType = kFileTypeDirectory;
+        else
+            fileType = kFileTypeUnknown;
+#else
+        // stat the file
+        fileType = ::getFileType(path.appendPathCopy(entry->d_name).string());
+#endif
+
+        if (fileType != kFileTypeRegular && fileType != kFileTypeDirectory)
+            continue;
+
+        AssetDir::FileInfo info;
+        info.set(String8(entry->d_name), fileType);
+        if (strcasecmp(info.getFileName().getPathExtension().string(), ".gz") == 0)
+            info.setFileName(info.getFileName().getBasePath());
+        info.setSourceName(path.appendPathCopy(info.getFileName()));
+        pContents->add(info);
+    }
+
+    closedir(dir);
+    return pContents;
+}
+
+/*
+ * Scan the contents out of the specified Zip archive, and merge what we
+ * find into "pMergedInfo".  If the Zip archive in question doesn't exist,
+ * we return immediately.
+ *
+ * Returns "false" if we found nothing to contribute.
+ */
+bool AssetManager::scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const asset_path& ap, const char* rootDir, const char* baseDirName)
+{
+    ZipFileRO* pZip;
+    Vector<String8> dirs;
+    AssetDir::FileInfo info;
+    SortedVector<AssetDir::FileInfo> contents;
+    String8 sourceName, zipName, dirName;
+
+    pZip = mZipSet.getZip(ap.path);
+    if (pZip == NULL) {
+        LOGW("Failure opening zip %s\n", ap.path.string());
+        return false;
+    }
+
+    zipName = ZipSet::getPathName(ap.path.string());
+
+    /* convert "sounds" to "rootDir/sounds" */
+    if (rootDir != NULL) dirName = rootDir;
+    dirName.appendPath(baseDirName);
+
+    /*
+     * Scan through the list of files, looking for a match.  The files in
+     * the Zip table of contents are not in sorted order, so we have to
+     * process the entire list.  We're looking for a string that begins
+     * with the characters in "dirName", is followed by a '/', and has no
+     * subsequent '/' in the stuff that follows.
+     *
+     * What makes this especially fun is that directories are not stored
+     * explicitly in Zip archives, so we have to infer them from context.
+     * When we see "sounds/foo.wav" we have to leave a note to ourselves
+     * to insert a directory called "sounds" into the list.  We store
+     * these in temporary vector so that we only return each one once.
+     *
+     * Name comparisons are case-sensitive to match UNIX filesystem
+     * semantics.
+     */
+    int dirNameLen = dirName.length();
+    for (int i = 0; i < pZip->getNumEntries(); i++) {
+        ZipEntryRO entry;
+        char nameBuf[256];
+
+        entry = pZip->findEntryByIndex(i);
+        if (pZip->getEntryFileName(entry, nameBuf, sizeof(nameBuf)) != 0) {
+            // TODO: fix this if we expect to have long names
+            LOGE("ARGH: name too long?\n");
+            continue;
+        }
+        if (dirNameLen == 0 ||
+            (strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&
+             nameBuf[dirNameLen] == '/'))
+        {
+            const char* cp;
+            const char* nextSlash;
+
+            cp = nameBuf + dirNameLen;
+            if (dirNameLen != 0)
+                cp++;       // advance past the '/'
+
+            nextSlash = strchr(cp, '/');
+//xxx this may break if there are bare directory entries
+            if (nextSlash == NULL) {
+                /* this is a file in the requested directory */
+
+                info.set(String8(nameBuf).getPathLeaf(), kFileTypeRegular);
+
+                info.setSourceName(
+                    createZipSourceNameLocked(zipName, dirName, info.getFileName()));
+
+                contents.add(info);
+                //printf("FOUND: file '%s'\n", (const char*) info.mFileName);
+            } else {
+                /* this is a subdir; add it if we don't already have it*/
+                String8 subdirName(cp, nextSlash - cp);
+                size_t j;
+                size_t N = dirs.size();
+
+                for (j = 0; j < N; j++) {
+                    if (subdirName == dirs[j]) {
+                        break;
+                    }
+                }
+                if (j == N) {
+                    dirs.add(subdirName);
+                }
+
+                //printf("FOUND: dir '%s'\n", (const char*) subdirName);
+            }
+        }
+    }
+
+    /*
+     * Add the set of unique directories.
+     */
+    for (int i = 0; i < (int) dirs.size(); i++) {
+        info.set(dirs[i], kFileTypeDirectory);
+        info.setSourceName(
+            createZipSourceNameLocked(zipName, dirName, info.getFileName()));
+        contents.add(info);
+    }
+
+    mergeInfoLocked(pMergedInfo, &contents);
+
+    return true;
+}
+
+
+/*
+ * Merge two vectors of FileInfo.
+ *
+ * The merged contents will be stuffed into *pMergedInfo.
+ *
+ * If an entry for a file exists in both "pMergedInfo" and "pContents",
+ * we use the newer "pContents" entry.
+ */
+void AssetManager::mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const SortedVector<AssetDir::FileInfo>* pContents)
+{
+    /*
+     * Merge what we found in this directory with what we found in
+     * other places.
+     *
+     * Two basic approaches:
+     * (1) Create a new array that holds the unique values of the two
+     *     arrays.
+     * (2) Take the elements from pContents and shove them into pMergedInfo.
+     *
+     * Because these are vectors of complex objects, moving elements around
+     * inside the vector requires constructing new objects and allocating
+     * storage for members.  With approach #1, we're always adding to the
+     * end, whereas with #2 we could be inserting multiple elements at the
+     * front of the vector.  Approach #1 requires a full copy of the
+     * contents of pMergedInfo, but approach #2 requires the same copy for
+     * every insertion at the front of pMergedInfo.
+     *
+     * (We should probably use a SortedVector interface that allows us to
+     * just stuff items in, trusting us to maintain the sort order.)
+     */
+    SortedVector<AssetDir::FileInfo>* pNewSorted;
+    int mergeMax, contMax;
+    int mergeIdx, contIdx;
+
+    pNewSorted = new SortedVector<AssetDir::FileInfo>;
+    mergeMax = pMergedInfo->size();
+    contMax = pContents->size();
+    mergeIdx = contIdx = 0;
+
+    while (mergeIdx < mergeMax || contIdx < contMax) {
+        if (mergeIdx == mergeMax) {
+            /* hit end of "merge" list, copy rest of "contents" */
+            pNewSorted->add(pContents->itemAt(contIdx));
+            contIdx++;
+        } else if (contIdx == contMax) {
+            /* hit end of "cont" list, copy rest of "merge" */
+            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
+            mergeIdx++;
+        } else if (pMergedInfo->itemAt(mergeIdx) == pContents->itemAt(contIdx))
+        {
+            /* items are identical, add newer and advance both indices */
+            pNewSorted->add(pContents->itemAt(contIdx));
+            mergeIdx++;
+            contIdx++;
+        } else if (pMergedInfo->itemAt(mergeIdx) < pContents->itemAt(contIdx))
+        {
+            /* "merge" is lower, add that one */
+            pNewSorted->add(pMergedInfo->itemAt(mergeIdx));
+            mergeIdx++;
+        } else {
+            /* "cont" is lower, add that one */
+            assert(pContents->itemAt(contIdx) < pMergedInfo->itemAt(mergeIdx));
+            pNewSorted->add(pContents->itemAt(contIdx));
+            contIdx++;
+        }
+    }
+
+    /*
+     * Overwrite the "merged" list with the new stuff.
+     */
+    *pMergedInfo = *pNewSorted;
+    delete pNewSorted;
+
+#if 0       // for Vector, rather than SortedVector
+    int i, j;
+    for (i = pContents->size() -1; i >= 0; i--) {
+        bool add = true;
+
+        for (j = pMergedInfo->size() -1; j >= 0; j--) {
+            /* case-sensitive comparisons, to behave like UNIX fs */
+            if (strcmp(pContents->itemAt(i).mFileName,
+                       pMergedInfo->itemAt(j).mFileName) == 0)
+            {
+                /* match, don't add this entry */
+                add = false;
+                break;
+            }
+        }
+
+        if (add)
+            pMergedInfo->add(pContents->itemAt(i));
+    }
+#endif
+}
+
+
+/*
+ * Load all files into the file name cache.  We want to do this across
+ * all combinations of { appname, locale, vendor }, performing a recursive
+ * directory traversal.
+ *
+ * This is not the most efficient data structure.  Also, gathering the
+ * information as we needed it (file-by-file or directory-by-directory)
+ * would be faster.  However, on the actual device, 99% of the files will
+ * live in Zip archives, so this list will be very small.  The trouble
+ * is that we have to check the "loose" files first, so it's important
+ * that we don't beat the filesystem silly looking for files that aren't
+ * there.
+ *
+ * Note on thread safety: this is the only function that causes updates
+ * to mCache, and anybody who tries to use it will call here if !mCacheValid,
+ * so we need to employ a mutex here.
+ */
+void AssetManager::loadFileNameCacheLocked(void)
+{
+    assert(!mCacheValid);
+    assert(mCache.size() == 0);
+
+#ifdef DO_TIMINGS   // need to link against -lrt for this now
+    DurationTimer timer;
+    timer.start();
+#endif
+
+    fncScanLocked(&mCache, "");
+
+#ifdef DO_TIMINGS
+    timer.stop();
+    LOGD("Cache scan took %.3fms\n",
+        timer.durationUsecs() / 1000.0);
+#endif
+
+#if 0
+    int i;
+    printf("CACHED FILE LIST (%d entries):\n", mCache.size());
+    for (i = 0; i < (int) mCache.size(); i++) {
+        printf(" %d: (%d) '%s'\n", i,
+            mCache.itemAt(i).getFileType(),
+            (const char*) mCache.itemAt(i).getFileName());
+    }
+#endif
+
+    mCacheValid = true;
+}
+
+/*
+ * Scan up to 8 versions of the specified directory.
+ */
+void AssetManager::fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const char* dirName)
+{
+    size_t i = mAssetPaths.size();
+    while (i > 0) {
+        i--;
+        const asset_path& ap = mAssetPaths.itemAt(i);
+        fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, NULL, dirName);
+        if (mLocale != NULL)
+            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, NULL, dirName);
+        if (mVendor != NULL)
+            fncScanAndMergeDirLocked(pMergedInfo, ap, NULL, mVendor, dirName);
+        if (mLocale != NULL && mVendor != NULL)
+            fncScanAndMergeDirLocked(pMergedInfo, ap, mLocale, mVendor, dirName);
+    }
+}
+
+/*
+ * Recursively scan this directory and all subdirs.
+ *
+ * This is similar to scanAndMergeDir, but we don't remove the .EXCLUDE
+ * files, and we prepend the extended partial path to the filenames.
+ */
+bool AssetManager::fncScanAndMergeDirLocked(
+    SortedVector<AssetDir::FileInfo>* pMergedInfo,
+    const asset_path& ap, const char* locale, const char* vendor,
+    const char* dirName)
+{
+    SortedVector<AssetDir::FileInfo>* pContents;
+    String8 partialPath;
+    String8 fullPath;
+
+    // XXX This is broken -- the filename cache needs to hold the base
+    // asset path separately from its filename.
+    
+    partialPath = createPathNameLocked(ap, locale, vendor);
+    if (dirName[0] != '\0') {
+        partialPath.appendPath(dirName);
+    }
+
+    fullPath = partialPath;
+    pContents = scanDirLocked(fullPath);
+    if (pContents == NULL) {
+        return false;       // directory did not exist
+    }
+
+    /*
+     * Scan all subdirectories of the current dir, merging what we find
+     * into "pMergedInfo".
+     */
+    for (int i = 0; i < (int) pContents->size(); i++) {
+        if (pContents->itemAt(i).getFileType() == kFileTypeDirectory) {
+            String8 subdir(dirName);
+            subdir.appendPath(pContents->itemAt(i).getFileName());
+
+            fncScanAndMergeDirLocked(pMergedInfo, ap, locale, vendor, subdir.string());
+        }
+    }
+
+    /*
+     * To be consistent, we want entries for the root directory.  If
+     * we're the root, add one now.
+     */
+    if (dirName[0] == '\0') {
+        AssetDir::FileInfo tmpInfo;
+
+        tmpInfo.set(String8(""), kFileTypeDirectory);
+        tmpInfo.setSourceName(createPathNameLocked(ap, locale, vendor));
+        pContents->add(tmpInfo);
+    }
+
+    /*
+     * We want to prepend the extended partial path to every entry in
+     * "pContents".  It's the same value for each entry, so this will
+     * not change the sorting order of the vector contents.
+     */
+    for (int i = 0; i < (int) pContents->size(); i++) {
+        const AssetDir::FileInfo& info = pContents->itemAt(i);
+        pContents->editItemAt(i).setFileName(partialPath.appendPathCopy(info.getFileName()));
+    }
+
+    mergeInfoLocked(pMergedInfo, pContents);
+    return true;
+}
+
+/*
+ * Trash the cache.
+ */
+void AssetManager::purgeFileNameCacheLocked(void)
+{
+    mCacheValid = false;
+    mCache.clear();
+}
+
+/*
+ * ===========================================================================
+ *      AssetManager::SharedZip
+ * ===========================================================================
+ */
+
+
+Mutex AssetManager::SharedZip::gLock;
+DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen;
+
+AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
+    : mPath(path), mZipFile(NULL), mModWhen(modWhen), mResourceTableAsset(NULL)
+{
+    //LOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
+    mZipFile = new ZipFileRO;
+    LOGV("+++ opening zip '%s'\n", mPath.string());
+    if (mZipFile->open(mPath.string()) != NO_ERROR) {
+        LOGD("failed to open Zip archive '%s'\n", mPath.string());
+        delete mZipFile;
+        mZipFile = NULL;
+    }
+}
+
+sp<AssetManager::SharedZip> AssetManager::SharedZip::get(const String8& path)
+{
+    AutoMutex _l(gLock);
+    time_t modWhen = getFileModDate(path);
+    sp<SharedZip> zip = gOpen.valueFor(path).promote();
+    if (zip != NULL && zip->mModWhen == modWhen) {
+        return zip;
+    }
+    zip = new SharedZip(path, modWhen);
+    gOpen.add(path, zip);
+    return zip;
+
+}
+
+ZipFileRO* AssetManager::SharedZip::getZip()
+{
+    return mZipFile;
+}
+
+Asset* AssetManager::SharedZip::getResourceTableAsset()
+{
+    LOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
+    return mResourceTableAsset;
+}
+
+Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)
+{
+    {
+        AutoMutex _l(gLock);
+        if (mResourceTableAsset == NULL) {
+            mResourceTableAsset = asset;
+            // This is not thread safe the first time it is called, so
+            // do it here with the global lock held.
+            asset->getBuffer(true);
+            return asset;
+        }
+    }
+    delete asset;
+    return mResourceTableAsset;
+}
+
+bool AssetManager::SharedZip::isUpToDate()
+{
+    time_t modWhen = getFileModDate(mPath.string());
+    return mModWhen == modWhen;
+}
+
+AssetManager::SharedZip::~SharedZip()
+{
+    //LOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath);
+    if (mResourceTableAsset != NULL) {
+        delete mResourceTableAsset;
+    }
+    if (mZipFile != NULL) {
+        delete mZipFile;
+        LOGV("Closed '%s'\n", mPath.string());
+    }
+}
+
+/*
+ * ===========================================================================
+ *      AssetManager::ZipSet
+ * ===========================================================================
+ */
+
+/*
+ * Constructor.
+ */
+AssetManager::ZipSet::ZipSet(void)
+{
+}
+
+/*
+ * Destructor.  Close any open archives.
+ */
+AssetManager::ZipSet::~ZipSet(void)
+{
+    size_t N = mZipFile.size();
+    for (size_t i = 0; i < N; i++)
+        closeZip(i);
+}
+
+/*
+ * Close a Zip file and reset the entry.
+ */
+void AssetManager::ZipSet::closeZip(int idx)
+{
+    mZipFile.editItemAt(idx) = NULL;
+}
+
+
+/*
+ * Retrieve the appropriate Zip file from the set.
+ */
+ZipFileRO* AssetManager::ZipSet::getZip(const String8& path)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    if (zip == NULL) {
+        zip = SharedZip::get(path);
+        mZipFile.editItemAt(idx) = zip;
+    }
+    return zip->getZip();
+}
+
+Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    if (zip == NULL) {
+        zip = SharedZip::get(path);
+        mZipFile.editItemAt(idx) = zip;
+    }
+    return zip->getResourceTableAsset();
+}
+
+Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path,
+                                                 Asset* asset)
+{
+    int idx = getIndex(path);
+    sp<SharedZip> zip = mZipFile[idx];
+    // doesn't make sense to call before previously accessing.
+    return zip->setResourceTableAsset(asset);
+}
+
+/*
+ * Generate the partial pathname for the specified archive.  The caller
+ * gets to prepend the asset root directory.
+ *
+ * Returns something like "common/en-US-noogle.jar".
+ */
+/*static*/ String8 AssetManager::ZipSet::getPathName(const char* zipPath)
+{
+    return String8(zipPath);
+}
+
+bool AssetManager::ZipSet::isUpToDate()
+{
+    const size_t N = mZipFile.size();
+    for (size_t i=0; i<N; i++) {
+        if (mZipFile[i] != NULL && !mZipFile[i]->isUpToDate()) {
+            return false;
+        }
+    }
+    return true;
+}
+
+/*
+ * Compute the zip file's index.
+ *
+ * "appName", "locale", and "vendor" should be set to NULL to indicate the
+ * default directory.
+ */
+int AssetManager::ZipSet::getIndex(const String8& zip) const
+{
+    const size_t N = mZipPath.size();
+    for (size_t i=0; i<N; i++) {
+        if (mZipPath[i] == zip) {
+            return i;
+        }
+    }
+
+    mZipPath.add(zip);
+    mZipFile.add(NULL);
+
+    return mZipPath.size()-1;
+}
+
diff --git a/libs/utils/Binder.cpp b/libs/utils/Binder.cpp
new file mode 100644
index 0000000..37e4685
--- /dev/null
+++ b/libs/utils/Binder.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/Binder.h>
+
+#include <utils/Atomic.h>
+#include <utils/BpBinder.h>
+#include <utils/IInterface.h>
+#include <utils/Parcel.h>
+
+#include <stdio.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)
+{
+    return NULL;
+}
+
+BBinder* IBinder::localBinder()
+{
+    return NULL;
+}
+
+BpBinder* IBinder::remoteBinder()
+{
+    return NULL;
+}
+
+bool IBinder::checkSubclass(const void* /*subclassID*/) const
+{
+    return false;
+}
+
+// ---------------------------------------------------------------------------
+
+class BBinder::Extras
+{
+public:
+    Mutex mLock;
+    BpBinder::ObjectManager mObjects;
+};
+
+// ---------------------------------------------------------------------------
+
+BBinder::BBinder()
+    : mExtras(NULL)
+{
+}
+
+bool BBinder::isBinderAlive() const
+{
+    return true;
+}
+
+status_t BBinder::pingBinder()
+{
+    return NO_ERROR;
+}
+
+String16 BBinder::getInterfaceDescriptor() const
+{
+    LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
+    return String16();
+}
+
+status_t BBinder::transact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    data.setDataPosition(0);
+
+    status_t err = NO_ERROR;
+    switch (code) {
+        case PING_TRANSACTION:
+            reply->writeInt32(pingBinder());
+            break;
+        default:
+            err = onTransact(code, data, reply, flags);
+            break;
+    }
+
+    if (reply != NULL) {
+        reply->setDataPosition(0);
+    }
+
+    return err;
+}
+
+status_t BBinder::linkToDeath(
+    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
+{
+    return INVALID_OPERATION;
+}
+
+status_t BBinder::unlinkToDeath(
+    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
+    wp<DeathRecipient>* outRecipient)
+{
+    return INVALID_OPERATION;
+}
+
+status_t BBinder::dump(int fd, const Vector<String16>& args)
+{
+    return NO_ERROR;
+}
+
+void BBinder::attachObject(
+    const void* objectID, void* object, void* cleanupCookie,
+    object_cleanup_func func)
+{
+    Extras* e = mExtras;
+
+    if (!e) {
+        e = new Extras;
+        if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
+                reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
+            delete e;
+            e = mExtras;
+        }
+        if (e == 0) return; // out of memory
+    }
+
+    AutoMutex _l(e->mLock);
+    e->mObjects.attach(objectID, object, cleanupCookie, func);
+}
+
+void* BBinder::findObject(const void* objectID) const
+{
+    Extras* e = mExtras;
+    if (!e) return NULL;
+
+    AutoMutex _l(e->mLock);
+    return e->mObjects.find(objectID);
+}
+
+void BBinder::detachObject(const void* objectID)
+{
+    Extras* e = mExtras;
+    if (!e) return;
+
+    AutoMutex _l(e->mLock);
+    e->mObjects.detach(objectID);
+}
+
+BBinder* BBinder::localBinder()
+{
+    return this;
+}
+
+BBinder::~BBinder()
+{
+    if (mExtras) delete mExtras;
+}
+
+
+status_t BBinder::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case INTERFACE_TRANSACTION:
+            reply->writeString16(getInterfaceDescriptor());
+            return NO_ERROR;
+
+        case DUMP_TRANSACTION: {
+            int fd = data.readFileDescriptor();
+            int argc = data.readInt32();
+            Vector<String16> args;
+            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
+               args.add(data.readString16());
+            }
+            return dump(fd, args);
+        }
+        default:
+            return UNKNOWN_TRANSACTION;
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+enum {
+    // This is used to transfer ownership of the remote binder from
+    // the BpRefBase object holding it (when it is constructed), to the
+    // owner of the BpRefBase object when it first acquires that BpRefBase.
+    kRemoteAcquired = 0x00000001
+};
+
+BpRefBase::BpRefBase(const sp<IBinder>& o)
+    : mRemote(o.get()), mRefs(NULL), mState(0)
+{
+    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
+
+    if (mRemote) {
+        mRemote->incStrong(this);           // Removed on first IncStrong().
+        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
+    }
+}
+
+BpRefBase::~BpRefBase()
+{
+    if (mRemote) {
+        if (!(mState&kRemoteAcquired)) {
+            mRemote->decStrong(this);
+        }
+        mRefs->decWeak(this);
+    }
+}
+
+void BpRefBase::onFirstRef()
+{
+    android_atomic_or(kRemoteAcquired, &mState);
+}
+
+void BpRefBase::onLastStrongRef(const void* id)
+{
+    if (mRemote) {
+        mRemote->decStrong(this);
+    }
+}
+
+bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+    return mRemote ? mRefs->attemptIncStrong(this) : false;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/BpBinder.cpp b/libs/utils/BpBinder.cpp
new file mode 100644
index 0000000..69ab195
--- /dev/null
+++ b/libs/utils/BpBinder.cpp
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "BpBinder"
+//#define LOG_NDEBUG 0
+
+#include <utils/BpBinder.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+
+//#undef LOGV
+//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+BpBinder::ObjectManager::ObjectManager()
+{
+}
+
+BpBinder::ObjectManager::~ObjectManager()
+{
+    kill();
+}
+
+void BpBinder::ObjectManager::attach(
+    const void* objectID, void* object, void* cleanupCookie,
+    IBinder::object_cleanup_func func)
+{
+    entry_t e;
+    e.object = object;
+    e.cleanupCookie = cleanupCookie;
+    e.func = func;
+
+    if (mObjects.indexOfKey(objectID) >= 0) {
+        LOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
+                objectID, this,  object);
+        return;
+    }
+
+    mObjects.add(objectID, e);
+}
+
+void* BpBinder::ObjectManager::find(const void* objectID) const
+{
+    const ssize_t i = mObjects.indexOfKey(objectID);
+    if (i < 0) return NULL;
+    return mObjects.valueAt(i).object;
+}
+
+void BpBinder::ObjectManager::detach(const void* objectID)
+{
+    mObjects.removeItem(objectID);
+}
+
+void BpBinder::ObjectManager::kill()
+{
+    const size_t N = mObjects.size();
+    LOGV("Killing %d objects in manager %p", N, this);
+    for (size_t i=0; i<N; i++) {
+        const entry_t& e = mObjects.valueAt(i);
+        if (e.func != NULL) {
+            e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
+        }
+    }
+
+    mObjects.clear();
+}
+
+// ---------------------------------------------------------------------------
+
+BpBinder::BpBinder(int32_t handle)
+    : mHandle(handle)
+    , mAlive(1)
+    , mObitsSent(0)
+    , mObituaries(NULL)
+{
+    LOGV("Creating BpBinder %p handle %d\n", this, mHandle);
+
+    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
+    IPCThreadState::self()->incWeakHandle(handle);
+}
+
+String16 BpBinder::getInterfaceDescriptor() const
+{
+    String16 res;
+    Parcel send, reply;
+    status_t err = const_cast<BpBinder*>(this)->transact(
+            INTERFACE_TRANSACTION, send, &reply);
+    if (err == NO_ERROR) {
+        res = reply.readString16();
+    }
+    return res;
+}
+
+bool BpBinder::isBinderAlive() const
+{
+    return mAlive != 0;
+}
+
+status_t BpBinder::pingBinder()
+{
+    Parcel send;
+    Parcel reply;
+    status_t err = transact(PING_TRANSACTION, send, &reply);
+    if (err != NO_ERROR) return err;
+    if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
+    return (status_t)reply.readInt32();
+}
+
+status_t BpBinder::dump(int fd, const Vector<String16>& args)
+{
+    Parcel send;
+    Parcel reply;
+    send.writeFileDescriptor(fd);
+    const size_t numArgs = args.size();
+    send.writeInt32(numArgs);
+    for (size_t i = 0; i < numArgs; i++) {
+        send.writeString16(args[i]);
+    }
+    status_t err = transact(DUMP_TRANSACTION, send, &reply);
+    return err;
+}
+
+status_t BpBinder::transact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    // Once a binder has died, it will never come back to life.
+    if (mAlive) {
+        status_t status = IPCThreadState::self()->transact(
+            mHandle, code, data, reply, flags);
+        if (status == DEAD_OBJECT) mAlive = 0;
+        return status;
+    }
+
+    return DEAD_OBJECT;
+}
+
+status_t BpBinder::linkToDeath(
+    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
+{
+    Obituary ob;
+    ob.recipient = recipient;
+    ob.cookie = cookie;
+    ob.flags = flags;
+
+    LOG_ALWAYS_FATAL_IF(recipient == NULL,
+                        "linkToDeath(): recipient must be non-NULL");
+
+    {
+        AutoMutex _l(mLock);
+
+        if (!mObitsSent) {
+            if (!mObituaries) {
+                mObituaries = new Vector<Obituary>;
+                if (!mObituaries) {
+                    return NO_MEMORY;
+                }
+                LOGV("Requesting death notification: %p handle %d\n", this, mHandle);
+                getWeakRefs()->incWeak(this);
+                IPCThreadState* self = IPCThreadState::self();
+                self->requestDeathNotification(mHandle, this);
+                self->flushCommands();
+            }
+            ssize_t res = mObituaries->add(ob);
+            return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
+        }
+    }
+
+    return DEAD_OBJECT;
+}
+
+status_t BpBinder::unlinkToDeath(
+    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
+    wp<DeathRecipient>* outRecipient)
+{
+    AutoMutex _l(mLock);
+
+    if (mObitsSent) {
+        return DEAD_OBJECT;
+    }
+
+    const size_t N = mObituaries ? mObituaries->size() : 0;
+    for (size_t i=0; i<N; i++) {
+        const Obituary& obit = mObituaries->itemAt(i);
+        if ((obit.recipient == recipient
+                    || (recipient == NULL && obit.cookie == cookie))
+                && obit.flags == flags) {
+            const uint32_t allFlags = obit.flags|flags;
+            if (outRecipient != NULL) {
+                *outRecipient = mObituaries->itemAt(i).recipient;
+            }
+            mObituaries->removeAt(i);
+            if (mObituaries->size() == 0) {
+                LOGV("Clearing death notification: %p handle %d\n", this, mHandle);
+                IPCThreadState* self = IPCThreadState::self();
+                self->clearDeathNotification(mHandle, this);
+                self->flushCommands();
+                delete mObituaries;
+                mObituaries = NULL;
+            }
+            return NO_ERROR;
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+void BpBinder::sendObituary()
+{
+    LOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
+        this, mHandle, mObitsSent ? "true" : "false");
+
+    mAlive = 0;
+    if (mObitsSent) return;
+
+    mLock.lock();
+    Vector<Obituary>* obits = mObituaries;
+    if(obits != NULL) {
+        LOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
+        IPCThreadState* self = IPCThreadState::self();
+        self->clearDeathNotification(mHandle, this);
+        self->flushCommands();
+        mObituaries = NULL;
+    }
+    mObitsSent = 1;
+    mLock.unlock();
+
+    LOGV("Reporting death of proxy %p for %d recipients\n",
+        this, obits ? obits->size() : 0);
+
+    if (obits != NULL) {
+        const size_t N = obits->size();
+        for (size_t i=0; i<N; i++) {
+            reportOneDeath(obits->itemAt(i));
+        }
+
+        delete obits;
+    }
+}
+
+void BpBinder::reportOneDeath(const Obituary& obit)
+{
+    sp<DeathRecipient> recipient = obit.recipient.promote();
+    LOGV("Reporting death to recipient: %p\n", recipient.get());
+    if (recipient == NULL) return;
+
+    recipient->binderDied(this);
+}
+
+
+void BpBinder::attachObject(
+    const void* objectID, void* object, void* cleanupCookie,
+    object_cleanup_func func)
+{
+    AutoMutex _l(mLock);
+    LOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
+    mObjects.attach(objectID, object, cleanupCookie, func);
+}
+
+void* BpBinder::findObject(const void* objectID) const
+{
+    AutoMutex _l(mLock);
+    return mObjects.find(objectID);
+}
+
+void BpBinder::detachObject(const void* objectID)
+{
+    AutoMutex _l(mLock);
+    mObjects.detach(objectID);
+}
+
+BpBinder* BpBinder::remoteBinder()
+{
+    return this;
+}
+
+BpBinder::~BpBinder()
+{
+    LOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
+
+    IPCThreadState* ipc = IPCThreadState::self();
+
+    mLock.lock();
+    Vector<Obituary>* obits = mObituaries;
+    if(obits != NULL) {
+        if (ipc) ipc->clearDeathNotification(mHandle, this);
+        mObituaries = NULL;
+    }
+    mLock.unlock();
+
+    if (obits != NULL) {
+        // XXX Should we tell any remaining DeathRecipient
+        // objects that the last strong ref has gone away, so they
+        // are no longer linked?
+        delete obits;
+    }
+
+    if (ipc) {
+        ipc->expungeHandle(mHandle, this);
+        ipc->decWeakHandle(mHandle);
+    }
+}
+
+void BpBinder::onFirstRef()
+{
+    LOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
+    IPCThreadState* ipc = IPCThreadState::self();
+    if (ipc) ipc->incStrongHandle(mHandle);
+}
+
+void BpBinder::onLastStrongRef(const void* id)
+{
+    LOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
+    IF_LOGV() {
+        printRefs();
+    }
+    IPCThreadState* ipc = IPCThreadState::self();
+    if (ipc) ipc->decStrongHandle(mHandle);
+}
+
+bool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+    LOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
+    IPCThreadState* ipc = IPCThreadState::self();
+    return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/BufferedTextOutput.cpp b/libs/utils/BufferedTextOutput.cpp
new file mode 100644
index 0000000..989662e
--- /dev/null
+++ b/libs/utils/BufferedTextOutput.cpp
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/BufferedTextOutput.h>
+
+#include <utils/Atomic.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <cutils/threads.h>
+
+#include <private/utils/Static.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+struct BufferedTextOutput::BufferState : public RefBase
+{
+    BufferState(int32_t _seq)
+        : seq(_seq)
+        , buffer(NULL)
+        , bufferPos(0)
+        , bufferSize(0)
+        , atFront(true)
+        , indent(0)
+        , bundle(0) {
+    }
+    ~BufferState() {
+        free(buffer);
+    }
+    
+    status_t append(const char* txt, size_t len) {
+        if ((len+bufferPos) > bufferSize) {
+            void* b = realloc(buffer, ((len+bufferPos)*3)/2);
+            if (!b) return NO_MEMORY;
+            buffer = (char*)b;
+        }
+        memcpy(buffer+bufferPos, txt, len);
+        bufferPos += len;
+        return NO_ERROR;
+    }
+    
+    void restart() {
+        bufferPos = 0;
+        atFront = true;
+        if (bufferSize > 256) {
+            void* b = realloc(buffer, 256);
+            if (b) {
+                buffer = (char*)b;
+                bufferSize = 256;
+            }
+        }
+    }
+    
+    const int32_t seq;
+    char* buffer;
+    size_t bufferPos;
+    size_t bufferSize;
+    bool atFront;
+    int32_t indent;
+    int32_t bundle;
+};
+
+struct BufferedTextOutput::ThreadState
+{
+    Vector<sp<BufferedTextOutput::BufferState> > states;
+};
+
+static mutex_t          gMutex;
+
+static thread_store_t   tls;
+
+BufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState()
+{
+    ThreadState*  ts = (ThreadState*) thread_store_get( &tls );
+    if (ts) return ts;
+    ts = new ThreadState;
+    thread_store_set( &tls, ts, threadDestructor );
+    return ts;
+}
+
+void BufferedTextOutput::threadDestructor(void *st)
+{
+    delete ((ThreadState*)st);
+}
+
+static volatile int32_t gSequence = 0;
+
+static volatile int32_t gFreeBufferIndex = -1;
+
+static int32_t allocBufferIndex()
+{
+    int32_t res = -1;
+    
+    mutex_lock(&gMutex);
+    
+    if (gFreeBufferIndex >= 0) {
+        res = gFreeBufferIndex;
+        gFreeBufferIndex = gTextBuffers[res];
+        gTextBuffers.editItemAt(res) = -1;
+
+    } else {
+        res = gTextBuffers.size();
+        gTextBuffers.add(-1);
+    }
+
+    mutex_unlock(&gMutex);
+    
+    return res;
+}
+
+static void freeBufferIndex(int32_t idx)
+{
+    mutex_lock(&gMutex);
+    gTextBuffers.editItemAt(idx) = gFreeBufferIndex;
+    gFreeBufferIndex = idx;
+    mutex_unlock(&gMutex);
+}
+
+// ---------------------------------------------------------------------------
+
+BufferedTextOutput::BufferedTextOutput(uint32_t flags)
+    : mFlags(flags)
+    , mSeq(android_atomic_inc(&gSequence))
+    , mIndex(allocBufferIndex())
+{
+    mGlobalState = new BufferState(mSeq);
+    if (mGlobalState) mGlobalState->incStrong(this);
+}
+    
+BufferedTextOutput::~BufferedTextOutput()
+{
+    if (mGlobalState) mGlobalState->decStrong(this);
+    freeBufferIndex(mIndex);
+}
+
+status_t BufferedTextOutput::print(const char* txt, size_t len)
+{
+    //printf("BufferedTextOutput: printing %d\n", len);
+    
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    
+    const char* const end = txt+len;
+    
+    status_t err;
+
+    while (txt < end) {
+        // Find the next line.
+        const char* first = txt;
+        while (txt < end && *txt != '\n') txt++;
+        
+        // Include this and all following empty lines.
+        while (txt < end && *txt == '\n') txt++;
+        
+        // Special cases for first data on a line.
+        if (b->atFront) {
+            if (b->indent > 0) {
+                // If this is the start of a line, add the indent.
+                const char* prefix = stringForIndent(b->indent);
+                err = b->append(prefix, strlen(prefix));
+                if (err != NO_ERROR) return err;
+                
+            } else if (*(txt-1) == '\n' && !b->bundle) {
+                // Fast path: if we are not indenting or bundling, and
+                // have been given one or more complete lines, just write
+                // them out without going through the buffer.
+                
+                // Slurp up all of the lines.
+                const char* lastLine = txt+1;
+                while (txt < end) {
+                    if (*txt++ == '\n') lastLine = txt;
+                }
+                struct iovec vec;
+                vec.iov_base = (void*)first;
+                vec.iov_len = lastLine-first;
+                //printf("Writing %d bytes of data!\n", vec.iov_len);
+                writeLines(vec, 1);
+                txt = lastLine;
+                continue;
+            }
+        }
+        
+        // Append the new text to the buffer.
+        err = b->append(first, txt-first);
+        if (err != NO_ERROR) return err;
+        b->atFront = *(txt-1) == '\n';
+        
+        // If we have finished a line and are not bundling, write
+        // it out.
+        //printf("Buffer is now %d bytes\n", b->bufferPos);
+        if (b->atFront && !b->bundle) {
+            struct iovec vec;
+            vec.iov_base = b->buffer;
+            vec.iov_len = b->bufferPos;
+            //printf("Writing %d bytes of data!\n", vec.iov_len);
+            writeLines(vec, 1);
+            b->restart();
+        }
+    }
+    
+    return NO_ERROR;
+}
+
+void BufferedTextOutput::moveIndent(int delta)
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->indent += delta;
+    if (b->indent < 0) b->indent = 0;
+}
+
+void BufferedTextOutput::pushBundle()
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->bundle++;
+}
+
+void BufferedTextOutput::popBundle()
+{
+    AutoMutex _l(mLock);
+    BufferState* b = getBuffer();
+    b->bundle--;
+    LOG_FATAL_IF(b->bundle < 0,
+        "TextOutput::popBundle() called more times than pushBundle()");
+    if (b->bundle < 0) b->bundle = 0;
+    
+    if (b->bundle == 0) {
+        // Last bundle, write out data if it is complete.  If it is not
+        // complete, don't write until the last line is done... this may
+        // or may not be the write thing to do, but it's the easiest.
+        if (b->bufferPos > 0 && b->atFront) {
+            struct iovec vec;
+            vec.iov_base = b->buffer;
+            vec.iov_len = b->bufferPos;
+            writeLines(vec, 1);
+            b->restart();
+        }
+    }
+}
+
+BufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const
+{
+    if ((mFlags&MULTITHREADED) != 0) {
+        ThreadState* ts = getThreadState();
+        if (ts) {
+            while (ts->states.size() <= (size_t)mIndex) ts->states.add(NULL);
+            BufferState* bs = ts->states[mIndex].get();
+            if (bs != NULL && bs->seq == mSeq) return bs;
+            
+            ts->states.editItemAt(mIndex) = new BufferState(mIndex);
+            bs = ts->states[mIndex].get();
+            if (bs != NULL) return bs;
+        }
+    }
+    
+    return mGlobalState;
+}
+
+}; // namespace android
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
new file mode 100644
index 0000000..4968666
--- /dev/null
+++ b/libs/utils/CallStack.cpp
@@ -0,0 +1,335 @@
+/*
+ * 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 "CallStack"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if HAVE_DLADDR
+#include <dlfcn.h>
+#endif
+
+#if HAVE_CXXABI
+#include <cxxabi.h>
+#endif
+
+#include <unwind.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/CallStack.h>
+#include <utils/threads.h>
+
+
+/*****************************************************************************/
+namespace android {
+
+
+typedef struct {
+    size_t count;
+    size_t ignore;
+    const void** addrs;
+} stack_crawl_state_t;
+
+static
+_Unwind_Reason_Code trace_function(_Unwind_Context *context, void *arg)
+{
+    stack_crawl_state_t* state = (stack_crawl_state_t*)arg;
+    if (state->count) {
+        void* ip = (void*)_Unwind_GetIP(context);
+        if (ip) {
+            if (state->ignore) {
+                state->ignore--;
+            } else {
+                state->addrs[0] = ip; 
+                state->addrs++;
+                state->count--;
+            }
+        }
+    }
+    return _URC_NO_REASON;
+}
+
+static
+int backtrace(const void** addrs, size_t ignore, size_t size)
+{
+    stack_crawl_state_t state;
+    state.count = size;
+    state.ignore = ignore;
+    state.addrs = addrs;
+    _Unwind_Backtrace(trace_function, (void*)&state);
+    return size - state.count;
+}
+
+/*****************************************************************************/
+
+static 
+const char *lookup_symbol(const void* addr, uint32_t *offset, char* name, size_t bufSize)
+{
+#if HAVE_DLADDR
+	Dl_info info;
+	if (dladdr(addr, &info)) {
+		*offset = (uint32_t)info.dli_saddr;
+		return info.dli_sname;
+	}
+#endif
+	return NULL;
+}
+
+static 
+int32_t linux_gcc_demangler(const char *mangled_name, char *unmangled_name, size_t buffersize)
+{
+	size_t out_len = 0;
+#if HAVE_CXXABI
+	int status = 0;
+	char *demangled = abi::__cxa_demangle(mangled_name, 0, &out_len, &status);
+	if (status == 0) {
+		// OK
+		if (out_len < buffersize) memcpy(unmangled_name, demangled, out_len);
+		else out_len = 0;
+		free(demangled);
+	} else {
+		out_len = 0;
+	}
+#endif
+	return out_len;
+}
+
+/*****************************************************************************/
+
+class MapInfo {
+    struct mapinfo {
+        struct mapinfo *next;
+        unsigned start;
+        unsigned end;
+        char name[];
+    };
+
+    const char *map_to_name(unsigned pc, const char* def) {
+        mapinfo* mi = getMapInfoList();
+        while(mi) {
+            if ((pc >= mi->start) && (pc < mi->end))
+                return mi->name;
+            mi = mi->next;
+        }
+        return def;
+    }
+
+    mapinfo *parse_maps_line(char *line) {
+        mapinfo *mi;
+        int len = strlen(line);
+        if (len < 1) return 0;
+        line[--len] = 0;
+        if (len < 50) return 0;
+        if (line[20] != 'x') return 0;
+        mi = (mapinfo*)malloc(sizeof(mapinfo) + (len - 47));
+        if (mi == 0) return 0;
+        mi->start = strtoul(line, 0, 16);
+        mi->end = strtoul(line + 9, 0, 16);
+        mi->next = 0;
+        strcpy(mi->name, line + 49);
+        return mi;
+    }
+
+    mapinfo* getMapInfoList() {
+        Mutex::Autolock _l(mLock);
+        if (milist == 0) {
+            char data[1024];
+            FILE *fp;
+            sprintf(data, "/proc/%d/maps", getpid());
+            fp = fopen(data, "r");
+            if (fp) {
+                while(fgets(data, 1024, fp)) {
+                    mapinfo *mi = parse_maps_line(data);
+                    if(mi) {
+                        mi->next = milist;
+                        milist = mi;
+                    }
+                }
+                fclose(fp);
+            }
+        }
+        return milist;
+    }
+    mapinfo*    milist;
+    Mutex       mLock;
+    static MapInfo sMapInfo;
+
+public:
+    MapInfo()
+     : milist(0) {
+    }
+
+    ~MapInfo() {
+        while (milist) {
+            mapinfo *next = milist->next;
+            free(milist);
+            milist = next;
+        }
+    }
+    
+    static const char *mapAddressToName(const void* pc, const char* def) {
+        return sMapInfo.map_to_name((unsigned)pc, def);
+    }
+
+};
+
+/*****************************************************************************/
+
+MapInfo MapInfo::sMapInfo;
+
+/*****************************************************************************/
+
+CallStack::CallStack()
+    : mCount(0)
+{
+}
+
+CallStack::CallStack(const CallStack& rhs)
+    : mCount(rhs.mCount)
+{
+    if (mCount) {
+        memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
+    }
+}
+
+CallStack::~CallStack()
+{
+}
+
+CallStack& CallStack::operator = (const CallStack& rhs)
+{
+    mCount = rhs.mCount;
+    if (mCount) {
+        memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
+    }
+    return *this;
+}
+
+bool CallStack::operator == (const CallStack& rhs) const {
+    if (mCount != rhs.mCount)
+        return false;
+    return !mCount || (memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) == 0);
+}
+
+bool CallStack::operator != (const CallStack& rhs) const {
+    return !operator == (rhs);
+}
+
+bool CallStack::operator < (const CallStack& rhs) const {
+    if (mCount != rhs.mCount)
+        return mCount < rhs.mCount;
+    return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) < 0;
+}
+
+bool CallStack::operator >= (const CallStack& rhs) const {
+    return !operator < (rhs);
+}
+
+bool CallStack::operator > (const CallStack& rhs) const {
+    if (mCount != rhs.mCount)
+        return mCount > rhs.mCount;
+    return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) > 0;
+}
+
+bool CallStack::operator <= (const CallStack& rhs) const {
+    return !operator > (rhs);
+}
+
+const void* CallStack::operator [] (int index) const {
+    if (index >= int(mCount))
+        return 0;
+    return mStack[index];
+}
+
+
+void CallStack::clear()
+{
+    mCount = 0;
+}
+
+void CallStack::update(int32_t ignoreDepth, int32_t maxDepth)
+{
+    if (maxDepth > MAX_DEPTH)
+        maxDepth = MAX_DEPTH;
+    mCount = backtrace(mStack, ignoreDepth, maxDepth);
+}
+
+// Return the stack frame name on the designated level
+String8 CallStack::toStringSingleLevel(const char* prefix, int32_t level) const
+{
+    String8 res;
+    char namebuf[1024];
+    char tmp[256];
+    char tmp1[32];
+    char tmp2[32];
+    uint32_t offs;
+
+    const void* ip = mStack[level];
+    if (!ip) return res;
+
+    if (prefix) res.append(prefix);
+    snprintf(tmp1, 32, "#%02d  ", level);
+    res.append(tmp1);
+
+    const char* name = lookup_symbol(ip, &offs, namebuf, sizeof(namebuf));
+    if (name) {
+        if (linux_gcc_demangler(name, tmp, 256) != 0)
+            name = tmp;
+        snprintf(tmp1, 32, "0x%08x: <", (size_t)ip);
+        snprintf(tmp2, 32, ">+0x%08x", offs);
+        res.append(tmp1);
+        res.append(name);
+        res.append(tmp2);
+    } else { 
+        name = MapInfo::mapAddressToName(ip, "<unknown>");
+        snprintf(tmp, 256, "pc %08x  %s", (size_t)ip, name);
+        res.append(tmp);
+    }
+    res.append("\n");
+
+    return res;
+}
+
+// Dump a stack trace to the log
+void CallStack::dump(const char* prefix) const
+{
+    /* 
+     * Sending a single long log may be truncated since the stack levels can
+     * get very deep. So we request function names of each frame individually.
+     */
+    for (int i=0; i<int(mCount); i++) {
+        LOGD("%s", toStringSingleLevel(prefix, i).string());
+    }
+}
+
+// Return a string (possibly very long) containing the complete stack trace
+String8 CallStack::toString(const char* prefix) const
+{
+    String8 res;
+
+    for (int i=0; i<int(mCount); i++) {
+        res.append(toStringSingleLevel(prefix, i).string());
+    }
+
+    return res;
+}
+
+/*****************************************************************************/
+
+}; // namespace android
diff --git a/libs/utils/Debug.cpp b/libs/utils/Debug.cpp
new file mode 100644
index 0000000..f7988ec
--- /dev/null
+++ b/libs/utils/Debug.cpp
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/Debug.h>
+
+#include <utils/misc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------
+
+static const char indentStr[] =
+"                                                                            "
+"                                                                            ";
+
+const char* stringForIndent(int32_t indentLevel)
+{
+    ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
+    return indentStr + (off < 0 ? 0 : off);
+}
+
+// ---------------------------------------------------------------------
+
+static void defaultPrintFunc(void* cookie, const char* txt)
+{
+    printf("%s", txt);
+}
+
+// ---------------------------------------------------------------------
+
+static inline int isident(int c)
+{
+    return isalnum(c) || c == '_';
+}
+
+static inline bool isasciitype(char c)
+{
+    if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
+    return false;
+}
+
+static inline char makehexdigit(uint32_t val)
+{
+    return "0123456789abcdef"[val&0xF];
+}
+
+static char* appendhexnum(uint32_t val, char* out)
+{
+    for( int32_t i=28; i>=0; i-=4 ) {
+        *out++ = makehexdigit( val>>i );
+    }
+    *out = 0;
+    return out;
+}
+
+static inline char makeupperhexdigit(uint32_t val)
+{
+    return "0123456789ABCDEF"[val&0xF];
+}
+
+static char* appendupperhexnum(uint32_t val, char* out)
+{
+    for( int32_t i=28; i>=0; i-=4 ) {
+        *out++ = makeupperhexdigit( val>>i );
+    }
+    *out = 0;
+    return out;
+}
+
+static char* appendcharornum(char c, char* out, bool skipzero = true)
+{
+    if (skipzero && c == 0) return out;
+
+    if (isasciitype(c)) {
+        *out++ = c;
+        return out;
+    }
+
+    *out++ = '\\';
+    *out++ = 'x';
+    *out++ = makehexdigit(c>>4);
+    *out++ = makehexdigit(c);
+    return out;
+}
+
+static char* typetostring(uint32_t type, char* out,
+                          bool fullContext = true,
+                          bool strict = false)
+{
+    char* pos = out;
+    char c[4];
+    c[0] = (char)((type>>24)&0xFF);
+    c[1] = (char)((type>>16)&0xFF);
+    c[2] = (char)((type>>8)&0xFF);
+    c[3] = (char)(type&0xFF);
+    bool valid;
+    if( !strict ) {
+        // now even less strict!
+        // valid = isasciitype(c[3]);
+        valid = true;
+        int32_t i = 0;
+        bool zero = true;
+        while (valid && i<3) {
+            if (c[i] == 0) {
+                if (!zero) valid = false;
+            } else {
+                zero = false;
+                //if (!isasciitype(c[i])) valid = false;
+            }
+            i++;
+        }
+        // if all zeros, not a valid type code.
+        if (zero) valid = false;
+    } else {
+        valid = isident(c[3]) ? true : false;
+        int32_t i = 0;
+        bool zero = true;
+        while (valid && i<3) {
+            if (c[i] == 0) {
+                if (!zero) valid = false;
+            } else {
+                zero = false;
+                if (!isident(c[i])) valid = false;
+            }
+            i++;
+        }
+    }
+    if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
+        if( fullContext ) *pos++ = '\'';
+        pos = appendcharornum(c[0], pos);
+        pos = appendcharornum(c[1], pos);
+        pos = appendcharornum(c[2], pos);
+        pos = appendcharornum(c[3], pos);
+        if( fullContext ) *pos++ = '\'';
+        *pos = 0;
+        return pos;
+    }
+    
+    if( fullContext ) {
+        *pos++ = '0';
+        *pos++ = 'x';
+    }
+    return appendhexnum(type, pos);
+}
+
+void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
+{
+    char buffer[32];
+    char* end = typetostring(typeCode, buffer);
+    *end = 0;
+    func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
+}
+
+void printHexData(int32_t indent, const void *buf, size_t length,
+    size_t bytesPerLine, int32_t singleLineBytesCutoff,
+    size_t alignment, bool cStyle,
+    debugPrintFunc func, void* cookie)
+{
+    if (alignment == 0) {
+        if (bytesPerLine >= 16) alignment = 4;
+        else if (bytesPerLine >= 8) alignment = 2;
+        else alignment = 1;
+    }
+    if (func == NULL) func = defaultPrintFunc;
+
+    size_t offset;
+    
+    unsigned char *pos = (unsigned char *)buf;
+    
+    if (pos == NULL) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        func(cookie, "(NULL)");
+        return;
+    }
+    
+    if (length == 0) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        func(cookie, "(empty)");
+        return;
+    }
+    
+    if ((int32_t)length < 0) {
+        if (singleLineBytesCutoff < 0) func(cookie, "\n");
+        char buf[64];
+        sprintf(buf, "(bad length: %d)", length);
+        func(cookie, buf);
+        return;
+    }
+    
+    char buffer[256];
+    static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
+    
+    if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
+    
+    const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
+    bool newLine = false;
+    if (cStyle) {
+        indent++;
+        func(cookie, "{\n");
+        newLine = true;
+    } else if (!oneLine) {
+        func(cookie, "\n");
+        newLine = true;
+    }
+    
+    for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
+        long remain = length;
+
+        char* c = buffer;
+        if (!oneLine && !cStyle) {
+            sprintf(c, "0x%08x: ", (int)offset);
+            c += 12;
+        }
+
+        size_t index;
+        size_t word;
+        
+        for (word = 0; word < bytesPerLine; ) {
+
+#ifdef HAVE_LITTLE_ENDIAN
+            const size_t startIndex = word+(alignment-(alignment?1:0));
+            const ssize_t dir = -1;
+#else
+            const size_t startIndex = word;
+            const ssize_t dir = 1;
+#endif
+
+            for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
+            
+                if (!cStyle) {
+                    if (index == 0 && word > 0 && alignment > 0) {
+                        *c++ = ' ';
+                    }
+                
+                    if (remain-- > 0) {
+                        const unsigned char val = *(pos+startIndex+(index*dir));
+                        *c++ = makehexdigit(val>>4);
+                        *c++ = makehexdigit(val);
+                    } else if (!oneLine) {
+                        *c++ = ' ';
+                        *c++ = ' ';
+                    }
+                } else {
+                    if (remain > 0) {
+                        if (index == 0 && word > 0) {
+                            *c++ = ',';
+                            *c++ = ' ';
+                        }
+                        if (index == 0) {
+                            *c++ = '0';
+                            *c++ = 'x';
+                        }
+                        const unsigned char val = *(pos+startIndex+(index*dir));
+                        *c++ = makehexdigit(val>>4);
+                        *c++ = makehexdigit(val);
+                        remain--;
+                    }
+                }
+            }
+            
+            word += index;
+        }
+
+        if (!cStyle) {
+            remain = length;
+            *c++ = ' ';
+            *c++ = '\'';
+            for (index = 0; index < bytesPerLine; index++) {
+
+                if (remain-- > 0) {
+                    const unsigned char val = pos[index];
+                    *c++ = (val >= ' ' && val < 127) ? val : '.';
+                } else if (!oneLine) {
+                    *c++ = ' ';
+                }
+            }
+            
+            *c++ = '\'';
+            if (length > bytesPerLine) *c++ = '\n';
+        } else {
+            if (remain > 0) *c++ = ',';
+            *c++ = '\n';
+        }
+
+        if (newLine && indent) func(cookie, stringForIndent(indent));
+        *c = 0;
+        func(cookie, buffer);
+        newLine = true;
+        
+        if (length <= bytesPerLine) break;
+        length -= bytesPerLine;
+    }
+
+    if (cStyle) {
+        if (indent > 0) func(cookie, stringForIndent(indent-1));
+        func(cookie, "};");
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/utils/FileMap.cpp b/libs/utils/FileMap.cpp
new file mode 100644
index 0000000..e1ba9b2
--- /dev/null
+++ b/libs/utils/FileMap.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Shared file mapping class.
+//
+
+#define LOG_TAG "filemap"
+
+#include <utils/FileMap.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_POSIX_FILEMAP
+#include <sys/mman.h>
+#endif
+
+#include <string.h>
+#include <memory.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*static*/ long FileMap::mPageSize = -1;
+
+
+/*
+ * Constructor.  Create an empty object.
+ */
+FileMap::FileMap(void)
+    : mRefCount(1), mFileName(NULL), mBasePtr(NULL), mBaseLength(0),
+      mDataPtr(NULL), mDataLength(0)
+{
+}
+
+/*
+ * Destructor.
+ */
+FileMap::~FileMap(void)
+{
+    assert(mRefCount == 0);
+
+    //printf("+++ removing FileMap %p %u\n", mDataPtr, mDataLength);
+
+    mRefCount = -100;       // help catch double-free
+    if (mFileName != NULL) {
+        free(mFileName);
+    }
+#ifdef HAVE_POSIX_FILEMAP    
+    if (munmap(mBasePtr, mBaseLength) != 0) {
+        LOGD("munmap(%p, %d) failed\n", mBasePtr, (int) mBaseLength);
+    }
+#endif
+#ifdef HAVE_WIN32_FILEMAP
+    if ( UnmapViewOfFile(mBasePtr) == 0) {
+        LOGD("UnmapViewOfFile(%p) failed, error = %ld\n", mBasePtr, 
+              GetLastError() );
+    }
+    CloseHandle(mFileMapping);
+    CloseHandle(mFileHandle);
+#endif
+}
+
+
+/*
+ * Create a new mapping on an open file.
+ *
+ * Closing the file descriptor does not unmap the pages, so we don't
+ * claim ownership of the fd.
+ *
+ * Returns "false" on failure.
+ */
+bool FileMap::create(const char* origFileName, int fd, off_t offset, size_t length, bool readOnly)
+{
+#ifdef HAVE_WIN32_FILEMAP
+    int     adjust;
+    off_t   adjOffset;
+    size_t  adjLength;
+
+    if (mPageSize == -1) {
+        SYSTEM_INFO  si;
+        
+        GetSystemInfo( &si );
+        mPageSize = si.dwAllocationGranularity;
+    }
+
+    DWORD  protect = readOnly ? PAGE_READONLY : PAGE_READWRITE;
+    
+    mFileHandle  = (HANDLE) _get_osfhandle(fd);
+    mFileMapping = CreateFileMapping( mFileHandle, NULL, protect, 0, 0, NULL);
+    if (mFileMapping == NULL) {
+        LOGE("CreateFileMapping(%p, %lx) failed with error %ld\n",
+              mFileHandle, protect, GetLastError() );
+        return false;
+    }
+    
+    adjust    = offset % mPageSize;
+    adjOffset = offset - adjust;
+    adjLength = length + adjust;
+    
+    mBasePtr = MapViewOfFile( mFileMapping, 
+                              readOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,
+                              0,
+                              (DWORD)(adjOffset),
+                              adjLength );
+    if (mBasePtr == NULL) {
+        LOGE("MapViewOfFile(%ld, %ld) failed with error %ld\n",
+              adjOffset, adjLength, GetLastError() );
+        CloseHandle(mFileMapping);
+        mFileMapping = INVALID_HANDLE_VALUE;
+        return false;
+    }
+#endif
+#ifdef HAVE_POSIX_FILEMAP
+    int     prot, flags, adjust;
+    off_t   adjOffset;
+    size_t  adjLength;
+
+    void* ptr;
+
+    assert(mRefCount == 1);
+    assert(fd >= 0);
+    assert(offset >= 0);
+    assert(length > 0);
+
+    /* init on first use */
+    if (mPageSize == -1) {
+#if NOT_USING_KLIBC
+        mPageSize = sysconf(_SC_PAGESIZE);
+        if (mPageSize == -1) {
+            LOGE("could not get _SC_PAGESIZE\n");
+            return false;
+        }
+#else
+        /* this holds for Linux, Darwin, Cygwin, and doesn't pain the ARM */
+        mPageSize = 4096;
+#endif
+    }
+
+    adjust   = offset % mPageSize;
+try_again:
+    adjOffset = offset - adjust;
+    adjLength = length + adjust;
+
+    flags = MAP_SHARED;
+    prot = PROT_READ;
+    if (!readOnly)
+        prot |= PROT_WRITE;
+
+    ptr = mmap(NULL, adjLength, prot, flags, fd, adjOffset);
+    if (ptr == MAP_FAILED) {
+    	// Cygwin does not seem to like file mapping files from an offset.
+    	// So if we fail, try again with offset zero
+    	if (adjOffset > 0) {
+    		adjust = offset;
+    		goto try_again;
+    	}
+    
+        LOGE("mmap(%ld,%ld) failed: %s\n",
+            (long) adjOffset, (long) adjLength, strerror(errno));
+        return false;
+    }
+    mBasePtr = ptr;
+#endif /* HAVE_POSIX_FILEMAP */
+
+    mFileName = origFileName != NULL ? strdup(origFileName) : NULL;
+    mBaseLength = adjLength;
+    mDataOffset = offset;
+    mDataPtr = (char*) mBasePtr + adjust;
+    mDataLength = length;
+
+    assert(mBasePtr != NULL);
+
+    LOGV("MAP: base %p/%d data %p/%d\n",
+        mBasePtr, (int) mBaseLength, mDataPtr, (int) mDataLength);
+
+    return true;
+}
+
+/*
+ * Provide guidance to the system.
+ */
+int FileMap::advise(MapAdvice advice)
+{
+#if HAVE_MADVISE
+    int cc, sysAdvice;
+
+    switch (advice) {
+        case NORMAL:        sysAdvice = MADV_NORMAL;        break;
+        case RANDOM:        sysAdvice = MADV_RANDOM;        break;
+        case SEQUENTIAL:    sysAdvice = MADV_SEQUENTIAL;    break;
+        case WILLNEED:      sysAdvice = MADV_WILLNEED;      break;
+        case DONTNEED:      sysAdvice = MADV_DONTNEED;      break;
+        default:
+                            assert(false);
+                            return -1;
+    }
+
+    cc = madvise(mBasePtr, mBaseLength, sysAdvice);
+    if (cc != 0)
+        LOGW("madvise(%d) failed: %s\n", sysAdvice, strerror(errno));
+    return cc;
+#else
+	return -1;
+#endif // HAVE_MADVISE
+}
diff --git a/libs/utils/IDataConnection.cpp b/libs/utils/IDataConnection.cpp
new file mode 100644
index 0000000..c6d49aa
--- /dev/null
+++ b/libs/utils/IDataConnection.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/Parcel.h>
+
+#include <utils/IDataConnection.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+enum
+{
+    CONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+    DISCONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1
+};
+
+class BpDataConnection : public BpInterface<IDataConnection>
+{
+public:
+    BpDataConnection::BpDataConnection(const sp<IBinder>& impl)
+        : BpInterface<IDataConnection>(impl)
+    {
+    }
+
+	virtual void connect()
+	{
+		Parcel data, reply;
+        data.writeInterfaceToken(IDataConnection::descriptor());
+		remote()->transact(CONNECT_TRANSACTION, data, &reply);
+	}
+	
+	virtual void disconnect()
+	{
+		Parcel data, reply;
+		remote()->transact(DISCONNECT_TRANSACTION, data, &reply);
+	}
+};
+
+IMPLEMENT_META_INTERFACE(DataConnection, "android.utils.IDataConnection");
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnDataConnection::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code)
+    {
+		case CONNECT_TRANSACTION:
+		{                   
+            CHECK_INTERFACE(IDataConnection, data, reply);
+			connect();
+			return NO_ERROR;
+		}    
+		
+		case DISCONNECT_TRANSACTION:
+		{                   
+            CHECK_INTERFACE(IDataConnection, data, reply);
+			disconnect();
+			return NO_ERROR;
+		}
+       
+		default:
+			return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/IInterface.cpp b/libs/utils/IInterface.cpp
new file mode 100644
index 0000000..6ea8178
--- /dev/null
+++ b/libs/utils/IInterface.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/IInterface.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+sp<IBinder> IInterface::asBinder()
+{
+    return this ? onAsBinder() : NULL;
+}
+
+sp<const IBinder> IInterface::asBinder() const
+{
+    return this ? const_cast<IInterface*>(this)->onAsBinder() : NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/utils/IMemory.cpp b/libs/utils/IMemory.cpp
new file mode 100644
index 0000000..429bc2b
--- /dev/null
+++ b/libs/utils/IMemory.cpp
@@ -0,0 +1,486 @@
+/*
+ * 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 "IMemory"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <utils/IMemory.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <utils/Parcel.h>
+#include <utils/CallStack.h>
+
+#define VERBOSE   0
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class HeapCache : public IBinder::DeathRecipient
+{
+public:
+    HeapCache();
+    virtual ~HeapCache();
+    
+    virtual void binderDied(const wp<IBinder>& who);
+
+    sp<IMemoryHeap> find_heap(const sp<IBinder>& binder); 
+    void pin_heap(const sp<IBinder>& binder); 
+    void free_heap(const sp<IBinder>& binder); 
+    sp<IMemoryHeap> get_heap(const sp<IBinder>& binder);
+    void dump_heaps();
+
+private:
+    // For IMemory.cpp
+    struct heap_info_t {
+        sp<IMemoryHeap> heap;
+        int32_t         count;
+    };
+
+    void free_heap(const wp<IBinder>& binder); 
+
+    Mutex mHeapCacheLock;
+    KeyedVector< wp<IBinder>, heap_info_t > mHeapCache;
+};
+
+static sp<HeapCache> gHeapCache = new HeapCache();
+
+/******************************************************************************/
+
+enum {
+    HEAP_ID = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpMemoryHeap : public BpInterface<IMemoryHeap>
+{
+public:
+    BpMemoryHeap(const sp<IBinder>& impl);
+    virtual ~BpMemoryHeap();
+
+    virtual int getHeapID() const;
+    virtual void* getBase() const;
+    virtual size_t getSize() const;
+    virtual uint32_t getFlags() const;
+
+private:
+    friend class IMemory;
+    friend class HeapCache;
+    
+    // for debugging in this module
+    static inline sp<IMemoryHeap> find_heap(const sp<IBinder>& binder) {
+        return gHeapCache->find_heap(binder);
+    }
+    static inline void free_heap(const sp<IBinder>& binder) {
+        gHeapCache->free_heap(binder);
+    }
+    static inline sp<IMemoryHeap> get_heap(const sp<IBinder>& binder) {
+        return gHeapCache->get_heap(binder);
+    }
+    static inline void dump_heaps() {
+        gHeapCache->dump_heaps();       
+    }
+    void inline pin_heap() const {
+        gHeapCache->pin_heap(const_cast<BpMemoryHeap*>(this)->asBinder());
+    }
+
+    void assertMapped() const;
+    void assertReallyMapped() const;
+    void pinHeap() const;
+
+    mutable volatile int32_t mHeapId;
+    mutable void*       mBase;
+    mutable size_t      mSize;
+    mutable uint32_t    mFlags;
+    mutable bool        mRealHeap;
+    mutable Mutex       mLock;
+};
+
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_MEMORY = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpMemory : public BpInterface<IMemory>
+{
+public:
+    BpMemory(const sp<IBinder>& impl);
+    virtual ~BpMemory();
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const;
+    
+private:
+    mutable sp<IMemoryHeap> mHeap;
+    mutable ssize_t mOffset;
+    mutable size_t mSize;
+};
+
+/******************************************************************************/
+
+void* IMemory::fastPointer(const sp<IBinder>& binder, ssize_t offset) const
+{
+    sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder);
+    void* const base = realHeap->base();
+    if (base == MAP_FAILED)
+        return 0;
+    return static_cast<char*>(base) + offset;
+}
+
+void* IMemory::pointer() const {
+    ssize_t offset;
+    sp<IMemoryHeap> heap = getMemory(&offset);
+    void* const base = heap!=0 ? heap->base() : MAP_FAILED;
+    if (base == MAP_FAILED)
+        return 0;
+    return static_cast<char*>(base) + offset;
+}
+
+size_t IMemory::size() const {
+    size_t size;
+    getMemory(NULL, &size);
+    return size;
+}
+
+ssize_t IMemory::offset() const {
+    ssize_t offset;
+    getMemory(&offset);
+    return offset;
+}
+
+/******************************************************************************/
+
+BpMemory::BpMemory(const sp<IBinder>& impl)
+    : BpInterface<IMemory>(impl), mOffset(0), mSize(0)
+{
+}
+
+BpMemory::~BpMemory()
+{
+}
+
+sp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (mHeap == 0) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMemory::getInterfaceDescriptor());
+        if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) {
+            sp<IBinder> heap = reply.readStrongBinder();
+            ssize_t o = reply.readInt32();
+            size_t s = reply.readInt32();
+            if (heap != 0) {
+                mHeap = interface_cast<IMemoryHeap>(heap);
+                if (mHeap != 0) {
+                    mOffset = o;
+                    mSize = s;
+                }
+            }
+        }
+    }
+    if (offset) *offset = mOffset;
+    if (size) *size = mSize;
+    return mHeap;
+}
+
+// ---------------------------------------------------------------------------
+
+IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory");
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnMemory::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_MEMORY: {
+            CHECK_INTERFACE(IMemory, data, reply);
+            ssize_t offset;
+            size_t size;
+            reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() );
+            reply->writeInt32(offset);
+            reply->writeInt32(size);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+
+/******************************************************************************/
+
+BpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl)
+    : BpInterface<IMemoryHeap>(impl),
+        mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mRealHeap(false)
+{
+}
+
+BpMemoryHeap::~BpMemoryHeap() {
+    if (mHeapId != -1) {
+        close(mHeapId);
+        if (mRealHeap) {
+            // by construction we're the last one
+            if (mBase != MAP_FAILED) {
+                sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
+
+                if (VERBOSE) {
+                    LOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d", 
+                            binder.get(), this, mSize, mHeapId);
+                    CallStack stack;
+                    stack.update();
+                    stack.dump("callstack");
+                }
+
+                munmap(mBase, mSize);
+            }
+        } else {
+            // remove from list only if it was mapped before
+            sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
+            free_heap(binder);
+        }
+    }
+}
+
+void BpMemoryHeap::assertMapped() const
+{
+    if (mHeapId == -1) {
+        sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder());
+        sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get()));
+        heap->assertReallyMapped();
+        if (heap->mBase != MAP_FAILED) {
+            Mutex::Autolock _l(mLock);
+            if (mHeapId == -1) {
+                mBase   = heap->mBase;
+                mSize   = heap->mSize;
+                android_atomic_write( dup( heap->mHeapId ), &mHeapId );
+            }
+        } else {
+            // something went wrong
+            free_heap(binder);
+        }
+    }
+}
+
+void BpMemoryHeap::assertReallyMapped() const
+{
+    if (mHeapId == -1) {
+
+        // remote call without mLock held, worse case scenario, we end up
+        // calling transact() from multiple threads, but that's not a problem,
+        // only mmap below must be in the critical section.
+        
+        Parcel data, reply;
+        data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor());
+        status_t err = remote()->transact(HEAP_ID, data, &reply);
+        int parcel_fd = reply.readFileDescriptor();
+        ssize_t size = reply.readInt32();
+        uint32_t flags = reply.readInt32();
+
+        LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%d, err=%d (%s)",
+                asBinder().get(), parcel_fd, size, err, strerror(-err));
+
+        int fd = dup( parcel_fd );
+        LOGE_IF(fd==-1, "cannot dup fd=%d, size=%d, err=%d (%s)",
+                parcel_fd, size, err, strerror(errno));
+
+        int access = PROT_READ;
+        if (!(flags & READ_ONLY)) {
+            access |= PROT_WRITE;
+        }
+
+        Mutex::Autolock _l(mLock);
+        if (mHeapId == -1) {
+            mRealHeap = true;
+            mBase = mmap(0, size, access, MAP_SHARED, fd, 0);
+            if (mBase == MAP_FAILED) {
+                LOGE("cannot map BpMemoryHeap (binder=%p), size=%d, fd=%d (%s)",
+                        asBinder().get(), size, fd, strerror(errno));
+                close(fd);
+            } else {
+                if (flags & MAP_ONCE) {
+                    //LOGD("pinning heap (binder=%p, size=%d, fd=%d",
+                    //        asBinder().get(), size, fd);
+                    pin_heap();
+                }
+                mSize = size;
+                mFlags = flags;
+                android_atomic_write(fd, &mHeapId);
+            }
+        }
+    }
+}
+
+int BpMemoryHeap::getHeapID() const {
+    assertMapped();
+    return mHeapId;
+}
+
+void* BpMemoryHeap::getBase() const {
+    assertMapped();
+    return mBase;
+}
+
+size_t BpMemoryHeap::getSize() const {
+    assertMapped();
+    return mSize;
+}
+
+uint32_t BpMemoryHeap::getFlags() const {
+    assertMapped();
+    return mFlags;
+}
+
+// ---------------------------------------------------------------------------
+
+IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap");
+
+status_t BnMemoryHeap::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+       case HEAP_ID: {
+            CHECK_INTERFACE(IMemoryHeap, data, reply);
+            reply->writeFileDescriptor(getHeapID());
+            reply->writeInt32(getSize());
+            reply->writeInt32(getFlags());
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+/*****************************************************************************/
+
+HeapCache::HeapCache()
+    : DeathRecipient()
+{
+}
+
+HeapCache::~HeapCache()
+{
+}
+
+void HeapCache::binderDied(const wp<IBinder>& binder)
+{
+    //LOGD("binderDied binder=%p", binder.unsafe_get());
+    free_heap(binder); 
+}
+
+sp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder) 
+{
+    Mutex::Autolock _l(mHeapCacheLock);
+    ssize_t i = mHeapCache.indexOfKey(binder);
+    if (i>=0) {
+        heap_info_t& info = mHeapCache.editValueAt(i);
+        LOGD_IF(VERBOSE,
+                "found binder=%p, heap=%p, size=%d, fd=%d, count=%d", 
+                binder.get(), info.heap.get(),
+                static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
+                static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
+                info.count);
+        android_atomic_inc(&info.count);
+        return info.heap;
+    } else {
+        heap_info_t info;
+        info.heap = interface_cast<IMemoryHeap>(binder);
+        info.count = 1;
+        //LOGD("adding binder=%p, heap=%p, count=%d",
+        //      binder.get(), info.heap.get(), info.count);
+        mHeapCache.add(binder, info);
+        return info.heap;
+    }
+}
+
+void HeapCache::pin_heap(const sp<IBinder>& binder) 
+{
+    Mutex::Autolock _l(mHeapCacheLock);
+    ssize_t i = mHeapCache.indexOfKey(binder);
+    if (i>=0) {
+        heap_info_t& info(mHeapCache.editValueAt(i));
+        android_atomic_inc(&info.count);
+        binder->linkToDeath(this);
+    } else {
+        LOGE("pin_heap binder=%p not found!!!", binder.get());
+    }    
+}
+
+void HeapCache::free_heap(const sp<IBinder>& binder)  {
+    free_heap( wp<IBinder>(binder) );
+}
+
+void HeapCache::free_heap(const wp<IBinder>& binder) 
+{
+    sp<IMemoryHeap> rel;
+    {
+        Mutex::Autolock _l(mHeapCacheLock);
+        ssize_t i = mHeapCache.indexOfKey(binder);
+        if (i>=0) {
+            heap_info_t& info(mHeapCache.editValueAt(i));
+            int32_t c = android_atomic_dec(&info.count);
+            if (c == 1) {
+                LOGD_IF(VERBOSE,
+                        "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d", 
+                        binder.unsafe_get(), info.heap.get(),
+                        static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
+                        static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
+                        info.count);
+                rel = mHeapCache.valueAt(i).heap;
+                mHeapCache.removeItemsAt(i);
+            }
+        } else {
+            LOGE("free_heap binder=%p not found!!!", binder.unsafe_get());
+        }
+    }
+}
+
+sp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder)
+{
+    sp<IMemoryHeap> realHeap;
+    Mutex::Autolock _l(mHeapCacheLock);
+    ssize_t i = mHeapCache.indexOfKey(binder);
+    if (i>=0)   realHeap = mHeapCache.valueAt(i).heap;
+    else        realHeap = interface_cast<IMemoryHeap>(binder);
+    return realHeap;
+}
+
+void HeapCache::dump_heaps() 
+{
+    Mutex::Autolock _l(mHeapCacheLock);
+    int c = mHeapCache.size();
+    for (int i=0 ; i<c ; i++) {
+        const heap_info_t& info = mHeapCache.valueAt(i);
+        BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get()));
+        LOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)",
+                mHeapCache.keyAt(i).unsafe_get(),
+                info.heap.get(), info.count, 
+                h->mHeapId, h->mBase, h->mSize);
+    }
+}
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/IPCThreadState.cpp b/libs/utils/IPCThreadState.cpp
new file mode 100644
index 0000000..ca49d9a
--- /dev/null
+++ b/libs/utils/IPCThreadState.cpp
@@ -0,0 +1,1007 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/IPCThreadState.h>
+
+#include <utils/Binder.h>
+#include <utils/BpBinder.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/utils/binder_module.h>
+#include <private/utils/Static.h>
+
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef HAVE_PTHREADS
+#include <pthread.h>
+#include <sched.h>
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_WIN32_THREADS
+#include <windows.h>
+#endif
+
+
+#if LOG_NDEBUG
+
+#define IF_LOG_TRANSACTIONS() if (false)
+#define IF_LOG_COMMANDS() if (false)
+#define LOG_REMOTEREFS(...) 
+#define IF_LOG_REMOTEREFS() if (false)
+#define LOG_THREADPOOL(...) 
+#define LOG_ONEWAY(...) 
+
+#else
+
+#define IF_LOG_TRANSACTIONS() IF_LOG(LOG_VERBOSE, "transact")
+#define IF_LOG_COMMANDS() IF_LOG(LOG_VERBOSE, "ipc")
+#define LOG_REMOTEREFS(...) LOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
+#define IF_LOG_REMOTEREFS() IF_LOG(LOG_DEBUG, "remoterefs")
+#define LOG_THREADPOOL(...) LOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
+#define LOG_ONEWAY(...) LOG(LOG_DEBUG, "ipc", __VA_ARGS__)
+
+#endif
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+static const char* getReturnString(size_t idx);
+static const char* getCommandString(size_t idx);
+static const void* printReturnCommand(TextOutput& out, const void* _cmd);
+static const void* printCommand(TextOutput& out, const void* _cmd);
+
+// This will result in a missing symbol failure if the IF_LOG_COMMANDS()
+// conditionals don't get stripped...  but that is probably what we want.
+#if !LOG_NDEBUG
+static const char *kReturnStrings[] = {
+#if 1 /* TODO: error update strings */
+    "unknown",
+#else
+    "BR_OK",
+    "BR_TIMEOUT",
+    "BR_WAKEUP",
+    "BR_TRANSACTION",
+    "BR_REPLY",
+    "BR_ACQUIRE_RESULT",
+    "BR_DEAD_REPLY",
+    "BR_TRANSACTION_COMPLETE",
+    "BR_INCREFS",
+    "BR_ACQUIRE",
+    "BR_RELEASE",
+    "BR_DECREFS",
+    "BR_ATTEMPT_ACQUIRE",
+    "BR_EVENT_OCCURRED",
+    "BR_NOOP",
+    "BR_SPAWN_LOOPER",
+    "BR_FINISHED",
+    "BR_DEAD_BINDER",
+    "BR_CLEAR_DEATH_NOTIFICATION_DONE"
+#endif
+};
+
+static const char *kCommandStrings[] = {
+#if 1 /* TODO: error update strings */
+    "unknown",
+#else
+    "BC_NOOP",
+    "BC_TRANSACTION",
+    "BC_REPLY",
+    "BC_ACQUIRE_RESULT",
+    "BC_FREE_BUFFER",
+    "BC_TRANSACTION_COMPLETE",
+    "BC_INCREFS",
+    "BC_ACQUIRE",
+    "BC_RELEASE",
+    "BC_DECREFS",
+    "BC_INCREFS_DONE",
+    "BC_ACQUIRE_DONE",
+    "BC_ATTEMPT_ACQUIRE",
+    "BC_RETRIEVE_ROOT_OBJECT",
+    "BC_SET_THREAD_ENTRY",
+    "BC_REGISTER_LOOPER",
+    "BC_ENTER_LOOPER",
+    "BC_EXIT_LOOPER",
+    "BC_SYNC",
+    "BC_STOP_PROCESS",
+    "BC_STOP_SELF",
+    "BC_REQUEST_DEATH_NOTIFICATION",
+    "BC_CLEAR_DEATH_NOTIFICATION",
+    "BC_DEAD_BINDER_DONE"
+#endif
+};
+
+static const char* getReturnString(size_t idx)
+{
+    if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
+        return kReturnStrings[idx];
+    else
+        return "unknown";
+}
+
+static const char* getCommandString(size_t idx)
+{
+    if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
+        return kCommandStrings[idx];
+    else
+        return "unknown";
+}
+
+static const void* printBinderTransactionData(TextOutput& out, const void* data)
+{
+    const binder_transaction_data* btd =
+        (const binder_transaction_data*)data;
+    out << "target=" << btd->target.ptr << " (cookie " << btd->cookie << ")" << endl
+        << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
+        << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
+        << " bytes)" << endl
+        << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
+        << " bytes)" << endl;
+    return btd+1;
+}
+
+static const void* printReturnCommand(TextOutput& out, const void* _cmd)
+{
+    static const int32_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
+    
+    const int32_t* cmd = (const int32_t*)_cmd;
+    int32_t code = *cmd++;
+    if (code == BR_ERROR) {
+        out << "BR_ERROR: " << (void*)(*cmd++) << endl;
+        return cmd;
+    } else if (code < 0 || code >= N) {
+        out << "Unknown reply: " << code << endl;
+        return cmd;
+    }
+    
+    out << kReturnStrings[code];
+    switch (code) {
+        case BR_TRANSACTION:
+        case BR_REPLY: {
+            out << ": " << indent;
+            cmd = (const int32_t *)printBinderTransactionData(out, cmd);
+            out << dedent;
+        } break;
+        
+        case BR_ACQUIRE_RESULT: {
+            const int32_t res = *cmd++;
+            out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
+        } break;
+        
+        case BR_INCREFS:
+        case BR_ACQUIRE:
+        case BR_RELEASE:
+        case BR_DECREFS: {
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+        } break;
+    
+        case BR_ATTEMPT_ACQUIRE: {
+            const int32_t p = *cmd++;
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c
+                << "), pri=" << p;
+        } break;
+
+        case BR_DEAD_BINDER:
+        case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
+            const int32_t c = *cmd++;
+            out << ": death cookie " << (void*)c;
+        } break;
+    }
+    
+    out << endl;
+    return cmd;
+}
+
+static const void* printCommand(TextOutput& out, const void* _cmd)
+{
+    static const int32_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
+    
+    const int32_t* cmd = (const int32_t*)_cmd;
+    int32_t code = *cmd++;
+    if (code < 0 || code >= N) {
+        out << "Unknown command: " << code << endl;
+        return cmd;
+    }
+    
+    out << kCommandStrings[code];
+    switch (code) {
+        case BC_TRANSACTION:
+        case BC_REPLY: {
+            out << ": " << indent;
+            cmd = (const int32_t *)printBinderTransactionData(out, cmd);
+            out << dedent;
+        } break;
+        
+        case BC_ACQUIRE_RESULT: {
+            const int32_t res = *cmd++;
+            out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
+        } break;
+        
+        case BC_FREE_BUFFER: {
+            const int32_t buf = *cmd++;
+            out << ": buffer=" << (void*)buf;
+        } break;
+        
+        case BC_INCREFS:
+        case BC_ACQUIRE:
+        case BC_RELEASE:
+        case BC_DECREFS: {
+            const int32_t d = *cmd++;
+            out << ": descriptor=" << (void*)d;
+        } break;
+    
+        case BC_INCREFS_DONE:
+        case BC_ACQUIRE_DONE: {
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+        } break;
+        
+        case BC_ATTEMPT_ACQUIRE: {
+            const int32_t p = *cmd++;
+            const int32_t d = *cmd++;
+            out << ": decriptor=" << (void*)d << ", pri=" << p;
+        } break;
+        
+        case BC_REQUEST_DEATH_NOTIFICATION:
+        case BC_CLEAR_DEATH_NOTIFICATION: {
+            const int32_t h = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": handle=" << h << " (death cookie " << (void*)c << ")";
+        } break;
+
+        case BC_DEAD_BINDER_DONE: {
+            const int32_t c = *cmd++;
+            out << ": death cookie " << (void*)c;
+        } break;
+    }
+    
+    out << endl;
+    return cmd;
+}
+#endif
+
+static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
+static bool gHaveTLS = false;
+static pthread_key_t gTLS = 0;
+static bool gShutdown = false;
+
+IPCThreadState* IPCThreadState::self()
+{
+    if (gHaveTLS) {
+restart:
+        const pthread_key_t k = gTLS;
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
+        if (st) return st;
+        return new IPCThreadState;
+    }
+    
+    if (gShutdown) return NULL;
+    
+    pthread_mutex_lock(&gTLSMutex);
+    if (!gHaveTLS) {
+        if (pthread_key_create(&gTLS, threadDestructor) != 0) {
+            pthread_mutex_unlock(&gTLSMutex);
+            return NULL;
+        }
+        gHaveTLS = true;
+    }
+    pthread_mutex_unlock(&gTLSMutex);
+    goto restart;
+}
+
+void IPCThreadState::shutdown()
+{
+    gShutdown = true;
+    
+    if (gHaveTLS) {
+        // XXX Need to wait for all thread pool threads to exit!
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
+        if (st) {
+            delete st;
+            pthread_setspecific(gTLS, NULL);
+        }
+        gHaveTLS = false;
+    }
+}
+
+sp<ProcessState> IPCThreadState::process()
+{
+    return mProcess;
+}
+
+status_t IPCThreadState::clearLastError()
+{
+    const status_t err = mLastError;
+    mLastError = NO_ERROR;
+    return err;
+}
+
+int IPCThreadState::getCallingPid()
+{
+    return mCallingPid;
+}
+
+int IPCThreadState::getCallingUid()
+{
+    return mCallingUid;
+}
+
+int64_t IPCThreadState::clearCallingIdentity()
+{
+    int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
+    clearCaller();
+    return token;
+}
+
+void IPCThreadState::restoreCallingIdentity(int64_t token)
+{
+    mCallingUid = (int)(token>>32);
+    mCallingPid = (int)token;
+}
+
+void IPCThreadState::clearCaller()
+{
+    if (mProcess->supportsProcesses()) {
+        mCallingPid = getpid();
+        mCallingUid = getuid();
+    } else {
+        mCallingPid = -1;
+        mCallingUid = -1;
+    }
+}
+
+void IPCThreadState::flushCommands()
+{
+    if (mProcess->mDriverFD <= 0)
+        return;
+    talkWithDriver(false);
+}
+
+void IPCThreadState::joinThreadPool(bool isMain)
+{
+    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
+
+    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
+    
+    status_t result;
+    do {
+        int32_t cmd;
+        result = talkWithDriver();
+        if (result >= NO_ERROR) {
+            size_t IN = mIn.dataAvail();
+            if (IN < sizeof(int32_t)) continue;
+            cmd = mIn.readInt32();
+            IF_LOG_COMMANDS() {
+                alog << "Processing top-level Command: "
+                    << getReturnString(cmd) << endl;
+            }
+            result = executeCommand(cmd);
+        }
+        
+        // Let this thread exit the thread pool if it is no longer
+        // needed and it is not the main process thread.
+        if(result == TIMED_OUT && !isMain) {
+            break;
+        }
+    } while (result != -ECONNREFUSED && result != -EBADF);
+
+    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
+        (void*)pthread_self(), getpid(), (void*)result);
+    
+    mOut.writeInt32(BC_EXIT_LOOPER);
+    talkWithDriver(false);
+}
+
+void IPCThreadState::stopProcess(bool immediate)
+{
+    //LOGI("**** STOPPING PROCESS");
+    flushCommands();
+    int fd = mProcess->mDriverFD;
+    mProcess->mDriverFD = -1;
+    close(fd);
+    //kill(getpid(), SIGKILL);
+}
+
+status_t IPCThreadState::transact(int32_t handle,
+                                  uint32_t code, const Parcel& data,
+                                  Parcel* reply, uint32_t flags)
+{
+    status_t err = data.errorCheck();
+
+    flags |= TF_ACCEPT_FDS;
+
+    IF_LOG_TRANSACTIONS() {
+        TextOutput::Bundle _b(alog);
+        alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
+            << handle << " / code " << TypeCode(code) << ": "
+            << indent << data << dedent << endl;
+    }
+    
+    if (err == NO_ERROR) {
+        LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
+            (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
+        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
+    }
+    
+    if (err != NO_ERROR) {
+        if (reply) reply->setError(err);
+        return (mLastError = err);
+    }
+    
+    if ((flags & TF_ONE_WAY) == 0) {
+        if (reply) {
+            err = waitForResponse(reply);
+        } else {
+            Parcel fakeReply;
+            err = waitForResponse(&fakeReply);
+        }
+        
+        IF_LOG_TRANSACTIONS() {
+            TextOutput::Bundle _b(alog);
+            alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
+                << handle << ": ";
+            if (reply) alog << indent << *reply << dedent << endl;
+            else alog << "(none requested)" << endl;
+        }
+    } else {
+        err = waitForResponse(NULL, NULL);
+    }
+    
+    return err;
+}
+
+void IPCThreadState::incStrongHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
+    mOut.writeInt32(BC_ACQUIRE);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::decStrongHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
+    mOut.writeInt32(BC_RELEASE);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::incWeakHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
+    mOut.writeInt32(BC_INCREFS);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::decWeakHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
+    mOut.writeInt32(BC_DECREFS);
+    mOut.writeInt32(handle);
+}
+
+status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
+{
+    mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
+    mOut.writeInt32(0); // xxx was thread priority
+    mOut.writeInt32(handle);
+    status_t result = UNKNOWN_ERROR;
+    
+    waitForResponse(NULL, &result);
+    
+#if LOG_REFCOUNTS
+    printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
+        handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
+#endif
+    
+    return result;
+}
+
+void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
+{
+#if LOG_REFCOUNTS
+    printf("IPCThreadState::expungeHandle(%ld)\n", handle);
+#endif
+    self()->mProcess->expungeHandle(handle, binder);
+}
+
+status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
+{
+    mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
+    mOut.writeInt32((int32_t)handle);
+    mOut.writeInt32((int32_t)proxy);
+    return NO_ERROR;
+}
+
+status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
+{
+    mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
+    mOut.writeInt32((int32_t)handle);
+    mOut.writeInt32((int32_t)proxy);
+    return NO_ERROR;
+}
+
+IPCThreadState::IPCThreadState()
+    : mProcess(ProcessState::self())
+{
+    pthread_setspecific(gTLS, this);
+        clearCaller();
+    mIn.setDataCapacity(256);
+    mOut.setDataCapacity(256);
+}
+
+IPCThreadState::~IPCThreadState()
+{
+}
+
+status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
+{
+    status_t err;
+    status_t statusBuffer;
+    err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
+    if (err < NO_ERROR) return err;
+    
+    return waitForResponse(NULL, NULL);
+}
+
+status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
+{
+    int32_t cmd;
+    int32_t err;
+
+    while (1) {
+        if ((err=talkWithDriver()) < NO_ERROR) break;
+        err = mIn.errorCheck();
+        if (err < NO_ERROR) break;
+        if (mIn.dataAvail() == 0) continue;
+        
+        cmd = mIn.readInt32();
+        
+        IF_LOG_COMMANDS() {
+            alog << "Processing waitForResponse Command: "
+                << getReturnString(cmd) << endl;
+        }
+
+        switch (cmd) {
+        case BR_TRANSACTION_COMPLETE:
+            if (!reply && !acquireResult) goto finish;
+            break;
+        
+        case BR_DEAD_REPLY:
+            err = DEAD_OBJECT;
+            goto finish;
+
+        case BR_FAILED_REPLY:
+            err = FAILED_TRANSACTION;
+            goto finish;
+        
+        case BR_ACQUIRE_RESULT:
+            {
+                LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
+                const int32_t result = mIn.readInt32();
+                if (!acquireResult) continue;
+                *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
+            }
+            goto finish;
+        
+        case BR_REPLY:
+            {
+                binder_transaction_data tr;
+                err = mIn.read(&tr, sizeof(tr));
+                LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
+                if (err != NO_ERROR) goto finish;
+
+                if (reply) {
+                    if ((tr.flags & TF_STATUS_CODE) == 0) {
+                        reply->ipcSetDataReference(
+                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                            tr.data_size,
+                            reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(size_t),
+                            freeBuffer, this);
+                    } else {
+                        err = *static_cast<const status_t*>(tr.data.ptr.buffer);
+                        freeBuffer(NULL,
+                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                            tr.data_size,
+                            reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(size_t), this);
+                    }
+                } else {
+                    freeBuffer(NULL,
+                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                        tr.data_size,
+                        reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                        tr.offsets_size/sizeof(size_t), this);
+                    continue;
+                }
+            }
+            goto finish;
+
+        default:
+            err = executeCommand(cmd);
+            if (err != NO_ERROR) goto finish;
+            break;
+        }
+    }
+
+finish:
+    if (err != NO_ERROR) {
+        if (acquireResult) *acquireResult = err;
+        if (reply) reply->setError(err);
+        mLastError = err;
+    }
+    
+    return err;
+}
+
+status_t IPCThreadState::talkWithDriver(bool doReceive)
+{
+    LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
+    
+    binder_write_read bwr;
+    
+    // Is the read buffer empty?
+    const bool needRead = mIn.dataPosition() >= mIn.dataSize();
+    
+    // We don't want to write anything if we are still reading
+    // from data left in the input buffer and the caller
+    // has requested to read the next data.
+    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
+    
+    bwr.write_size = outAvail;
+    bwr.write_buffer = (long unsigned int)mOut.data();
+
+    // This is what we'll read.
+    if (doReceive && needRead) {
+        bwr.read_size = mIn.dataCapacity();
+        bwr.read_buffer = (long unsigned int)mIn.data();
+    } else {
+        bwr.read_size = 0;
+    }
+    
+    IF_LOG_COMMANDS() {
+        TextOutput::Bundle _b(alog);
+        if (outAvail != 0) {
+            alog << "Sending commands to driver: " << indent;
+            const void* cmds = (const void*)bwr.write_buffer;
+            const void* end = ((const uint8_t*)cmds)+bwr.write_size;
+            alog << HexDump(cmds, bwr.write_size) << endl;
+            while (cmds < end) cmds = printCommand(alog, cmds);
+            alog << dedent;
+        }
+        alog << "Size of receive buffer: " << bwr.read_size
+            << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
+    }
+    
+    // Return immediately if there is nothing to do.
+    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
+    
+    bwr.write_consumed = 0;
+    bwr.read_consumed = 0;
+    status_t err;
+    do {
+        IF_LOG_COMMANDS() {
+            alog << "About to read/write, write size = " << mOut.dataSize() << endl;
+        }
+#if defined(HAVE_ANDROID_OS)
+        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
+            err = NO_ERROR;
+        else
+            err = -errno;
+#else
+        err = INVALID_OPERATION;
+#endif
+        IF_LOG_COMMANDS() {
+            alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
+        }
+    } while (err == -EINTR);
+    
+    IF_LOG_COMMANDS() {
+        alog << "Our err: " << (void*)err << ", write consumed: "
+            << bwr.write_consumed << " (of " << mOut.dataSize()
+			<< "), read consumed: " << bwr.read_consumed << endl;
+    }
+
+    if (err >= NO_ERROR) {
+        if (bwr.write_consumed > 0) {
+            if (bwr.write_consumed < (ssize_t)mOut.dataSize())
+                mOut.remove(0, bwr.write_consumed);
+            else
+                mOut.setDataSize(0);
+        }
+        if (bwr.read_consumed > 0) {
+            mIn.setDataSize(bwr.read_consumed);
+            mIn.setDataPosition(0);
+        }
+        IF_LOG_COMMANDS() {
+            TextOutput::Bundle _b(alog);
+            alog << "Remaining data size: " << mOut.dataSize() << endl;
+            alog << "Received commands from driver: " << indent;
+            const void* cmds = mIn.data();
+            const void* end = mIn.data() + mIn.dataSize();
+            alog << HexDump(cmds, mIn.dataSize()) << endl;
+            while (cmds < end) cmds = printReturnCommand(alog, cmds);
+            alog << dedent;
+        }
+        return NO_ERROR;
+    }
+    
+    return err;
+}
+
+status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
+    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
+{
+    binder_transaction_data tr;
+
+    tr.target.handle = handle;
+    tr.code = code;
+    tr.flags = binderFlags;
+    
+    const status_t err = data.errorCheck();
+    if (err == NO_ERROR) {
+        tr.data_size = data.ipcDataSize();
+        tr.data.ptr.buffer = data.ipcData();
+        tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
+        tr.data.ptr.offsets = data.ipcObjects();
+    } else if (statusBuffer) {
+        tr.flags |= TF_STATUS_CODE;
+        *statusBuffer = err;
+        tr.data_size = sizeof(status_t);
+        tr.data.ptr.buffer = statusBuffer;
+        tr.offsets_size = 0;
+        tr.data.ptr.offsets = NULL;
+    } else {
+        return (mLastError = err);
+    }
+    
+    mOut.writeInt32(cmd);
+    mOut.write(&tr, sizeof(tr));
+    
+    return NO_ERROR;
+}
+
+sp<BBinder> the_context_object;
+
+void setTheContextObject(sp<BBinder> obj)
+{
+    the_context_object = obj;
+}
+
+status_t IPCThreadState::executeCommand(int32_t cmd)
+{
+    BBinder* obj;
+    RefBase::weakref_type* refs;
+    status_t result = NO_ERROR;
+    
+    switch (cmd) {
+    case BR_ERROR:
+        result = mIn.readInt32();
+        break;
+        
+    case BR_OK:
+        break;
+        
+    case BR_ACQUIRE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        LOG_ASSERT(refs->refBase() == obj,
+                   "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
+                   refs, obj, refs->refBase());
+        obj->incStrong(mProcess.get());
+        IF_LOG_REMOTEREFS() {
+            LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
+            obj->printRefs();
+        }
+        mOut.writeInt32(BC_ACQUIRE_DONE);
+        mOut.writeInt32((int32_t)refs);
+        mOut.writeInt32((int32_t)obj);
+        break;
+        
+    case BR_RELEASE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        LOG_ASSERT(refs->refBase() == obj,
+                   "BR_RELEASE: object %p does not match cookie %p (expected %p)",
+                   refs, obj, refs->refBase());
+        IF_LOG_REMOTEREFS() {
+            LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
+            obj->printRefs();
+        }
+        obj->decStrong(mProcess.get());
+        break;
+        
+    case BR_INCREFS:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        refs->incWeak(mProcess.get());
+        mOut.writeInt32(BC_INCREFS_DONE);
+        mOut.writeInt32((int32_t)refs);
+        mOut.writeInt32((int32_t)obj);
+        break;
+        
+    case BR_DECREFS:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        // NOTE: This assertion is not valid, because the object may no
+        // longer exist (thus the (BBinder*)cast above resulting in a different
+        // memory address).
+        //LOG_ASSERT(refs->refBase() == obj,
+        //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
+        //           refs, obj, refs->refBase());
+        refs->decWeak(mProcess.get());
+        break;
+        
+    case BR_ATTEMPT_ACQUIRE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+         
+        {
+            const bool success = refs->attemptIncStrong(mProcess.get());
+            LOG_ASSERT(success && refs->refBase() == obj,
+                       "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
+                       refs, obj, refs->refBase());
+            
+            mOut.writeInt32(BC_ACQUIRE_RESULT);
+            mOut.writeInt32((int32_t)success);
+        }
+        break;
+    
+    case BR_TRANSACTION:
+        {
+            binder_transaction_data tr;
+            result = mIn.read(&tr, sizeof(tr));
+            LOG_ASSERT(result == NO_ERROR,
+                "Not enough command data for brTRANSACTION");
+            if (result != NO_ERROR) break;
+            
+            Parcel buffer;
+            buffer.ipcSetDataReference(
+                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                tr.data_size,
+                reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                tr.offsets_size/sizeof(size_t), freeBuffer, this);
+            
+            const pid_t origPid = mCallingPid;
+            const uid_t origUid = mCallingUid;
+            
+            mCallingPid = tr.sender_pid;
+            mCallingUid = tr.sender_euid;
+            
+            //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
+            
+            Parcel reply;
+            IF_LOG_TRANSACTIONS() {
+                TextOutput::Bundle _b(alog);
+                alog << "BR_TRANSACTION thr " << (void*)pthread_self()
+                    << " / obj " << tr.target.ptr << " / code "
+                    << TypeCode(tr.code) << ": " << indent << buffer
+                    << dedent << endl
+                    << "Data addr = "
+                    << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
+                    << ", offsets addr="
+                    << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
+            }
+            if (tr.target.ptr) {
+                sp<BBinder> b((BBinder*)tr.cookie);
+                const status_t error = b->transact(tr.code, buffer, &reply, 0);
+                if (error < NO_ERROR) reply.setError(error);
+                
+            } else {
+                const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
+                if (error < NO_ERROR) reply.setError(error);
+            }
+            
+            //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
+            //     mCallingPid, origPid, origUid);
+            
+            if ((tr.flags & TF_ONE_WAY) == 0) {
+                LOG_ONEWAY("Sending reply to %d!", mCallingPid);
+                sendReply(reply, 0);
+            } else {
+                LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
+            }
+            
+            mCallingPid = origPid;
+            mCallingUid = origUid;
+            
+            IF_LOG_TRANSACTIONS() {
+                TextOutput::Bundle _b(alog);
+                alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
+                    << tr.target.ptr << ": " << indent << reply << dedent << endl;
+            }
+            
+        }
+        break;
+    
+    case BR_DEAD_BINDER:
+        {
+            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            proxy->sendObituary();
+            mOut.writeInt32(BC_DEAD_BINDER_DONE);
+            mOut.writeInt32((int32_t)proxy);
+        } break;
+        
+    case BR_CLEAR_DEATH_NOTIFICATION_DONE:
+        {
+            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            proxy->getWeakRefs()->decWeak(proxy);
+        } break;
+        
+    case BR_FINISHED:
+        result = TIMED_OUT;
+        break;
+        
+    case BR_NOOP:
+        break;
+        
+    case BR_SPAWN_LOOPER:
+        mProcess->spawnPooledThread(false);
+        break;
+        
+    default:
+        printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
+        result = UNKNOWN_ERROR;
+        break;
+    }
+
+    if (result != NO_ERROR) {
+        mLastError = result;
+    }
+    
+    return result;
+}
+
+void IPCThreadState::threadDestructor(void *st)
+{
+	IPCThreadState* const self = static_cast<IPCThreadState*>(st);
+	if (self) {
+		self->flushCommands();
+#if defined(HAVE_ANDROID_OS)
+        ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
+#endif
+		delete self;
+	}
+}
+
+
+void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
+                                const size_t* objects, size_t objectsSize,
+                                void* cookie)
+{
+    //LOGI("Freeing parcel %p", &parcel);
+    IF_LOG_COMMANDS() {
+        alog << "Writing BC_FREE_BUFFER for " << data << endl;
+    }
+    LOG_ASSERT(data != NULL, "Called with NULL data");
+    if (parcel != NULL) parcel->closeFileDescriptors();
+    IPCThreadState* state = self();
+    state->mOut.writeInt32(BC_FREE_BUFFER);
+    state->mOut.writeInt32((int32_t)data);
+}
+
+}; // namespace android
diff --git a/libs/utils/IPermissionController.cpp b/libs/utils/IPermissionController.cpp
new file mode 100644
index 0000000..f01d38f
--- /dev/null
+++ b/libs/utils/IPermissionController.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "PermissionController"
+
+#include <utils/IPermissionController.h>
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/String8.h>
+
+#include <private/utils/Static.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BpPermissionController : public BpInterface<IPermissionController>
+{
+public:
+    BpPermissionController(const sp<IBinder>& impl)
+        : BpInterface<IPermissionController>(impl)
+    {
+    }
+        
+    virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
+        data.writeString16(permission);
+        data.writeInt32(pid);
+        data.writeInt32(uid);
+        remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
+        // fail on exception
+        if (reply.readInt32() != 0) return 0;
+        return reply.readInt32() != 0;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnPermissionController::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    //printf("PermissionController received: "); data.print();
+    switch(code) {
+        case CHECK_PERMISSION_TRANSACTION: {
+            CHECK_INTERFACE(IPermissionController, data, reply);
+            String16 permission = data.readString16();
+            int32_t pid = data.readInt32();
+            int32_t uid = data.readInt32();
+            bool res = checkPermission(permission, pid, uid);
+            // write exception
+            reply->writeInt32(0);
+            reply->writeInt32(res ? 1 : 0);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/utils/IServiceManager.cpp b/libs/utils/IServiceManager.cpp
new file mode 100644
index 0000000..9beeadd
--- /dev/null
+++ b/libs/utils/IServiceManager.cpp
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "ServiceManager"
+
+#include <utils/IServiceManager.h>
+
+#include <utils/Debug.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/String8.h>
+#include <utils/SystemClock.h>
+
+#include <private/utils/Static.h>
+
+#include <unistd.h>
+
+namespace android {
+
+sp<IServiceManager> defaultServiceManager()
+{
+    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
+    
+    {
+        AutoMutex _l(gDefaultServiceManagerLock);
+        if (gDefaultServiceManager == NULL) {
+            gDefaultServiceManager = interface_cast<IServiceManager>(
+                ProcessState::self()->getContextObject(NULL));
+        }
+    }
+    
+    return gDefaultServiceManager;
+}
+
+bool checkCallingPermission(const String16& permission)
+{
+    return checkCallingPermission(permission, NULL, NULL);
+}
+
+static String16 _permission("permission");
+
+bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
+{
+    IPCThreadState* ipcState = IPCThreadState::self();
+    int32_t pid = ipcState->getCallingPid();
+    int32_t uid = ipcState->getCallingUid();
+    if (outPid) *outPid = pid;
+    if (outUid) *outUid= uid;
+    
+    sp<IPermissionController> pc;
+    gDefaultServiceManagerLock.lock();
+    pc = gPermissionController;
+    gDefaultServiceManagerLock.unlock();
+    
+    int64_t startTime = 0;
+
+    while (true) {
+        if (pc != NULL) {
+            bool res = pc->checkPermission(permission, pid, uid);
+            if (res) {
+                if (startTime != 0) {
+                    LOGI("Check passed after %d seconds for %s from uid=%d pid=%d",
+                            (int)((uptimeMillis()-startTime)/1000),
+                            String8(permission).string(), uid, pid);
+                }
+                return res;
+            }
+            
+            // Is this a permission failure, or did the controller go away?
+            if (pc->asBinder()->isBinderAlive()) {
+                LOGW("Permission failure: %s from uid=%d pid=%d",
+                        String8(permission).string(), uid, pid);
+                return false;
+            }
+            
+            // Object is dead!
+            gDefaultServiceManagerLock.lock();
+            if (gPermissionController == pc) {
+                gPermissionController = NULL;
+            }
+            gDefaultServiceManagerLock.unlock();
+        }
+    
+        // Need to retrieve the permission controller.
+        sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
+        if (binder == NULL) {
+            // Wait for the permission controller to come back...
+            if (startTime == 0) {
+                startTime = uptimeMillis();
+                LOGI("Waiting to check permission %s from uid=%d pid=%d",
+                        String8(permission).string(), uid, pid);
+            }
+            sleep(1);
+        } else {
+            pc = interface_cast<IPermissionController>(binder);
+            // Install the new permission controller, and try again.        
+            gDefaultServiceManagerLock.lock();
+            gPermissionController = pc;
+            gDefaultServiceManagerLock.unlock();
+        }
+    }
+}
+
+// ----------------------------------------------------------------------
+
+class BpServiceManager : public BpInterface<IServiceManager>
+{
+public:
+    BpServiceManager(const sp<IBinder>& impl)
+        : 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());
+            sleep(1);
+        }
+        return NULL;
+    }
+    
+    virtual sp<IBinder> checkService( const String16& name) const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+        data.writeString16(name);
+        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
+        return reply.readStrongBinder();
+    }
+
+    virtual status_t addService(const String16& name, const sp<IBinder>& service)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeStrongBinder(service);
+        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
+        return err == NO_ERROR ? reply.readInt32() : err;
+    }
+
+    virtual Vector<String16> listServices()
+    {
+        Vector<String16> res;
+        int n = 0;
+
+        for (;;) {
+            Parcel data, reply;
+            data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+            data.writeInt32(n++);
+            status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
+            if (err != NO_ERROR)
+                break;
+            res.add(reply.readString16());
+        }
+        return res;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+            LOGW("Call incorrectly routed to " #interface); \
+            return PERMISSION_DENIED; \
+        } } while (0)
+
+status_t BnServiceManager::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    //printf("ServiceManager received: "); data.print();
+    switch(code) {
+        case GET_SERVICE_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            String16 which = data.readString16();
+            sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which);
+            reply->writeStrongBinder(b);
+            return NO_ERROR;
+        } break;
+        case CHECK_SERVICE_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            String16 which = data.readString16();
+            sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which);
+            reply->writeStrongBinder(b);
+            return NO_ERROR;
+        } break;
+        case ADD_SERVICE_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            String16 which = data.readString16();
+            sp<IBinder> b = data.readStrongBinder();
+            status_t err = addService(which, b);
+            reply->writeInt32(err);
+            return NO_ERROR;
+        } break;
+        case LIST_SERVICES_TRANSACTION: {
+            CHECK_INTERFACE(IServiceManager, data, reply);
+            Vector<String16> list = listServices();
+            const size_t N = list.size();
+            reply->writeInt32(N);
+            for (size_t i=0; i<N; i++) {
+                reply->writeString16(list[i]);
+            }
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/utils/InetAddress.cpp b/libs/utils/InetAddress.cpp
new file mode 100644
index 0000000..39a0a68
--- /dev/null
+++ b/libs/utils/InetAddress.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Internet address class.
+//
+#ifdef HAVE_WINSOCK
+# include <winsock2.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+//# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
+#include <utils/inet_address.h>
+#include <utils/threads.h>
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+using namespace android;
+
+
+/*
+ * ===========================================================================
+ *      InetAddress
+ * ===========================================================================
+ */
+
+// lock for the next couple of functions; could tuck into InetAddress
+static Mutex*   gGHBNLock;
+
+/*
+ * Lock/unlock access to the hostent struct returned by gethostbyname().
+ */
+static inline void lock_gethostbyname(void)
+{
+    if (gGHBNLock == NULL)
+        gGHBNLock = new Mutex;
+    gGHBNLock->lock();
+}
+static inline void unlock_gethostbyname(void)
+{
+    assert(gGHBNLock != NULL);
+    gGHBNLock->unlock();
+}
+
+
+/*
+ * Constructor -- just init members.  This is private so that callers
+ * are required to use getByName().
+ */
+InetAddress::InetAddress(void)
+    : mAddress(NULL), mLength(-1), mName(NULL)
+{
+}
+
+/*
+ * Destructor -- free address storage.
+ */
+InetAddress::~InetAddress(void)
+{
+    delete[] (char*) mAddress;
+    delete[] mName;
+}
+
+/*
+ * Copy constructor.
+ */
+InetAddress::InetAddress(const InetAddress& orig)
+{
+    *this = orig;   // use assignment code
+}
+
+/*
+ * Assignment operator.
+ */
+InetAddress& InetAddress::operator=(const InetAddress& addr)
+{
+    // handle self-assignment
+    if (this == &addr)
+        return *this;
+    // copy mLength and mAddress
+    mLength = addr.mLength;
+    if (mLength > 0) {
+        mAddress = new char[mLength];
+        memcpy(mAddress, addr.mAddress, mLength);
+        LOG(LOG_DEBUG, "socket",
+            "HEY: copied %d bytes in assignment operator\n", mLength);
+    } else {
+        mAddress = NULL;
+    }
+    // copy mName
+    mName = new char[strlen(addr.mName)+1];
+    strcpy(mName, addr.mName);
+
+    return *this;
+}
+
+/*
+ * Create a new object from a name or a dotted-number IP notation.
+ *
+ * Returns NULL on failure.
+ */
+InetAddress*
+InetAddress::getByName(const char* host)
+{
+    InetAddress* newAddr = NULL;
+    struct sockaddr_in addr;
+    struct hostent* he;
+    DurationTimer hostTimer, lockTimer;
+
+    // gethostbyname() isn't reentrant, so we need to lock things until
+    // we can copy the data out.
+    lockTimer.start();
+    lock_gethostbyname();
+    hostTimer.start();
+
+    he = gethostbyname(host);
+    if (he == NULL) {
+        LOG(LOG_WARN, "socket", "WARNING: cannot resolve host %s\n", host);
+        unlock_gethostbyname();
+        return NULL;
+    }
+
+    memcpy(&addr.sin_addr, he->h_addr, he->h_length);
+    addr.sin_family = he->h_addrtype;
+    addr.sin_port = 0;
+
+    // got it, unlock us
+    hostTimer.stop();
+    he = NULL;
+    unlock_gethostbyname();
+
+    lockTimer.stop();
+    if ((long) lockTimer.durationUsecs() > 100000) {
+        long lockTime = (long) lockTimer.durationUsecs();
+        long hostTime = (long) hostTimer.durationUsecs();
+        LOG(LOG_DEBUG, "socket",
+            "Lookup of %s took %.3fs (gethostbyname=%.3fs lock=%.3fs)\n",
+            host, lockTime / 1000000.0, hostTime / 1000000.0,
+            (lockTime - hostTime) / 1000000.0);
+    }
+
+    // Alloc storage and copy it over.
+    newAddr = new InetAddress();
+    if (newAddr == NULL)
+        return NULL;
+
+    newAddr->mLength = sizeof(struct sockaddr_in);
+    newAddr->mAddress = new char[sizeof(struct sockaddr_in)];
+    if (newAddr->mAddress == NULL) {
+        delete newAddr;
+        return NULL;
+    }
+    memcpy(newAddr->mAddress, &addr, newAddr->mLength);
+
+    // Keep this for debug messages.
+    newAddr->mName = new char[strlen(host)+1];
+    if (newAddr->mName == NULL) {
+        delete newAddr;
+        return NULL;
+    }
+    strcpy(newAddr->mName, host);
+
+    return newAddr;
+}
+
+
+/*
+ * ===========================================================================
+ *      InetSocketAddress
+ * ===========================================================================
+ */
+
+/*
+ * Create an address with the host wildcard (INADDR_ANY).
+ */
+bool InetSocketAddress::create(int port)
+{
+    assert(mAddress == NULL);
+
+    mAddress = InetAddress::getByName("0.0.0.0");
+    if (mAddress == NULL)
+        return false;
+    mPort = port;
+    return true;
+}
+
+/*
+ * Create address with host and port specified.
+ */
+bool InetSocketAddress::create(const InetAddress* addr, int port)
+{
+    assert(mAddress == NULL);
+
+    mAddress = new InetAddress(*addr);  // make a copy
+    if (mAddress == NULL)
+        return false;
+    mPort = port;
+    return true;
+}
+
+/*
+ * Create address with host and port specified.
+ */
+bool InetSocketAddress::create(const char* host, int port)
+{
+    assert(mAddress == NULL);
+
+    mAddress = InetAddress::getByName(host);
+    if (mAddress == NULL)
+        return false;
+    mPort = port;
+    return true;
+}
+
diff --git a/libs/utils/LogSocket.cpp b/libs/utils/LogSocket.cpp
new file mode 100644
index 0000000..e64f794
--- /dev/null
+++ b/libs/utils/LogSocket.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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 HAVE_WINSOCK
+#define SOCKETLOG
+#endif
+
+#ifdef SOCKETLOG
+
+#define LOG_TAG "SOCKETLOG"
+
+#include <string.h>
+#include <cutils/log.h>
+#include "utils/LogSocket.h"
+#include "utils/logger.h"
+#include "cutils/hashmap.h"
+
+// defined in //device/data/etc/event-log-tags
+#define SOCKET_CLOSE_LOG 51000
+
+static Hashmap* statsMap = NULL;
+
+#define LOG_LIST_NUMBER 5
+
+typedef struct SocketStats {
+    int fd;
+    unsigned int send;
+    unsigned int recv;
+    unsigned int ip;
+    unsigned short port;
+    short reason;
+}SocketStats;
+
+SocketStats *get_socket_stats(int fd) {
+    if (statsMap == NULL) {
+        statsMap = hashmapCreate(8, &hashmapIntHash, &hashmapIntEquals);
+    }
+
+    SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
+    if (s == NULL) {
+        // LOGD("create SocketStats for fd %d", fd);
+        s = (SocketStats*) malloc(sizeof(SocketStats));
+        memset(s, 0, sizeof(SocketStats));
+        s->fd = fd;
+        hashmapPut(statsMap, &s->fd, s);
+    }
+    return s;
+}
+
+void log_socket_connect(int fd, unsigned int ip, unsigned short port) {
+    // LOGD("log_socket_connect for fd %d ip %d port%d", fd, ip, port);
+    SocketStats *s = get_socket_stats(fd);
+    s->ip = ip;
+    s->port = port;
+}
+
+void add_send_stats(int fd, int send) {
+    if (send <=0) {
+        LOGE("add_send_stats send %d", send);
+        return;
+    }
+    SocketStats *s = get_socket_stats(fd);
+    s->send += send;
+    // LOGD("add_send_stats for fd %d ip %d port%d", fd, s->ip, s->port);
+}
+
+void add_recv_stats(int fd, int recv) {
+    if (recv <=0) {
+        LOGE("add_recv_stats recv %d", recv);
+        return;
+    }
+    SocketStats *s = get_socket_stats(fd);
+    s->recv += recv;
+    // LOGD("add_recv_stats for fd %d ip %d port%d", fd, s->ip, s->port);
+}
+
+char* put_int(char* buf, int value) {
+    *buf = EVENT_TYPE_INT;
+    buf++;
+    memcpy(buf, &value, sizeof(int));
+    return buf + sizeof(int);
+}
+
+void log_socket_close(int fd, short reason) {
+    if (statsMap) {
+        SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
+        if (s != NULL) {
+            if (s->send != 0 || s->recv != 0) {
+                s->reason = reason;
+                // 5 int + list type need 2 bytes
+                char buf[LOG_LIST_NUMBER * 5 + 2];
+                buf[0] = EVENT_TYPE_LIST;
+                buf[1] = LOG_LIST_NUMBER;
+                char* writePos = buf + 2;
+                writePos = put_int(writePos, s->send);
+                writePos = put_int(writePos, s->recv);
+                writePos = put_int(writePos, s->ip);
+                writePos = put_int(writePos, s->port);
+                writePos = put_int(writePos, s->reason);
+                
+                android_bWriteLog(SOCKET_CLOSE_LOG, buf, sizeof(buf));
+                // LOGD("send %d recv %d reason %d", s->send, s->recv, s->reason);
+            }
+            hashmapRemove(statsMap, &s->fd);
+            free(s);
+        }
+    }
+}
+
+#else
+void add_send_stats(int fd, int send) {} 
+void add_recv_stats(int fd, int recv) {}
+void log_socket_close(int fd, short reason) {}
+void log_socket_connect(int fd, unsigned int ip, unsigned short port) {}
+#endif
diff --git a/libs/utils/MODULE_LICENSE_APACHE2 b/libs/utils/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/utils/MODULE_LICENSE_APACHE2
diff --git a/libs/utils/MemoryBase.cpp b/libs/utils/MemoryBase.cpp
new file mode 100644
index 0000000..f25e11c
--- /dev/null
+++ b/libs/utils/MemoryBase.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 <stdlib.h>
+#include <stdint.h>
+
+#include <utils/MemoryBase.h>
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+MemoryBase::MemoryBase(const sp<IMemoryHeap>& heap,
+        ssize_t offset, size_t size)
+    : mSize(size), mOffset(offset), mHeap(heap)
+{
+}
+
+sp<IMemoryHeap> MemoryBase::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (offset) *offset = mOffset;
+    if (size)   *size = mSize;
+    return mHeap;
+}
+
+MemoryBase::~MemoryBase()
+{
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/MemoryDealer.cpp b/libs/utils/MemoryDealer.cpp
new file mode 100644
index 0000000..e6d1d18
--- /dev/null
+++ b/libs/utils/MemoryDealer.cpp
@@ -0,0 +1,407 @@
+/*
+ * 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 "MemoryDealer"
+
+#include <utils/MemoryDealer.h>
+
+#include <utils/Log.h>
+#include <utils/IPCThreadState.h>
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
+#include <utils/MemoryBase.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/file.h>
+
+namespace android {
+
+
+// ----------------------------------------------------------------------------
+
+class SimpleMemory : public MemoryBase {
+public:
+    SimpleMemory(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);
+    virtual ~SimpleMemory();
+};
+
+
+// ----------------------------------------------------------------------------
+
+MemoryDealer::Allocation::Allocation(
+        const sp<MemoryDealer>& dealer, ssize_t offset, size_t size,
+        const sp<IMemory>& memory)
+    : mDealer(dealer), mOffset(offset), mSize(size), mMemory(memory) 
+{
+}
+
+MemoryDealer::Allocation::~Allocation()
+{
+    if (mSize) {
+        /* NOTE: it's VERY important to not free allocations of size 0 because
+         * they're special as they don't have any record in the allocator
+         * and could alias some real allocation (their offset is zero). */
+        mDealer->deallocate(mOffset);
+    }
+}
+
+sp<IMemoryHeap> MemoryDealer::Allocation::getMemory(
+    ssize_t* offset, size_t* size) const
+{
+    return mMemory->getMemory(offset, size);
+}
+
+// ----------------------------------------------------------------------------
+
+MemoryDealer::MemoryDealer(size_t size, uint32_t flags, const char* name)
+    : mHeap(new SharedHeap(size, flags, name)),
+    mAllocator(new SimpleBestFitAllocator(size))
+{    
+}
+
+MemoryDealer::MemoryDealer(const sp<HeapInterface>& heap)
+    : mHeap(heap),
+    mAllocator(new SimpleBestFitAllocator(heap->virtualSize()))
+{
+}
+
+MemoryDealer::MemoryDealer( const sp<HeapInterface>& heap,
+        const sp<AllocatorInterface>& allocator)
+    : mHeap(heap), mAllocator(allocator)
+{
+}
+
+MemoryDealer::~MemoryDealer()
+{
+}
+
+sp<IMemory> MemoryDealer::allocate(size_t size, uint32_t flags)
+{
+    sp<IMemory> memory;
+    const ssize_t offset = allocator()->allocate(size, flags);
+    if (offset >= 0) {
+        sp<IMemory> new_memory = heap()->mapMemory(offset, size);
+        if (new_memory != 0) {
+            memory = new Allocation(this, offset, size, new_memory);
+        } else {
+            LOGE("couldn't map [%8x, %d]", offset, size);
+            if (size) {
+                /* NOTE: it's VERY important to not free allocations of size 0
+                 * because they're special as they don't have any record in the 
+                 * allocator and could alias some real allocation 
+                 * (their offset is zero). */
+                allocator()->deallocate(offset);
+            }
+        }        
+    }
+    return memory;
+}
+
+void MemoryDealer::deallocate(size_t offset)
+{
+    allocator()->deallocate(offset);
+}
+
+void MemoryDealer::dump(const char* what, uint32_t flags) const
+{
+    allocator()->dump(what, flags);
+}
+
+const sp<HeapInterface>& MemoryDealer::heap() const {
+    return mHeap;
+}
+
+const sp<AllocatorInterface>& MemoryDealer::allocator() const {
+    return mAllocator;
+}
+
+// ----------------------------------------------------------------------------
+
+// align all the memory blocks on a cache-line boundary
+const int SimpleBestFitAllocator::kMemoryAlign = 32;
+
+SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
+{
+    size_t pagesize = getpagesize();
+    mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
+
+    chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
+    mList.insertHead(node);
+}
+
+SimpleBestFitAllocator::~SimpleBestFitAllocator()
+{
+    while(!mList.isEmpty()) {
+        delete mList.remove(mList.head());
+    }
+}
+
+size_t SimpleBestFitAllocator::size() const
+{
+    return mHeapSize;
+}
+
+size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
+{
+    Mutex::Autolock _l(mLock);
+    ssize_t offset = alloc(size, flags);
+    return offset;
+}
+
+status_t SimpleBestFitAllocator::deallocate(size_t offset)
+{
+    Mutex::Autolock _l(mLock);
+    chunk_t const * const freed = dealloc(offset);
+    if (freed) {
+        return NO_ERROR;
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
+{
+    if (size == 0) {
+        return 0;
+    }
+    size = (size + kMemoryAlign-1) / kMemoryAlign;
+    chunk_t* free_chunk = 0;
+    chunk_t* cur = mList.head();
+
+    size_t pagesize = getpagesize();
+    while (cur) {
+        int extra = 0;
+        if (flags & PAGE_ALIGNED)
+            extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;
+
+        // best fit
+        if (cur->free && (cur->size >= (size+extra))) {
+            if ((!free_chunk) || (cur->size < free_chunk->size)) {
+                free_chunk = cur;
+            }
+            if (cur->size == size) {
+                break;
+            }
+        }
+        cur = cur->next;
+    }
+
+    if (free_chunk) {
+        const size_t free_size = free_chunk->size;
+        free_chunk->free = 0;
+        free_chunk->size = size;
+        if (free_size > size) {
+            int extra = 0;
+            if (flags & PAGE_ALIGNED)
+                extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
+            if (extra) {
+                chunk_t* split = new chunk_t(free_chunk->start, extra);
+                free_chunk->start += extra;
+                mList.insertBefore(free_chunk, split);
+            }
+
+            LOGE_IF((flags&PAGE_ALIGNED) && 
+                    ((free_chunk->start*kMemoryAlign)&(pagesize-1)),
+                    "PAGE_ALIGNED requested, but page is not aligned!!!");
+
+            const ssize_t tail_free = free_size - (size+extra);
+            if (tail_free > 0) {
+                chunk_t* split = new chunk_t(
+                        free_chunk->start + free_chunk->size, tail_free);
+                mList.insertAfter(free_chunk, split);
+            }
+        }
+        return (free_chunk->start)*kMemoryAlign;
+    }
+    return NO_MEMORY;
+}
+
+SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
+{
+    start = start / kMemoryAlign;
+    chunk_t* cur = mList.head();
+    while (cur) {
+        if (cur->start == start) {
+            LOG_FATAL_IF(cur->free,
+                "block at offset 0x%08lX of size 0x%08lX already freed",
+                cur->start*kMemoryAlign, cur->size*kMemoryAlign);
+
+            // merge freed blocks together
+            chunk_t* freed = cur;
+            cur->free = 1;
+            do {
+                chunk_t* const p = cur->prev;
+                chunk_t* const n = cur->next;
+                if (p && (p->free || !cur->size)) {
+                    freed = p;
+                    p->size += cur->size;
+                    mList.remove(cur);
+                    delete cur;
+                }
+                cur = n;
+            } while (cur && cur->free);
+
+            #ifndef NDEBUG
+                if (!freed->free) {
+                    dump_l("dealloc (!freed->free)");
+                }
+            #endif
+            LOG_FATAL_IF(!freed->free,
+                "freed block at offset 0x%08lX of size 0x%08lX is not free!",
+                freed->start * kMemoryAlign, freed->size * kMemoryAlign);
+
+            return freed;
+        }
+        cur = cur->next;
+    }
+    return 0;
+}
+
+void SimpleBestFitAllocator::dump(const char* what, uint32_t flags) const
+{
+    Mutex::Autolock _l(mLock);
+    dump_l(what, flags);
+}
+
+void SimpleBestFitAllocator::dump_l(const char* what, uint32_t flags) const
+{
+    String8 result;
+    dump_l(result, what, flags);
+    LOGD("%s", result.string());
+}
+
+void SimpleBestFitAllocator::dump(String8& result,
+        const char* what, uint32_t flags) const
+{
+    Mutex::Autolock _l(mLock);
+    dump_l(result, what, flags);
+}
+
+void SimpleBestFitAllocator::dump_l(String8& result,
+        const char* what, uint32_t flags) const
+{
+    size_t size = 0;
+    int32_t i = 0;
+    chunk_t const* cur = mList.head();
+    
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    snprintf(buffer, SIZE, "  %s (%p, size=%u)\n",
+            what, this, (unsigned int)mHeapSize);
+    
+    result.append(buffer);
+            
+    while (cur) {
+        const char* errs[] = {"", "| link bogus NP",
+                            "| link bogus PN", "| link bogus NP+PN" };
+        int np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
+        int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;
+
+        snprintf(buffer, SIZE, "  %3u: %08x | 0x%08X | 0x%08X | %s %s\n",
+            i, int(cur), int(cur->start*kMemoryAlign),
+            int(cur->size*kMemoryAlign),
+                    int(cur->free) ? "F" : "A",
+                    errs[np|pn]);
+        
+        result.append(buffer);
+
+        if (!cur->free)
+            size += cur->size*kMemoryAlign;
+
+        i++;
+        cur = cur->next;
+    }
+    snprintf(buffer, SIZE, "  size allocated: %u (%u KB)\n", int(size), int(size/1024));
+    result.append(buffer);
+}
+        
+// ----------------------------------------------------------------------------
+
+
+SharedHeap::SharedHeap(size_t size, uint32_t flags, char const * name)
+    : MemoryHeapBase(size, flags, name)
+{
+}
+
+SharedHeap::~SharedHeap()
+{
+}
+
+sp<IMemory> SharedHeap::mapMemory(size_t offset, size_t size)
+{
+    return new SimpleMemory(this, offset, size);
+}
+ 
+
+SimpleMemory::SimpleMemory(const sp<IMemoryHeap>& heap,
+        ssize_t offset, size_t size)
+    : MemoryBase(heap, offset, size)
+{
+#ifndef NDEBUG
+    void* const start_ptr = (void*)(intptr_t(heap->base()) + offset);
+    memset(start_ptr, 0xda, size);
+#endif
+}
+
+SimpleMemory::~SimpleMemory()
+{
+    size_t freedOffset = getOffset();
+    size_t freedSize   = getSize();
+
+    // keep the size to unmap in excess
+    size_t pagesize = getpagesize();
+    size_t start = freedOffset;
+    size_t end = start + freedSize;
+    start &= ~(pagesize-1);
+    end = (end + pagesize-1) & ~(pagesize-1);
+
+    // give back to the kernel the pages we don't need
+    size_t free_start = freedOffset;
+    size_t free_end = free_start + freedSize;
+    if (start < free_start)
+        start = free_start;
+    if (end > free_end)
+        end = free_end;
+    start = (start + pagesize-1) & ~(pagesize-1);
+    end &= ~(pagesize-1);    
+
+    void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start);
+    size_t size = end-start;
+
+#ifndef NDEBUG
+    memset(start_ptr, 0xdf, size);
+#endif
+  
+// MADV_REMOVE is not defined on Dapper based Goobuntu 
+#ifdef MADV_REMOVE 
+    if (size) {
+        int err = madvise(start_ptr, size, MADV_REMOVE);
+        LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
+                start_ptr, size, err<0 ? strerror(errno) : "Ok");
+    }
+#endif
+}
+
+}; // namespace android
diff --git a/libs/utils/MemoryHeapBase.cpp b/libs/utils/MemoryHeapBase.cpp
new file mode 100644
index 0000000..59963c9
--- /dev/null
+++ b/libs/utils/MemoryHeapBase.cpp
@@ -0,0 +1,178 @@
+/*
+ * 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 "MemoryHeapBase"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/ashmem.h>
+#include <cutils/atomic.h>
+
+#include <utils/MemoryHeapBase.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+MemoryHeapBase::MemoryHeapBase() 
+    : mFD(-1), mSize(0), mBase(MAP_FAILED),
+      mDevice(NULL), mNeedUnmap(false) 
+{
+}
+
+MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
+    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
+      mDevice(0), mNeedUnmap(false)
+{
+    const size_t pagesize = getpagesize();
+    size = ((size + pagesize-1) & ~(pagesize-1));
+    int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
+    LOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
+    if (fd >= 0) {
+        if (mapfd(fd, size) == NO_ERROR) {
+            if (flags & READ_ONLY) {
+                ashmem_set_prot_region(fd, PROT_READ);
+            }
+        }
+    }
+}
+
+MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
+    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
+      mDevice(0), mNeedUnmap(false)
+{
+    int fd = open(device, O_RDWR);
+    LOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno));
+    if (fd >= 0) {
+        const size_t pagesize = getpagesize();
+        size = ((size + pagesize-1) & ~(pagesize-1));
+        if (mapfd(fd, size) == NO_ERROR) {
+            mDevice = device;
+        }
+    }
+}
+
+MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags)
+    : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
+      mDevice(0), mNeedUnmap(false)
+{
+    const size_t pagesize = getpagesize();
+    size = ((size + pagesize-1) & ~(pagesize-1));
+    mapfd(dup(fd), size);
+}
+
+status_t MemoryHeapBase::init(int fd, void *base, int size, int flags, const char* device)
+{
+    if (mFD != -1) {
+        return INVALID_OPERATION;
+    }
+    mFD = fd;
+    mBase = base;
+    mSize = size;
+    mFlags = flags;
+    mDevice = device;
+    return NO_ERROR;
+}
+
+status_t MemoryHeapBase::mapfd(int fd, size_t size)
+{
+    if (size == 0) {
+        // try to figure out the size automatically
+#if HAVE_ANDROID_OS
+        // first try the PMEM ioctl
+        pmem_region reg;
+        int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, &reg);
+        if (err == 0)
+            size = reg.len;
+#endif
+        if (size == 0) { // try fstat
+            struct stat sb;
+            if (fstat(fd, &sb) == 0)
+                size = sb.st_size;
+        }
+        // if it didn't work, let mmap() fail.
+    }
+
+    void* base = (uint8_t*)mmap(0, size,
+            PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    if (base == MAP_FAILED) {
+        LOGE("mmap(fd=%d, size=%u) failed (%s)",
+                fd, uint32_t(size), strerror(errno));
+        close(fd);
+        return -errno;
+    }
+    //LOGD("mmap(fd=%d, base=%p, size=%lu)", fd, base, size);
+    mFD = fd;
+    mBase = base;
+    mSize = size;
+    mNeedUnmap = true;
+    return NO_ERROR;
+}
+
+MemoryHeapBase::~MemoryHeapBase()
+{
+    dispose();
+}
+
+void MemoryHeapBase::dispose()
+{
+    int fd = android_atomic_or(-1, &mFD);
+    if (fd >= 0) {
+        if (mNeedUnmap) {
+            //LOGD("munmap(fd=%d, base=%p, size=%lu)", fd, mBase, mSize);
+            munmap(mBase, mSize);
+        }
+        mBase = 0;
+        mSize = 0;
+        close(fd);
+    }
+}
+
+int MemoryHeapBase::getHeapID() const {
+    return mFD;
+}
+
+void* MemoryHeapBase::getBase() const {
+    return mBase;
+}
+
+size_t MemoryHeapBase::getSize() const {
+    return mSize;
+}
+
+uint32_t MemoryHeapBase::getFlags() const {
+    return mFlags;
+}
+
+const char* MemoryHeapBase::getDevice() const {
+    return mDevice;
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/MemoryHeapPmem.cpp b/libs/utils/MemoryHeapPmem.cpp
new file mode 100644
index 0000000..1e5a1cc
--- /dev/null
+++ b/libs/utils/MemoryHeapPmem.cpp
@@ -0,0 +1,226 @@
+/*
+ * 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 "MemoryHeapPmem"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MemoryHeapPmem;
+
+class SubRegionMemory : public BnMemory {
+public:
+    SubRegionMemory(const sp<MemoryHeapPmem>& heap, ssize_t offset, size_t size);
+    virtual ~SubRegionMemory();
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+private:
+    friend class MemoryHeapPmem;
+    void revoke();
+    size_t              mSize;
+    ssize_t             mOffset;
+    sp<MemoryHeapPmem>  mClientHeap;
+};
+
+SubRegionMemory::SubRegionMemory(const sp<MemoryHeapPmem>& heap,
+        ssize_t offset, size_t size)
+    : mSize(size), mOffset(offset), mClientHeap(heap)
+{
+#ifndef NDEBUG
+    void* const start_ptr = (void*)(intptr_t(mClientHeap->base()) + offset);
+    memset(start_ptr, 0xda, size);
+#endif
+
+#if HAVE_ANDROID_OS
+    if (size > 0) {
+        const size_t pagesize = getpagesize();
+        size = (size + pagesize-1) & ~(pagesize-1);
+        int our_fd = heap->heapID();
+        struct pmem_region sub = { offset, size };
+        int err = ioctl(our_fd, PMEM_MAP, &sub);
+        LOGE_IF(err<0, "PMEM_MAP failed (%s), "
+                "mFD=%d, sub.offset=%lu, sub.size=%lu",
+                strerror(errno), our_fd, sub.offset, sub.len);
+}
+#endif
+}
+
+sp<IMemoryHeap> SubRegionMemory::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (offset) *offset = mOffset;
+    if (size)   *size = mSize;
+    return mClientHeap;
+}
+
+SubRegionMemory::~SubRegionMemory()
+{
+    revoke();
+}
+
+
+void SubRegionMemory::revoke()
+{
+    // NOTE: revoke() doesn't need to be protected by a lock because it
+    // can only be called from MemoryHeapPmem::revoke(), which means
+    // that we can't be in ~SubRegionMemory(), or in ~SubRegionMemory(),
+    // which means MemoryHeapPmem::revoke() wouldn't have been able to 
+    // promote() it.
+    
+#if HAVE_ANDROID_OS
+    if (mClientHeap != NULL) {
+        int our_fd = mClientHeap->heapID();
+        struct pmem_region sub;
+        sub.offset = mOffset;
+        sub.len = mSize;
+        int err = ioctl(our_fd, PMEM_UNMAP, &sub);
+        LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
+                "mFD=%d, sub.offset=%lu, sub.size=%lu",
+                strerror(errno), our_fd, sub.offset, sub.len);
+        mClientHeap.clear();
+    }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
+MemoryHeapPmem::MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
+        uint32_t flags)
+    : HeapInterface(), MemoryHeapBase()
+{
+    char const * const device = pmemHeap->getDevice();
+#if HAVE_ANDROID_OS
+    if (device) {
+        int fd = open(device, O_RDWR);
+        LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
+        if (fd >= 0) {
+            int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID());
+            if (err < 0) {
+                LOGE("PMEM_CONNECT failed (%s), mFD=%d, sub-fd=%d",
+                        strerror(errno), fd, pmemHeap->heapID());
+                close(fd);
+            } else {
+                // everything went well...
+                mParentHeap = pmemHeap;
+                MemoryHeapBase::init(fd, 
+                        pmemHeap->getBase(),
+                        pmemHeap->getSize(),
+                        pmemHeap->getFlags() | flags,
+                        device);
+            }
+        }
+    }
+#else
+    mParentHeap = pmemHeap;
+    MemoryHeapBase::init( 
+            dup(pmemHeap->heapID()),
+            pmemHeap->getBase(),
+            pmemHeap->getSize(),
+            pmemHeap->getFlags() | flags,
+            device);
+#endif
+}
+
+MemoryHeapPmem::~MemoryHeapPmem()
+{
+}
+
+sp<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size)
+{
+    sp<SubRegionMemory> memory;
+    if (heapID() > 0) 
+        memory = new SubRegionMemory(this, offset, size);
+
+    if (memory != 0) {
+        Mutex::Autolock _l(mLock);
+        mAllocations.add(memory);
+    }
+    return memory;
+}
+
+status_t MemoryHeapPmem::slap()
+{
+#if HAVE_ANDROID_OS
+    size_t size = getSize();
+    const size_t pagesize = getpagesize();
+    size = (size + pagesize-1) & ~(pagesize-1);
+    int our_fd = getHeapID();
+    struct pmem_region sub = { 0, size };
+    int err = ioctl(our_fd, PMEM_MAP, &sub);
+    LOGE_IF(err<0, "PMEM_MAP failed (%s), "
+            "mFD=%d, sub.offset=%lu, sub.size=%lu",
+            strerror(errno), our_fd, sub.offset, sub.len);
+    return -errno;
+#else
+    return NO_ERROR;
+#endif
+}
+
+status_t MemoryHeapPmem::unslap()
+{
+#if HAVE_ANDROID_OS
+    size_t size = getSize();
+    const size_t pagesize = getpagesize();
+    size = (size + pagesize-1) & ~(pagesize-1);
+    int our_fd = getHeapID();
+    struct pmem_region sub = { 0, size };
+    int err = ioctl(our_fd, PMEM_UNMAP, &sub);
+    LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
+            "mFD=%d, sub.offset=%lu, sub.size=%lu",
+            strerror(errno), our_fd, sub.offset, sub.len);
+    return -errno;
+#else
+    return NO_ERROR;
+#endif
+}
+
+void MemoryHeapPmem::revoke()
+{
+    Vector< wp<SubRegionMemory> > allocations;
+
+    { // scope for lock
+        Mutex::Autolock _l(mLock);
+        allocations = mAllocations;
+        mAllocations.clear();
+    }
+    
+    ssize_t count = allocations.size();
+    for (ssize_t i=0 ; i<count ; i++) {
+        sp<SubRegionMemory> memory(allocations[i].promote());
+        if (memory != 0)
+            memory->revoke();
+    }
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/NOTICE b/libs/utils/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/libs/utils/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
new file mode 100644
index 0000000..3eca4b0
--- /dev/null
+++ b/libs/utils/Parcel.cpp
@@ -0,0 +1,1311 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "Parcel"
+//#define LOG_NDEBUG 0
+
+#include <utils/Parcel.h>
+
+#include <utils/Binder.h>
+#include <utils/BpBinder.h>
+#include <utils/Debug.h>
+#include <utils/ProcessState.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/TextOutput.h>
+#include <utils/misc.h>
+
+#include <private/utils/binder_module.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifndef INT32_MAX
+#define INT32_MAX ((int32_t)(2147483647))
+#endif
+
+#define LOG_REFS(...)
+//#define LOG_REFS(...) LOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
+
+// ---------------------------------------------------------------------------
+
+#define PAD_SIZE(s) (((s)+3)&~3)
+
+// XXX This can be made public if we want to provide
+// support for typed data.
+struct small_flat_data
+{
+    uint32_t type;
+    uint32_t data;
+};
+
+namespace android {
+
+void acquire_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who)
+{
+    switch (obj.type) {
+        case BINDER_TYPE_BINDER:
+            if (obj.binder) {
+                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
+                static_cast<IBinder*>(obj.cookie)->incStrong(who);
+            }
+            return;
+        case BINDER_TYPE_WEAK_BINDER:
+            if (obj.binder)
+                static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
+            return;
+        case BINDER_TYPE_HANDLE: {
+            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
+            if (b != NULL) {
+                LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
+                b->incStrong(who);
+            }
+            return;
+        }
+        case BINDER_TYPE_WEAK_HANDLE: {
+            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
+            if (b != NULL) b.get_refs()->incWeak(who);
+            return;
+        }
+        case BINDER_TYPE_FD: {
+            // intentionally blank -- nothing to do to acquire this, but we do
+            // recognize it as a legitimate object type.
+            return;
+        }
+    }
+
+    LOGD("Invalid object type 0x%08lx", obj.type);
+}
+
+void release_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who)
+{
+    switch (obj.type) {
+        case BINDER_TYPE_BINDER:
+            if (obj.binder) {
+                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
+                static_cast<IBinder*>(obj.cookie)->decStrong(who);
+            }
+            return;
+        case BINDER_TYPE_WEAK_BINDER:
+            if (obj.binder)
+                static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
+            return;
+        case BINDER_TYPE_HANDLE: {
+            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
+            if (b != NULL) {
+                LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
+                b->decStrong(who);
+            }
+            return;
+        }
+        case BINDER_TYPE_WEAK_HANDLE: {
+            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
+            if (b != NULL) b.get_refs()->decWeak(who);
+            return;
+        }
+        case BINDER_TYPE_FD: {
+            if (obj.cookie != (void*)0) close(obj.handle);
+            return;
+        }
+    }
+
+    LOGE("Invalid object type 0x%08lx", obj.type);
+}
+
+inline static status_t finish_flatten_binder(
+    const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)
+{
+    return out->writeObject(flat, false);
+}
+
+status_t flatten_binder(const sp<ProcessState>& proc,
+    const sp<IBinder>& binder, Parcel* out)
+{
+    flat_binder_object obj;
+    
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    if (binder != NULL) {
+        IBinder *local = binder->localBinder();
+        if (!local) {
+            BpBinder *proxy = binder->remoteBinder();
+            if (proxy == NULL) {
+                LOGE("null proxy");
+            }
+            const int32_t handle = proxy ? proxy->handle() : 0;
+            obj.type = BINDER_TYPE_HANDLE;
+            obj.handle = handle;
+            obj.cookie = NULL;
+        } else {
+            obj.type = BINDER_TYPE_BINDER;
+            obj.binder = local->getWeakRefs();
+            obj.cookie = local;
+        }
+    } else {
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+    }
+    
+    return finish_flatten_binder(binder, obj, out);
+}
+
+status_t flatten_binder(const sp<ProcessState>& proc,
+    const wp<IBinder>& binder, Parcel* out)
+{
+    flat_binder_object obj;
+    
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    if (binder != NULL) {
+        sp<IBinder> real = binder.promote();
+        if (real != NULL) {
+            IBinder *local = real->localBinder();
+            if (!local) {
+                BpBinder *proxy = real->remoteBinder();
+                if (proxy == NULL) {
+                    LOGE("null proxy");
+                }
+                const int32_t handle = proxy ? proxy->handle() : 0;
+                obj.type = BINDER_TYPE_WEAK_HANDLE;
+                obj.handle = handle;
+                obj.cookie = NULL;
+            } else {
+                obj.type = BINDER_TYPE_WEAK_BINDER;
+                obj.binder = binder.get_refs();
+                obj.cookie = binder.unsafe_get();
+            }
+            return finish_flatten_binder(real, obj, out);
+        }
+        
+        // XXX How to deal?  In order to flatten the given binder,
+        // we need to probe it for information, which requires a primary
+        // reference...  but we don't have one.
+        //
+        // The OpenBinder implementation uses a dynamic_cast<> here,
+        // but we can't do that with the different reference counting
+        // implementation we are using.
+        LOGE("Unable to unflatten Binder weak reference!");
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+        return finish_flatten_binder(NULL, obj, out);
+    
+    } else {
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+        return finish_flatten_binder(NULL, obj, out);
+    }
+}
+
+inline static status_t finish_unflatten_binder(
+    BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
+{
+    return NO_ERROR;
+}
+    
+status_t unflatten_binder(const sp<ProcessState>& proc,
+    const Parcel& in, sp<IBinder>* out)
+{
+    const flat_binder_object* flat = in.readObject(false);
+    
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_BINDER:
+                *out = static_cast<IBinder*>(flat->cookie);
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_HANDLE:
+                *out = proc->getStrongProxyForHandle(flat->handle);
+                return finish_unflatten_binder(
+                    static_cast<BpBinder*>(out->get()), *flat, in);
+        }        
+    }
+    return BAD_TYPE;
+}
+
+status_t unflatten_binder(const sp<ProcessState>& proc,
+    const Parcel& in, wp<IBinder>* out)
+{
+    const flat_binder_object* flat = in.readObject(false);
+    
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_BINDER:
+                *out = static_cast<IBinder*>(flat->cookie);
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_WEAK_BINDER:
+                if (flat->binder != NULL) {
+                    out->set_object_and_refs(
+                        static_cast<IBinder*>(flat->cookie),
+                        static_cast<RefBase::weakref_type*>(flat->binder));
+                } else {
+                    *out = NULL;
+                }
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_HANDLE:
+            case BINDER_TYPE_WEAK_HANDLE:
+                *out = proc->getWeakProxyForHandle(flat->handle);
+                return finish_unflatten_binder(
+                    static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
+        }
+    }
+    return BAD_TYPE;
+}
+
+// ---------------------------------------------------------------------------
+
+Parcel::Parcel()
+{
+    initState();
+}
+
+Parcel::~Parcel()
+{
+    freeDataNoInit();
+}
+
+const uint8_t* Parcel::data() const
+{
+    return mData;
+}
+
+size_t Parcel::dataSize() const
+{
+    return (mDataSize > mDataPos ? mDataSize : mDataPos);
+}
+
+size_t Parcel::dataAvail() const
+{
+    // TODO: decide what to do about the possibility that this can
+    // report an available-data size that exceeds a Java int's max
+    // positive value, causing havoc.  Fortunately this will only
+    // happen if someone constructs a Parcel containing more than two
+    // gigabytes of data, which on typical phone hardware is simply
+    // not possible.
+    return dataSize() - dataPosition();
+}
+
+size_t Parcel::dataPosition() const
+{
+    return mDataPos;
+}
+
+size_t Parcel::dataCapacity() const
+{
+    return mDataCapacity;
+}
+
+status_t Parcel::setDataSize(size_t size)
+{
+    status_t err;
+    err = continueWrite(size);
+    if (err == NO_ERROR) {
+        mDataSize = size;
+        LOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
+    }
+    return err;
+}
+
+void Parcel::setDataPosition(size_t pos) const
+{
+    mDataPos = pos;
+    mNextObjectHint = 0;
+}
+
+status_t Parcel::setDataCapacity(size_t size)
+{
+    if (size > mDataSize) return continueWrite(size);
+    return NO_ERROR;
+}
+
+status_t Parcel::setData(const uint8_t* buffer, size_t len)
+{
+    status_t err = restartWrite(len);
+    if (err == NO_ERROR) {
+        memcpy(const_cast<uint8_t*>(data()), buffer, len);
+        mDataSize = len;
+        mFdsKnown = false;
+    }
+    return err;
+}
+
+status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    status_t err;
+    uint8_t *data = parcel->mData;
+    size_t *objects = parcel->mObjects;
+    size_t size = parcel->mObjectsSize;
+    int startPos = mDataPos;
+    int firstIndex = -1, lastIndex = -2;
+
+    if (len == 0) {
+        return NO_ERROR;
+    }
+
+    // range checks against the source parcel size
+    if ((offset > parcel->mDataSize)
+            || (len > parcel->mDataSize)
+            || (offset + len > parcel->mDataSize)) {
+        return BAD_VALUE;
+    }
+
+    // Count objects in range
+    for (int i = 0; i < (int) size; i++) {
+        size_t off = objects[i];
+        if ((off >= offset) && (off < offset + len)) {
+            if (firstIndex == -1) {
+                firstIndex = i;
+            }
+            lastIndex = i;
+        }
+    }
+    int numObjects = lastIndex - firstIndex + 1;
+
+    // grow data
+    err = growData(len);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    // append data
+    memcpy(mData + mDataPos, data + offset, len);
+    mDataPos += len;
+    mDataSize += len;
+
+    if (numObjects > 0) {
+        // grow objects
+        if (mObjectsCapacity < mObjectsSize + numObjects) {
+            int newSize = ((mObjectsSize + numObjects)*3)/2;
+            size_t *objects =
+                (size_t*)realloc(mObjects, newSize*sizeof(size_t));
+            if (objects == (size_t*)0) {
+                return NO_MEMORY;
+            }
+            mObjects = objects;
+            mObjectsCapacity = newSize;
+        }
+        
+        // append and acquire objects
+        int idx = mObjectsSize;
+        for (int i = firstIndex; i <= lastIndex; i++) {
+            size_t off = objects[i] - offset + startPos;
+            mObjects[idx++] = off;
+            mObjectsSize++;
+
+            const flat_binder_object* flat
+                = reinterpret_cast<flat_binder_object*>(mData + off);
+            acquire_object(proc, *flat, this);
+
+            // take note if the object is a file descriptor
+            if (flat->type == BINDER_TYPE_FD) {
+                mHasFds = mFdsKnown = true;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+bool Parcel::hasFileDescriptors() const
+{
+    if (!mFdsKnown) {
+        scanForFds();
+    }
+    return mHasFds;
+}
+
+status_t Parcel::writeInterfaceToken(const String16& interface)
+{
+    // currently the interface identification token is just its name as a string
+    return writeString16(interface);
+}
+
+bool Parcel::enforceInterface(const String16& interface) const
+{
+    String16 str = readString16();
+    if (str == interface) {
+        return true;
+    } else {
+        LOGW("**** enforceInterface() expected '%s' but read '%s'\n",
+                String8(interface).string(), String8(str).string());
+        return false;
+    }
+} 
+
+const size_t* Parcel::objects() const
+{
+    return mObjects;
+}
+
+size_t Parcel::objectsCount() const
+{
+    return mObjectsSize;
+}
+
+status_t Parcel::errorCheck() const
+{
+    return mError;
+}
+
+void Parcel::setError(status_t err)
+{
+    mError = err;
+}
+
+status_t Parcel::finishWrite(size_t len)
+{
+    //printf("Finish write of %d\n", len);
+    mDataPos += len;
+    LOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
+    if (mDataPos > mDataSize) {
+        mDataSize = mDataPos;
+        LOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
+    }
+    //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
+    return NO_ERROR;
+}
+
+status_t Parcel::writeUnpadded(const void* data, size_t len)
+{
+    size_t end = mDataPos + len;
+    if (end < mDataPos) {
+        // integer overflow
+        return BAD_VALUE;
+    }
+
+    if (end <= mDataCapacity) {
+restart_write:
+        memcpy(mData+mDataPos, data, len);
+        return finishWrite(len);
+    }
+
+    status_t err = growData(len);
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::write(const void* data, size_t len)
+{
+    void* const d = writeInplace(len);
+    if (d) {
+        memcpy(d, data, len);
+        return NO_ERROR;
+    }
+    return mError;
+}
+
+void* Parcel::writeInplace(size_t len)
+{
+    const size_t padded = PAD_SIZE(len);
+
+    // sanity check for integer overflow
+    if (mDataPos+padded < mDataPos) {
+        return NULL;
+    }
+
+    if ((mDataPos+padded) <= mDataCapacity) {
+restart_write:
+        //printf("Writing %ld bytes, padded to %ld\n", len, padded);
+        uint8_t* const data = mData+mDataPos;
+
+        // Need to pad at end?
+        if (padded != len) {
+#if BYTE_ORDER == BIG_ENDIAN
+            static const uint32_t mask[4] = {
+                0x00000000, 0xffffff00, 0xffff0000, 0xff000000
+            };
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+            static const uint32_t mask[4] = {
+                0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
+            };
+#endif
+            //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
+            //    *reinterpret_cast<void**>(data+padded-4));
+            *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
+        }
+
+        finishWrite(padded);
+        return data;
+    }
+
+    status_t err = growData(padded);
+    if (err == NO_ERROR) goto restart_write;
+    return NULL;
+}
+
+status_t Parcel::writeInt32(int32_t val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<int32_t*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeInt64(int64_t val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<int64_t*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeFloat(float val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<float*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeDouble(double val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<double*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeCString(const char* str)
+{
+    return write(str, strlen(str)+1);
+}
+
+status_t Parcel::writeString8(const String8& str)
+{
+    status_t err = writeInt32(str.bytes());
+    if (err == NO_ERROR) {
+        err = write(str.string(), str.bytes()+1);
+    }
+    return err;
+}
+
+status_t Parcel::writeString16(const String16& str)
+{
+    return writeString16(str.string(), str.size());
+}
+
+status_t Parcel::writeString16(const char16_t* str, size_t len)
+{
+    if (str == NULL) return writeInt32(-1);
+    
+    status_t err = writeInt32(len);
+    if (err == NO_ERROR) {
+        len *= sizeof(char16_t);
+        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
+        if (data) {
+            memcpy(data, str, len);
+            *reinterpret_cast<char16_t*>(data+len) = 0;
+            return NO_ERROR;
+        }
+        err = mError;
+    }
+    return err;
+}
+
+status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
+{
+    return flatten_binder(ProcessState::self(), val, this);
+}
+
+status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
+{
+    return flatten_binder(ProcessState::self(), val, this);
+}
+
+status_t Parcel::writeFileDescriptor(int fd)
+{
+    flat_binder_object obj;
+    obj.type = BINDER_TYPE_FD;
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    obj.handle = fd;
+    obj.cookie = (void*)0;
+    return writeObject(obj, true);
+}
+
+status_t Parcel::writeDupFileDescriptor(int fd)
+{
+    flat_binder_object obj;
+    obj.type = BINDER_TYPE_FD;
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    obj.handle = dup(fd);
+    obj.cookie = (void*)1;
+    return writeObject(obj, true);
+}
+
+status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
+{
+    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
+    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
+    if (enoughData && enoughObjects) {
+restart_write:
+        *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
+        
+        // Need to write meta-data?
+        if (nullMetaData || val.binder != NULL) {
+            mObjects[mObjectsSize] = mDataPos;
+            acquire_object(ProcessState::self(), val, this);
+            mObjectsSize++;
+        }
+        
+        // remember if it's a file descriptor
+        if (val.type == BINDER_TYPE_FD) {
+            mHasFds = mFdsKnown = true;
+        }
+
+        return finishWrite(sizeof(flat_binder_object));
+    }
+
+    if (!enoughData) {
+        const status_t err = growData(sizeof(val));
+        if (err != NO_ERROR) return err;
+    }
+    if (!enoughObjects) {
+        size_t newSize = ((mObjectsSize+2)*3)/2;
+        size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
+        if (objects == NULL) return NO_MEMORY;
+        mObjects = objects;
+        mObjectsCapacity = newSize;
+    }
+    
+    goto restart_write;
+}
+
+
+void Parcel::remove(size_t start, size_t amt)
+{
+    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
+}
+
+status_t Parcel::read(void* outData, size_t len) const
+{
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+        memcpy(outData, mData+mDataPos, len);
+        mDataPos += PAD_SIZE(len);
+        LOGV("read Setting data pos of %p to %d\n", this, mDataPos);
+        return NO_ERROR;
+    }
+    return NOT_ENOUGH_DATA;
+}
+
+const void* Parcel::readInplace(size_t len) const
+{
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += PAD_SIZE(len);
+        LOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
+        return data;
+    }
+    return NULL;
+}
+
+status_t Parcel::readInt32(int32_t *pArg) const
+{
+    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int32_t);
+        *pArg =  *reinterpret_cast<const int32_t*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+int32_t Parcel::readInt32() const
+{
+    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int32_t);
+        LOGV("readInt32 Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const int32_t*>(data);
+    }
+    return 0;
+}
+
+
+status_t Parcel::readInt64(int64_t *pArg) const
+{
+    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int64_t);
+        *pArg = *reinterpret_cast<const int64_t*>(data);
+        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+int64_t Parcel::readInt64() const
+{
+    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int64_t);
+        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const int64_t*>(data);
+    }
+    return 0;
+}
+
+status_t Parcel::readFloat(float *pArg) const
+{
+    if ((mDataPos+sizeof(float)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(float);
+        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
+        *pArg = *reinterpret_cast<const float*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+float Parcel::readFloat() const
+{
+    if ((mDataPos+sizeof(float)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(float);
+        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const float*>(data);
+    }
+    return 0;
+}
+
+status_t Parcel::readDouble(double *pArg) const
+{
+    if ((mDataPos+sizeof(double)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(double);
+        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
+        *pArg = *reinterpret_cast<const double*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+double Parcel::readDouble() const
+{
+    if ((mDataPos+sizeof(double)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(double);
+        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const double*>(data);
+    }
+    return 0;
+}
+
+
+const char* Parcel::readCString() const
+{
+    const size_t avail = mDataSize-mDataPos;
+    if (avail > 0) {
+        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
+        // is the string's trailing NUL within the parcel's valid bounds?
+        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
+        if (eos) {
+            const size_t len = eos - str;
+            mDataPos += PAD_SIZE(len+1);
+            LOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
+            return str;
+        }
+    }
+    return NULL;
+}
+
+String8 Parcel::readString8() const
+{
+    int32_t size = readInt32();
+    // watch for potential int overflow adding 1 for trailing NUL
+    if (size > 0 && size < INT32_MAX) {
+        const char* str = (const char*)readInplace(size+1);
+        if (str) return String8(str, size);
+    }
+    return String8();
+}
+
+String16 Parcel::readString16() const
+{
+    size_t len;
+    const char16_t* str = readString16Inplace(&len);
+    if (str) return String16(str, len);
+    LOGE("Reading a NULL string not supported here.");
+    return String16();
+}
+
+const char16_t* Parcel::readString16Inplace(size_t* outLen) const
+{
+    int32_t size = readInt32();
+    // watch for potential int overflow from size+1
+    if (size >= 0 && size < INT32_MAX) {
+        *outLen = size;
+        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
+        if (str != NULL) {
+            return str;
+        }
+    }
+    *outLen = 0;
+    return NULL;
+}
+
+sp<IBinder> Parcel::readStrongBinder() const
+{
+    sp<IBinder> val;
+    unflatten_binder(ProcessState::self(), *this, &val);
+    return val;
+}
+
+wp<IBinder> Parcel::readWeakBinder() const
+{
+    wp<IBinder> val;
+    unflatten_binder(ProcessState::self(), *this, &val);
+    return val;
+}
+
+int Parcel::readFileDescriptor() const
+{
+    const flat_binder_object* flat = readObject(true);
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_FD:
+                //LOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
+                return flat->handle;
+        }        
+    }
+    return BAD_TYPE;
+}
+
+const flat_binder_object* Parcel::readObject(bool nullMetaData) const
+{
+    const size_t DPOS = mDataPos;
+    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
+        const flat_binder_object* obj
+                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
+        mDataPos = DPOS + sizeof(flat_binder_object);
+        if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
+            // When transfering a NULL object, we don't write it into
+            // the object list, so we don't want to check for it when
+            // reading.
+            LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+            return obj;
+        }
+        
+        // Ensure that this object is valid...
+        size_t* const OBJS = mObjects;
+        const size_t N = mObjectsSize;
+        size_t opos = mNextObjectHint;
+        
+        if (N > 0) {
+            LOGV("Parcel %p looking for obj at %d, hint=%d\n",
+                 this, DPOS, opos);
+            
+            // Start at the current hint position, looking for an object at
+            // the current data position.
+            if (opos < N) {
+                while (opos < (N-1) && OBJS[opos] < DPOS) {
+                    opos++;
+                }
+            } else {
+                opos = N-1;
+            }
+            if (OBJS[opos] == DPOS) {
+                // Found it!
+                LOGV("Parcel found obj %d at index %d with forward search",
+                     this, DPOS, opos);
+                mNextObjectHint = opos+1;
+                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                return obj;
+            }
+        
+            // Look backwards for it...
+            while (opos > 0 && OBJS[opos] > DPOS) {
+                opos--;
+            }
+            if (OBJS[opos] == DPOS) {
+                // Found it!
+                LOGV("Parcel found obj %d at index %d with backward search",
+                     this, DPOS, opos);
+                mNextObjectHint = opos+1;
+                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                return obj;
+            }
+        }
+        LOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",
+             this, DPOS);
+    }
+    return NULL;
+}
+
+void Parcel::closeFileDescriptors()
+{
+    size_t i = mObjectsSize;
+    if (i > 0) {
+        //LOGI("Closing file descriptors for %d objects...", mObjectsSize);
+    }
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
+        if (flat->type == BINDER_TYPE_FD) {
+            //LOGI("Closing fd: %ld\n", flat->handle);
+            close(flat->handle);
+        }
+    }
+}
+
+const uint8_t* Parcel::ipcData() const
+{
+    return mData;
+}
+
+size_t Parcel::ipcDataSize() const
+{
+    return (mDataSize > mDataPos ? mDataSize : mDataPos);
+}
+
+const size_t* Parcel::ipcObjects() const
+{
+    return mObjects;
+}
+
+size_t Parcel::ipcObjectsCount() const
+{
+    return mObjectsSize;
+}
+
+void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
+    const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
+{
+    freeDataNoInit();
+    mError = NO_ERROR;
+    mData = const_cast<uint8_t*>(data);
+    mDataSize = mDataCapacity = dataSize;
+    //LOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
+    mDataPos = 0;
+    LOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
+    mObjects = const_cast<size_t*>(objects);
+    mObjectsSize = mObjectsCapacity = objectsCount;
+    mNextObjectHint = 0;
+    mOwner = relFunc;
+    mOwnerCookie = relCookie;
+    scanForFds();
+}
+
+void Parcel::print(TextOutput& to, uint32_t flags) const
+{
+    to << "Parcel(";
+    
+    if (errorCheck() != NO_ERROR) {
+        const status_t err = errorCheck();
+        to << "Error: " << (void*)err << " \"" << strerror(-err) << "\"";
+    } else if (dataSize() > 0) {
+        const uint8_t* DATA = data();
+        to << indent << HexDump(DATA, dataSize()) << dedent;
+        const size_t* OBJS = objects();
+        const size_t N = objectsCount();
+        for (size_t i=0; i<N; i++) {
+            const flat_binder_object* flat
+                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
+            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
+                << TypeCode(flat->type & 0x7f7f7f00)
+                << " = " << flat->binder;
+        }
+    } else {
+        to << "NULL";
+    }
+    
+    to << ")";
+}
+
+void Parcel::releaseObjects()
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    size_t i = mObjectsSize;
+    uint8_t* const data = mData;
+    size_t* const objects = mObjects;
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
+        release_object(proc, *flat, this);
+    }
+}
+
+void Parcel::acquireObjects()
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    size_t i = mObjectsSize;
+    uint8_t* const data = mData;
+    size_t* const objects = mObjects;
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
+        acquire_object(proc, *flat, this);
+    }
+}
+
+void Parcel::freeData()
+{
+    freeDataNoInit();
+    initState();
+}
+
+void Parcel::freeDataNoInit()
+{
+    if (mOwner) {
+        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+    } else {
+        releaseObjects();
+        if (mData) free(mData);
+        if (mObjects) free(mObjects);
+    }
+}
+
+status_t Parcel::growData(size_t len)
+{
+    size_t newSize = ((mDataSize+len)*3)/2;
+    return (newSize <= mDataSize)
+            ? (status_t) NO_MEMORY
+            : continueWrite(newSize);
+}
+
+status_t Parcel::restartWrite(size_t desired)
+{
+    if (mOwner) {
+        freeData();
+        return continueWrite(desired);
+    }
+    
+    uint8_t* data = (uint8_t*)realloc(mData, desired);
+    if (!data && desired > mDataCapacity) {
+        mError = NO_MEMORY;
+        return NO_MEMORY;
+    }
+    
+    releaseObjects();
+    
+    if (data) {
+        mData = data;
+        mDataCapacity = desired;
+    }
+    
+    mDataSize = mDataPos = 0;
+    LOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
+    LOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
+        
+    free(mObjects);
+    mObjects = NULL;
+    mObjectsSize = mObjectsCapacity = 0;
+    mNextObjectHint = 0;
+    mHasFds = false;
+    mFdsKnown = true;
+    
+    return NO_ERROR;
+}
+
+status_t Parcel::continueWrite(size_t desired)
+{
+    // If shrinking, first adjust for any objects that appear
+    // after the new data size.
+    size_t objectsSize = mObjectsSize;
+    if (desired < mDataSize) {
+        if (desired == 0) {
+            objectsSize = 0;
+        } else {
+            while (objectsSize > 0) {
+                if (mObjects[objectsSize-1] < desired)
+                    break;
+                objectsSize--;
+            }
+        }
+    }
+    
+    if (mOwner) {
+        // If the size is going to zero, just release the owner's data.
+        if (desired == 0) {
+            freeData();
+            return NO_ERROR;
+        }
+
+        // If there is a different owner, we need to take
+        // posession.
+        uint8_t* data = (uint8_t*)malloc(desired);
+        if (!data) {
+            mError = NO_MEMORY;
+            return NO_MEMORY;
+        }
+        size_t* objects = NULL;
+        
+        if (objectsSize) {
+            objects = (size_t*)malloc(objectsSize*sizeof(size_t));
+            if (!objects) {
+                mError = NO_MEMORY;
+                return NO_MEMORY;
+            }
+
+            // Little hack to only acquire references on objects
+            // we will be keeping.
+            size_t oldObjectsSize = mObjectsSize;
+            mObjectsSize = objectsSize;
+            acquireObjects();
+            mObjectsSize = oldObjectsSize;
+        }
+        
+        if (mData) {
+            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
+        }
+        if (objects && mObjects) {
+            memcpy(objects, mObjects, objectsSize*sizeof(size_t));
+        }
+        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+        mOwner = NULL;
+
+        mData = data;
+        mObjects = objects;
+        mDataSize = (mDataSize < desired) ? mDataSize : desired;
+        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+        mDataCapacity = desired;
+        mObjectsSize = mObjectsCapacity = objectsSize;
+        mNextObjectHint = 0;
+
+    } else if (mData) {
+        if (objectsSize < mObjectsSize) {
+            // Need to release refs on any objects we are dropping.
+            const sp<ProcessState> proc(ProcessState::self());
+            for (size_t i=objectsSize; i<mObjectsSize; i++) {
+                const flat_binder_object* flat
+                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
+                if (flat->type == BINDER_TYPE_FD) {
+                    // will need to rescan because we may have lopped off the only FDs
+                    mFdsKnown = false;
+                }
+                release_object(proc, *flat, this);
+            }
+            size_t* objects =
+                (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));
+            if (objects) {
+                mObjects = objects;
+            }
+            mObjectsSize = objectsSize;
+            mNextObjectHint = 0;
+        }
+
+        // We own the data, so we can just do a realloc().
+        if (desired > mDataCapacity) {
+            uint8_t* data = (uint8_t*)realloc(mData, desired);
+            if (data) {
+                mData = data;
+                mDataCapacity = desired;
+            } else if (desired > mDataCapacity) {
+                mError = NO_MEMORY;
+                return NO_MEMORY;
+            }
+        } else {
+            mDataSize = desired;
+            LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+            if (mDataPos > desired) {
+                mDataPos = desired;
+                LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+            }
+        }
+        
+    } else {
+        // This is the first data.  Easy!
+        uint8_t* data = (uint8_t*)malloc(desired);
+        if (!data) {
+            mError = NO_MEMORY;
+            return NO_MEMORY;
+        }
+        
+        if(!(mDataCapacity == 0 && mObjects == NULL
+             && mObjectsCapacity == 0)) {
+            LOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
+        }
+        
+        mData = data;
+        mDataSize = mDataPos = 0;
+        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+        LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+        mDataCapacity = desired;
+    }
+
+    return NO_ERROR;
+}
+
+void Parcel::initState()
+{
+    mError = NO_ERROR;
+    mData = 0;
+    mDataSize = 0;
+    mDataCapacity = 0;
+    mDataPos = 0;
+    LOGV("initState Setting data size of %p to %d\n", this, mDataSize);
+    LOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
+    mObjects = NULL;
+    mObjectsSize = 0;
+    mObjectsCapacity = 0;
+    mNextObjectHint = 0;
+    mHasFds = false;
+    mFdsKnown = true;
+    mOwner = NULL;
+}
+
+void Parcel::scanForFds() const
+{
+    bool hasFds = false;
+    for (size_t i=0; i<mObjectsSize; i++) {
+        const flat_binder_object* flat
+            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
+        if (flat->type == BINDER_TYPE_FD) {
+            hasFds = true;
+            break;
+        }
+    }
+    mHasFds = hasFds;
+    mFdsKnown = true;
+}
+
+}; // namespace android
diff --git a/libs/utils/Pipe.cpp b/libs/utils/Pipe.cpp
new file mode 100644
index 0000000..613906b
--- /dev/null
+++ b/libs/utils/Pipe.cpp
@@ -0,0 +1,465 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Unidirectional pipe.
+//
+
+#include <utils/Pipe.h>
+#include <utils/Log.h>
+
+#if defined(HAVE_WIN32_IPC)
+# include <windows.h>
+#else
+# include <fcntl.h>
+# include <unistd.h>
+# include <errno.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+using namespace android;
+
+const unsigned long kInvalidHandle = (unsigned long) -1;
+
+
+/*
+ * Constructor.  Do little.
+ */
+Pipe::Pipe(void)
+    : mReadNonBlocking(false), mReadHandle(kInvalidHandle),
+      mWriteHandle(kInvalidHandle)
+{
+}
+
+/*
+ * Destructor.  Use the system-appropriate close call.
+ */
+Pipe::~Pipe(void)
+{
+#if defined(HAVE_WIN32_IPC)
+    if (mReadHandle != kInvalidHandle) {
+        if (!CloseHandle((HANDLE)mReadHandle))
+            LOG(LOG_WARN, "pipe", "failed closing read handle (%ld)\n",
+                mReadHandle);
+    }
+    if (mWriteHandle != kInvalidHandle) {
+        FlushFileBuffers((HANDLE)mWriteHandle);
+        if (!CloseHandle((HANDLE)mWriteHandle))
+            LOG(LOG_WARN, "pipe", "failed closing write handle (%ld)\n",
+                mWriteHandle);
+    }
+#else
+    if (mReadHandle != kInvalidHandle) {
+        if (close((int) mReadHandle) != 0)
+            LOG(LOG_WARN, "pipe", "failed closing read fd (%d)\n",
+                (int) mReadHandle);
+    }
+    if (mWriteHandle != kInvalidHandle) {
+        if (close((int) mWriteHandle) != 0)
+            LOG(LOG_WARN, "pipe", "failed closing write fd (%d)\n",
+                (int) mWriteHandle);
+    }
+#endif
+}
+
+/*
+ * Create the pipe.
+ *
+ * Use the POSIX stuff for everything but Windows.
+ */
+bool Pipe::create(void)
+{
+    assert(mReadHandle == kInvalidHandle);
+    assert(mWriteHandle == kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    /* we use this across processes, so they need to be inheritable */
+    HANDLE handles[2];
+    SECURITY_ATTRIBUTES saAttr;
+
+    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+    saAttr.bInheritHandle = TRUE;
+    saAttr.lpSecurityDescriptor = NULL;
+
+    if (!CreatePipe(&handles[0], &handles[1], &saAttr, 0)) {
+        LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
+        return false;
+    }
+    mReadHandle = (unsigned long) handles[0];
+    mWriteHandle = (unsigned long) handles[1];
+    return true;
+#else
+    int fds[2];
+
+    if (pipe(fds) != 0) {
+        LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
+        return false;
+    }
+    mReadHandle = fds[0];
+    mWriteHandle = fds[1];
+    return true;
+#endif
+}
+
+/*
+ * Create a "half pipe".  Please, no Segway riding.
+ */
+bool Pipe::createReader(unsigned long handle)
+{
+    mReadHandle = handle;
+    assert(mWriteHandle == kInvalidHandle);
+    return true;
+}
+
+/*
+ * Create a "half pipe" for writing.
+ */
+bool Pipe::createWriter(unsigned long handle)
+{
+    mWriteHandle = handle;
+    assert(mReadHandle == kInvalidHandle);
+    return true;
+}
+
+/*
+ * Return "true" if create() has been called successfully.
+ */
+bool Pipe::isCreated(void)
+{
+    // one or the other should be open
+    return (mReadHandle != kInvalidHandle || mWriteHandle != kInvalidHandle);
+}
+
+
+/*
+ * Read data from the pipe.
+ *
+ * For Linux and Darwin, just call read().  For Windows, implement
+ * non-blocking reads by calling PeekNamedPipe first.
+ */
+int Pipe::read(void* buf, int count)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    DWORD totalBytesAvail = count;
+    DWORD bytesRead;
+
+    if (mReadNonBlocking) {
+        // use PeekNamedPipe to adjust read count expectations
+        if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
+                &totalBytesAvail, NULL))
+        {
+            LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
+            return -1;
+        }
+
+        if (totalBytesAvail == 0)
+            return 0;
+    }
+
+    if (!ReadFile((HANDLE) mReadHandle, buf, totalBytesAvail, &bytesRead,
+            NULL))
+    {
+        DWORD err = GetLastError();
+        if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
+            return 0;
+        LOG(LOG_ERROR, "pipe", "ReadFile failed (err=%ld)\n", err);
+        return -1;
+    }
+
+    return (int) bytesRead;
+#else
+    int cc;
+    cc = ::read(mReadHandle, buf, count);
+    if (cc < 0 && errno == EAGAIN)
+        return 0;
+    return cc;
+#endif
+}
+
+/*
+ * Write data to the pipe.
+ *
+ * POSIX systems are trivial, Windows uses a different call and doesn't
+ * handle non-blocking writes.
+ *
+ * If we add non-blocking support here, we probably want to make it an
+ * all-or-nothing write.
+ *
+ * DO NOT use LOG() here, we could be writing a log message.
+ */
+int Pipe::write(const void* buf, int count)
+{
+    assert(mWriteHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    DWORD bytesWritten;
+
+    if (mWriteNonBlocking) {
+        // BUG: can't use PeekNamedPipe() to get the amount of space
+        // left.  Looks like we need to use "overlapped I/O" functions.
+        // I just don't care that much.
+    }
+
+    if (!WriteFile((HANDLE) mWriteHandle, buf, count, &bytesWritten, NULL)) {
+        // can't LOG, use stderr
+        fprintf(stderr, "WriteFile failed (err=%ld)\n", GetLastError());
+        return -1;
+    }
+
+    return (int) bytesWritten;
+#else
+    int cc;
+    cc = ::write(mWriteHandle, buf, count);
+    if (cc < 0 && errno == EAGAIN)
+        return 0;
+    return cc;
+#endif
+}
+
+/*
+ * Figure out if there is data available on the read fd.
+ *
+ * We return "true" on error because we want the caller to try to read
+ * from the pipe.  They'll notice the read failure and do something
+ * appropriate.
+ */
+bool Pipe::readReady(void)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    DWORD totalBytesAvail;
+
+    if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
+            &totalBytesAvail, NULL))
+    {
+        LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
+        return true;
+    }
+
+    return (totalBytesAvail != 0);
+#else
+    errno = 0;
+    fd_set readfds;
+    struct timeval tv = { 0, 0 };
+    int cc;
+
+    FD_ZERO(&readfds);
+    FD_SET(mReadHandle, &readfds);
+
+    cc = select(mReadHandle+1, &readfds, NULL, NULL, &tv);
+    if (cc < 0) {
+        LOG(LOG_ERROR, "pipe", "select() failed\n");
+        return true;
+    } else if (cc == 0) {
+        /* timed out, nothing available */
+        return false;
+    } else if (cc == 1) {
+        /* our fd is ready */
+        return true;
+    } else {
+        LOG(LOG_ERROR, "pipe", "HUH? select() returned > 1\n");
+        return true;
+    }
+#endif
+}
+
+/*
+ * Enable or disable non-blocking mode for the read descriptor.
+ *
+ * NOTE: the calls succeed under Mac OS X, but the pipe doesn't appear to
+ * actually be in non-blocking mode.  If this matters -- i.e. you're not
+ * using a select() call -- put a call to readReady() in front of the
+ * ::read() call, with a PIPE_NONBLOCK_BROKEN #ifdef in the Makefile for
+ * Darwin.
+ */
+bool Pipe::setReadNonBlocking(bool val)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    // nothing to do
+#else
+    int flags;
+
+    if (fcntl(mReadHandle, F_GETFL, &flags) == -1) {
+        LOG(LOG_ERROR, "pipe", "couldn't get flags for pipe read fd\n");
+        return false;
+    }
+    if (val)
+        flags |= O_NONBLOCK;
+    else
+        flags &= ~(O_NONBLOCK);
+    if (fcntl(mReadHandle, F_SETFL, &flags) == -1) {
+        LOG(LOG_ERROR, "pipe", "couldn't set flags for pipe read fd\n");
+        return false;
+    }
+#endif
+
+    mReadNonBlocking = val;
+    return true;
+}
+
+/*
+ * Enable or disable non-blocking mode for the write descriptor.
+ *
+ * As with setReadNonBlocking(), this does not work on the Mac.
+ */
+bool Pipe::setWriteNonBlocking(bool val)
+{
+    assert(mWriteHandle != kInvalidHandle);
+
+#if defined(HAVE_WIN32_IPC)
+    // nothing to do
+#else
+    int flags;
+
+    if (fcntl(mWriteHandle, F_GETFL, &flags) == -1) {
+        LOG(LOG_WARN, "pipe",
+            "Warning: couldn't get flags for pipe write fd (errno=%d)\n",
+            errno);
+        return false;
+    }
+    if (val)
+        flags |= O_NONBLOCK;
+    else
+        flags &= ~(O_NONBLOCK);
+    if (fcntl(mWriteHandle, F_SETFL, &flags) == -1) {
+        LOG(LOG_WARN, "pipe",
+            "Warning: couldn't set flags for pipe write fd (errno=%d)\n",
+            errno);
+        return false;
+    }
+#endif
+
+    mWriteNonBlocking = val;
+    return true;
+}
+
+/*
+ * Specify whether a file descriptor can be inherited by a child process.
+ * Under Linux this means setting the close-on-exec flag, under Windows
+ * this is SetHandleInformation(HANDLE_FLAG_INHERIT).
+ */
+bool Pipe::disallowReadInherit(void)
+{
+    if (mReadHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (SetHandleInformation((HANDLE) mReadHandle, HANDLE_FLAG_INHERIT, 0) == 0)
+        return false;
+#else
+    if (fcntl((int) mReadHandle, F_SETFD, FD_CLOEXEC) != 0)
+        return false;
+#endif
+    return true;
+}
+bool Pipe::disallowWriteInherit(void)
+{
+    if (mWriteHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (SetHandleInformation((HANDLE) mWriteHandle, HANDLE_FLAG_INHERIT, 0) == 0)
+        return false;
+#else
+    if (fcntl((int) mWriteHandle, F_SETFD, FD_CLOEXEC) != 0)
+        return false;
+#endif
+    return true;
+}
+
+/*
+ * Close read descriptor.
+ */
+bool Pipe::closeRead(void)
+{
+    if (mReadHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (mReadHandle != kInvalidHandle) {
+        if (!CloseHandle((HANDLE)mReadHandle)) {
+            LOG(LOG_WARN, "pipe", "failed closing read handle\n");
+            return false;
+        }
+    }
+#else
+    if (mReadHandle != kInvalidHandle) {
+        if (close((int) mReadHandle) != 0) {
+            LOG(LOG_WARN, "pipe", "failed closing read fd\n");
+            return false;
+        }
+    }
+#endif
+    mReadHandle = kInvalidHandle;
+    return true;
+}
+
+/*
+ * Close write descriptor.
+ */
+bool Pipe::closeWrite(void)
+{
+    if (mWriteHandle == kInvalidHandle)
+        return false;
+
+#if defined(HAVE_WIN32_IPC)
+    if (mWriteHandle != kInvalidHandle) {
+        if (!CloseHandle((HANDLE)mWriteHandle)) {
+            LOG(LOG_WARN, "pipe", "failed closing write handle\n");
+            return false;
+        }
+    }
+#else
+    if (mWriteHandle != kInvalidHandle) {
+        if (close((int) mWriteHandle) != 0) {
+            LOG(LOG_WARN, "pipe", "failed closing write fd\n");
+            return false;
+        }
+    }
+#endif
+    mWriteHandle = kInvalidHandle;
+    return true;
+}
+
+/*
+ * Get the read handle.
+ */
+unsigned long Pipe::getReadHandle(void)
+{
+    assert(mReadHandle != kInvalidHandle);
+
+    return mReadHandle;
+}
+
+/*
+ * Get the write handle.
+ */
+unsigned long Pipe::getWriteHandle(void)
+{
+    assert(mWriteHandle != kInvalidHandle);
+
+    return mWriteHandle;
+}
+
diff --git a/libs/utils/ProcessState.cpp b/libs/utils/ProcessState.cpp
new file mode 100644
index 0000000..4567df6
--- /dev/null
+++ b/libs/utils/ProcessState.cpp
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "ProcessState"
+
+#include <cutils/process_name.h>
+
+#include <utils/ProcessState.h>
+
+#include <utils/Atomic.h>
+#include <utils/BpBinder.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/IServiceManager.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
+
+#include <private/utils/binder_module.h>
+#include <private/utils/Static.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#define BINDER_VM_SIZE (1*1024*1024)
+
+static bool gSingleProcess = false;
+
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+ 
+// Global variables
+int                 mArgC;
+const char* const*  mArgV;
+int                 mArgLen;
+
+class PoolThread : public Thread
+{
+public:
+    PoolThread(bool isMain)
+        : mIsMain(isMain)
+    {
+    }
+    
+protected:
+    virtual bool threadLoop()
+    {
+        IPCThreadState::self()->joinThreadPool(mIsMain);
+        return false;
+    }
+    
+    const bool mIsMain;
+};
+
+sp<ProcessState> ProcessState::self()
+{
+    if (gProcess != NULL) return gProcess;
+    
+    AutoMutex _l(gProcessMutex);
+    if (gProcess == NULL) gProcess = new ProcessState;
+    return gProcess;
+}
+
+void ProcessState::setSingleProcess(bool singleProcess)
+{
+    gSingleProcess = singleProcess;
+}
+
+
+void ProcessState::setContextObject(const sp<IBinder>& object)
+{
+    setContextObject(object, String16("default"));
+}
+
+sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
+{
+    if (supportsProcesses()) {
+        return getStrongProxyForHandle(0);
+    } else {
+        return getContextObject(String16("default"), caller);
+    }
+}
+
+void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
+{
+    AutoMutex _l(mLock);
+    mContexts.add(name, object);
+}
+
+sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
+{
+    mLock.lock();
+    sp<IBinder> object(
+        mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
+    mLock.unlock();
+    
+    //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
+    
+    if (object != NULL) return object;
+
+    // Don't attempt to retrieve contexts if we manage them
+    if (mManagesContexts) {
+        LOGE("getContextObject(%s) failed, but we manage the contexts!\n",
+            String8(name).string());
+        return NULL;
+    }
+    
+    IPCThreadState* ipc = IPCThreadState::self();
+    {
+        Parcel data, reply;
+        // no interface token on this magic transaction
+        data.writeString16(name);
+        data.writeStrongBinder(caller);
+        status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
+        if (result == NO_ERROR) {
+            object = reply.readStrongBinder();
+        }
+    }
+    
+    ipc->flushCommands();
+    
+    if (object != NULL) setContextObject(object, name);
+    return object;
+}
+
+bool ProcessState::supportsProcesses() const
+{
+    return mDriverFD >= 0;
+}
+
+void ProcessState::startThreadPool()
+{
+    AutoMutex _l(mLock);
+    if (!mThreadPoolStarted) {
+        mThreadPoolStarted = true;
+        spawnPooledThread(true);
+    }
+}
+
+bool ProcessState::isContextManager(void) const
+{
+    return mManagesContexts;
+}
+
+bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
+{
+    if (!mManagesContexts) {
+        AutoMutex _l(mLock);
+        mBinderContextCheckFunc = checkFunc;
+        mBinderContextUserData = userData;
+        if (mDriverFD >= 0) {
+            int dummy = 0;
+#if defined(HAVE_ANDROID_OS)
+            status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
+#else
+            status_t result = INVALID_OPERATION;
+#endif
+            if (result == 0) {
+                mManagesContexts = true;
+            } else if (result == -1) {
+                mBinderContextCheckFunc = NULL;
+                mBinderContextUserData = NULL;
+                LOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
+            }
+        } else {
+            // If there is no driver, our only world is the local
+            // process so we can always become the context manager there.
+            mManagesContexts = true;
+        }
+    }
+    return mManagesContexts;
+}
+
+ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
+{
+    const size_t N=mHandleToObject.size();
+    if (N <= (size_t)handle) {
+        handle_entry e;
+        e.binder = NULL;
+        e.refs = NULL;
+        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
+        if (err < NO_ERROR) return NULL;
+    }
+    return &mHandleToObject.editItemAt(handle);
+}
+
+sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
+{
+    sp<IBinder> result;
+
+    AutoMutex _l(mLock);
+
+    handle_entry* e = lookupHandleLocked(handle);
+
+    if (e != NULL) {
+        // We need to create a new BpBinder if there isn't currently one, OR we
+        // are unable to acquire a weak reference on this current one.  See comment
+        // in getWeakProxyForHandle() for more info about this.
+        IBinder* b = e->binder;
+        if (b == NULL || !e->refs->attemptIncWeak(this)) {
+            b = new BpBinder(handle); 
+            e->binder = b;
+            if (b) e->refs = b->getWeakRefs();
+            result = b;
+        } else {
+            // This little bit of nastyness is to allow us to add a primary
+            // reference to the remote proxy when this team doesn't have one
+            // but another team is sending the handle to us.
+            result.force_set(b);
+            e->refs->decWeak(this);
+        }
+    }
+
+    return result;
+}
+
+wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
+{
+    wp<IBinder> result;
+
+    AutoMutex _l(mLock);
+
+    handle_entry* e = lookupHandleLocked(handle);
+
+    if (e != NULL) {        
+        // We need to create a new BpBinder if there isn't currently one, OR we
+        // are unable to acquire a weak reference on this current one.  The
+        // attemptIncWeak() is safe because we know the BpBinder destructor will always
+        // call expungeHandle(), which acquires the same lock we are holding now.
+        // We need to do this because there is a race condition between someone
+        // releasing a reference on this BpBinder, and a new reference on its handle
+        // arriving from the driver.
+        IBinder* b = e->binder;
+        if (b == NULL || !e->refs->attemptIncWeak(this)) {
+            b = new BpBinder(handle);
+            result = b;
+            e->binder = b;
+            if (b) e->refs = b->getWeakRefs();
+        } else {
+            result = b;
+            e->refs->decWeak(this);
+        }
+    }
+
+    return result;
+}
+
+void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
+{
+    AutoMutex _l(mLock);
+    
+    handle_entry* e = lookupHandleLocked(handle);
+
+    // This handle may have already been replaced with a new BpBinder
+    // (if someone failed the AttemptIncWeak() above); we don't want
+    // to overwrite it.
+    if (e && e->binder == binder) e->binder = NULL;
+}
+
+void ProcessState::setArgs(int argc, const char* const argv[])
+{
+    mArgC = argc;
+    mArgV = (const char **)argv;
+
+    mArgLen = 0;
+    for (int i=0; i<argc; i++) {
+        mArgLen += strlen(argv[i]) + 1;
+    }
+    mArgLen--;
+}
+
+int ProcessState::getArgC() const
+{
+    return mArgC;
+}
+
+const char* const* ProcessState::getArgV() const
+{
+    return mArgV;
+}
+
+void ProcessState::setArgV0(const char* txt)
+{
+    if (mArgV != NULL) {
+        strncpy((char*)mArgV[0], txt, mArgLen);
+        set_process_name(txt);
+    }
+}
+
+void ProcessState::spawnPooledThread(bool isMain)
+{
+    if (mThreadPoolStarted) {
+        int32_t s = android_atomic_add(1, &mThreadPoolSeq);
+        char buf[32];
+        sprintf(buf, "Binder Thread #%d", s);
+        LOGV("Spawning new pooled thread, name=%s\n", buf);
+        sp<Thread> t = new PoolThread(isMain);
+        t->run(buf);
+    }
+}
+
+static int open_driver()
+{
+    if (gSingleProcess) {
+        return -1;
+    }
+
+    int fd = open("/dev/binder", O_RDWR);
+    if (fd >= 0) {
+        fcntl(fd, F_SETFD, FD_CLOEXEC);
+        int vers;
+#if defined(HAVE_ANDROID_OS)
+        status_t result = ioctl(fd, BINDER_VERSION, &vers);
+#else
+        status_t result = -1;
+        errno = EPERM;
+#endif
+        if (result == -1) {
+            LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
+            close(fd);
+            fd = -1;
+        }
+        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
+            LOGE("Binder driver protocol does not match user space protocol!");
+            close(fd);
+            fd = -1;
+        }
+#if defined(HAVE_ANDROID_OS)
+        size_t maxThreads = 15;
+        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
+        if (result == -1) {
+            LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
+        }
+#endif
+        
+    } else {
+        LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
+    }
+    return fd;
+}
+
+ProcessState::ProcessState()
+    : mDriverFD(open_driver())
+    , mVMStart(MAP_FAILED)
+    , mManagesContexts(false)
+    , mBinderContextCheckFunc(NULL)
+    , mBinderContextUserData(NULL)
+    , mThreadPoolStarted(false)
+    , mThreadPoolSeq(1)
+{
+    if (mDriverFD >= 0) {
+        // XXX Ideally, there should be a specific define for whether we
+        // have mmap (or whether we could possibly have the kernel module
+        // availabla).
+#if !defined(HAVE_WIN32_IPC)
+        // mmap the binder, providing a chunk of virtual address space to receive transactions.
+        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
+        if (mVMStart == MAP_FAILED) {
+            // *sigh*
+            LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
+            close(mDriverFD);
+            mDriverFD = -1;
+        }
+#else
+        mDriverFD = -1;
+#endif
+    }
+    if (mDriverFD < 0) {
+        // Need to run without the driver, starting our own thread pool.
+    }
+}
+
+ProcessState::~ProcessState()
+{
+}
+        
+}; // namespace android
diff --git a/libs/utils/README b/libs/utils/README
new file mode 100644
index 0000000..36a706d
--- /dev/null
+++ b/libs/utils/README
@@ -0,0 +1,14 @@
+Android Utility Function Library
+
+If you need a feature that is native to Linux but not present on other
+platforms, construct a platform-dependent implementation that shares
+the Linux interface.  That way the actual device runs as "light" as
+possible.
+
+If that isn't feasible, create a system-independent interface and hide
+the details.
+
+The ultimate goal is *not* to create a super-duper platform abstraction
+layer.  The goal is to provide an optimized solution for Linux with
+reasonable implementations for other platforms.
+
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
new file mode 100644
index 0000000..0bd1af4
--- /dev/null
+++ b/libs/utils/RefBase.cpp
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "RefBase"
+
+#include <utils/RefBase.h>
+
+#include <utils/Atomic.h>
+#include <utils/CallStack.h>
+#include <utils/KeyedVector.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <typeinfo>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+// compile with refcounting debugging enabled
+#define DEBUG_REFS                      0
+#define DEBUG_REFS_ENABLED_BY_DEFAULT   1
+#define DEBUG_REFS_CALLSTACK_ENABLED    1
+
+// log all reference counting operations
+#define PRINT_REFS                      0
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+#define INITIAL_STRONG_VALUE (1<<28)
+
+// ---------------------------------------------------------------------------
+
+class RefBase::weakref_impl : public RefBase::weakref_type
+{
+public:
+    volatile int32_t    mStrong;
+    volatile int32_t    mWeak;
+    RefBase* const      mBase;
+    volatile int32_t    mFlags;
+
+
+#if !DEBUG_REFS
+
+    weakref_impl(RefBase* base)
+        : mStrong(INITIAL_STRONG_VALUE)
+        , mWeak(0)
+        , mBase(base)
+        , mFlags(0)
+    {
+    }
+
+    void addStrongRef(const void* /*id*/) { }
+    void removeStrongRef(const void* /*id*/) { }
+    void addWeakRef(const void* /*id*/) { }
+    void removeWeakRef(const void* /*id*/) { }
+    void printRefs() const { }
+    void trackMe(bool, bool) { }
+
+#else
+
+    weakref_impl(RefBase* base)
+        : mStrong(INITIAL_STRONG_VALUE)
+        , mWeak(0)
+        , mBase(base)
+        , mFlags(0)
+        , mStrongRefs(NULL)
+        , mWeakRefs(NULL)
+        , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
+        , mRetain(false)
+    {
+        //LOGI("NEW weakref_impl %p for RefBase %p", this, base);
+    }
+    
+    ~weakref_impl()
+    {
+        LOG_ALWAYS_FATAL_IF(!mRetain && mStrongRefs != NULL, "Strong references remain!");
+        LOG_ALWAYS_FATAL_IF(!mRetain && mWeakRefs != NULL, "Weak references remain!");
+    }
+
+    void addStrongRef(const void* id)
+    {
+        addRef(&mStrongRefs, id, mStrong);
+    }
+
+    void removeStrongRef(const void* id)
+    {
+        if (!mRetain)
+            removeRef(&mStrongRefs, id);
+        else
+            addRef(&mStrongRefs, id, -mStrong);
+    }
+
+    void addWeakRef(const void* id)
+    {
+        addRef(&mWeakRefs, id, mWeak);
+    }
+
+    void removeWeakRef(const void* id)
+    {
+        if (!mRetain)
+            removeRef(&mWeakRefs, id);
+        else
+            addRef(&mWeakRefs, id, -mWeak);
+    }
+
+    void trackMe(bool track, bool retain)
+    { 
+        mTrackEnabled = track;
+        mRetain = retain;
+    }
+
+    void printRefs() const
+    {
+        String8 text;
+
+        {
+            AutoMutex _l(const_cast<weakref_impl*>(this)->mMutex);
+    
+            char buf[128];
+            sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
+            text.append(buf);
+            printRefsLocked(&text, mStrongRefs);
+            sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
+            text.append(buf);
+            printRefsLocked(&text, mWeakRefs);
+        }
+
+        {
+            char name[100];
+            snprintf(name, 100, "/data/%p.stack", this);
+            int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
+            if (rc >= 0) {
+                write(rc, text.string(), text.length());
+                close(rc);
+                LOGD("STACK TRACE for %p saved in %s", this, name);
+            }
+            else LOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this,
+                      name, strerror(errno));
+        }
+    }
+
+private:
+    struct ref_entry
+    {
+        ref_entry* next;
+        const void* id;
+#if DEBUG_REFS_CALLSTACK_ENABLED
+        CallStack stack;
+#endif
+        int32_t ref;
+    };
+
+    void addRef(ref_entry** refs, const void* id, int32_t mRef)
+    {
+        if (mTrackEnabled) {
+            AutoMutex _l(mMutex);
+            ref_entry* ref = new ref_entry;
+            // Reference count at the time of the snapshot, but before the
+            // update.  Positive value means we increment, negative--we
+            // decrement the reference count.
+            ref->ref = mRef;
+            ref->id = id;
+#if DEBUG_REFS_CALLSTACK_ENABLED
+            ref->stack.update(2);
+#endif
+            
+            ref->next = *refs;
+            *refs = ref;
+        }
+    }
+
+    void removeRef(ref_entry** refs, const void* id)
+    {
+        if (mTrackEnabled) {
+            AutoMutex _l(mMutex);
+            
+            ref_entry* ref = *refs;
+            while (ref != NULL) {
+                if (ref->id == id) {
+                    *refs = ref->next;
+                    delete ref;
+                    return;
+                }
+                
+                refs = &ref->next;
+                ref = *refs;
+            }
+            
+            LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p (weakref_type %p) that doesn't exist!",
+                             id, mBase, this);
+        }
+    }
+
+    void printRefsLocked(String8* out, const ref_entry* refs) const
+    {
+        char buf[128];
+        while (refs) {
+            char inc = refs->ref >= 0 ? '+' : '-';
+            sprintf(buf, "\t%c ID %p (ref %d):\n", 
+                    inc, refs->id, refs->ref);
+            out->append(buf);
+#if DEBUG_REFS_CALLSTACK_ENABLED
+            out->append(refs->stack.toString("\t\t"));
+#else
+            out->append("\t\t(call stacks disabled)");
+#endif
+            refs = refs->next;
+        }
+    }
+
+    Mutex mMutex;
+    ref_entry* mStrongRefs;
+    ref_entry* mWeakRefs;
+
+    bool mTrackEnabled;
+    // Collect stack traces on addref and removeref, instead of deleting the stack references
+    // on removeref that match the address ones.
+    bool mRetain;
+
+#if 0
+    void addRef(KeyedVector<const void*, int32_t>* refs, const void* id)
+    {
+        AutoMutex _l(mMutex);
+        ssize_t i = refs->indexOfKey(id);
+        if (i >= 0) {
+            ++(refs->editValueAt(i));
+        } else {
+            i = refs->add(id, 1);
+        }
+    }
+
+    void removeRef(KeyedVector<const void*, int32_t>* refs, const void* id)
+    {
+        AutoMutex _l(mMutex);
+        ssize_t i = refs->indexOfKey(id);
+        LOG_ALWAYS_FATAL_IF(i < 0, "RefBase: removing id %p that doesn't exist!", id);
+        if (i >= 0) {
+            int32_t val = --(refs->editValueAt(i));
+            if (val == 0) {
+                refs->removeItemsAt(i);
+            }
+        }
+    }
+
+    void printRefs(const KeyedVector<const void*, int32_t>& refs)
+    {
+        const size_t N=refs.size();
+        for (size_t i=0; i<N; i++) {
+            printf("\tID %p: %d remain\n", refs.keyAt(i), refs.valueAt(i));
+        }
+    }
+
+    mutable Mutex mMutex;
+    KeyedVector<const void*, int32_t> mStrongRefs;
+    KeyedVector<const void*, int32_t> mWeakRefs;
+#endif
+
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+void RefBase::incStrong(const void* id) const
+{
+    weakref_impl* const refs = mRefs;
+    refs->addWeakRef(id);
+    refs->incWeak(id);
+    
+    refs->addStrongRef(id);
+    const int32_t c = android_atomic_inc(&refs->mStrong);
+    LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
+#if PRINT_REFS
+    LOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
+#endif
+    if (c != INITIAL_STRONG_VALUE)  {
+        return;
+    }
+
+    android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
+    const_cast<RefBase*>(this)->onFirstRef();
+}
+
+void RefBase::decStrong(const void* id) const
+{
+    weakref_impl* const refs = mRefs;
+    refs->removeStrongRef(id);
+    const int32_t c = android_atomic_dec(&refs->mStrong);
+#if PRINT_REFS
+    LOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
+#endif
+    LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
+    if (c == 1) {
+        const_cast<RefBase*>(this)->onLastStrongRef(id);
+        if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
+            delete this;
+        }
+    }
+    refs->removeWeakRef(id);
+    refs->decWeak(id);
+}
+
+void RefBase::forceIncStrong(const void* id) const
+{
+    weakref_impl* const refs = mRefs;
+    refs->addWeakRef(id);
+    refs->incWeak(id);
+    
+    refs->addStrongRef(id);
+    const int32_t c = android_atomic_inc(&refs->mStrong);
+    LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
+               refs);
+#if PRINT_REFS
+    LOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c);
+#endif
+
+    switch (c) {
+    case INITIAL_STRONG_VALUE:
+        android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
+        // fall through...
+    case 0:
+        const_cast<RefBase*>(this)->onFirstRef();
+    }
+}
+
+int32_t RefBase::getStrongCount() const
+{
+    return mRefs->mStrong;
+}
+
+
+
+RefBase* RefBase::weakref_type::refBase() const
+{
+    return static_cast<const weakref_impl*>(this)->mBase;
+}
+
+void RefBase::weakref_type::incWeak(const void* id)
+{
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    impl->addWeakRef(id);
+    const int32_t c = android_atomic_inc(&impl->mWeak);
+    LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
+}
+
+void RefBase::weakref_type::decWeak(const void* id)
+{
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    impl->removeWeakRef(id);
+    const int32_t c = android_atomic_dec(&impl->mWeak);
+    LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
+    if (c != 1) return;
+    
+    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
+        if (impl->mStrong == INITIAL_STRONG_VALUE)
+            delete impl->mBase;
+        else {
+//            LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
+            delete impl;
+        }
+    } else {
+        impl->mBase->onLastWeakRef(id);
+        if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
+            delete impl->mBase;
+        }
+    }
+}
+
+bool RefBase::weakref_type::attemptIncStrong(const void* id)
+{
+    incWeak(id);
+    
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    
+    int32_t curCount = impl->mStrong;
+    LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
+               this);
+    while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
+        if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
+            break;
+        }
+        curCount = impl->mStrong;
+    }
+    
+    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
+        bool allow;
+        if (curCount == INITIAL_STRONG_VALUE) {
+            // Attempting to acquire first strong reference...  this is allowed
+            // if the object does NOT have a longer lifetime (meaning the
+            // implementation doesn't need to see this), or if the implementation
+            // allows it to happen.
+            allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
+                  || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
+        } else {
+            // Attempting to revive the object...  this is allowed
+            // if the object DOES have a longer lifetime (so we can safely
+            // call the object with only a weak ref) and the implementation
+            // allows it to happen.
+            allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK
+                  && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
+        }
+        if (!allow) {
+            decWeak(id);
+            return false;
+        }
+        curCount = android_atomic_inc(&impl->mStrong);
+
+        // If the strong reference count has already been incremented by
+        // someone else, the implementor of onIncStrongAttempted() is holding
+        // an unneeded reference.  So call onLastStrongRef() here to remove it.
+        // (No, this is not pretty.)  Note that we MUST NOT do this if we
+        // are in fact acquiring the first reference.
+        if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
+            impl->mBase->onLastStrongRef(id);
+        }
+    }
+    
+    impl->addWeakRef(id);
+    impl->addStrongRef(id);
+
+#if PRINT_REFS
+    LOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
+#endif
+
+    if (curCount == INITIAL_STRONG_VALUE) {
+        android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
+        impl->mBase->onFirstRef();
+    }
+    
+    return true;
+}
+
+bool RefBase::weakref_type::attemptIncWeak(const void* id)
+{
+    weakref_impl* const impl = static_cast<weakref_impl*>(this);
+    
+    int32_t curCount = impl->mWeak;
+    LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
+               this);
+    while (curCount > 0) {
+        if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
+            break;
+        }
+        curCount = impl->mWeak;
+    }
+
+    if (curCount > 0) {
+        impl->addWeakRef(id);
+    }
+
+    return curCount > 0;
+}
+
+int32_t RefBase::weakref_type::getWeakCount() const
+{
+    return static_cast<const weakref_impl*>(this)->mWeak;
+}
+
+void RefBase::weakref_type::printRefs() const
+{
+    static_cast<const weakref_impl*>(this)->printRefs();
+}
+
+void RefBase::weakref_type::trackMe(bool enable, bool retain)
+{
+    static_cast<const weakref_impl*>(this)->trackMe(enable, retain);
+}
+
+RefBase::weakref_type* RefBase::createWeak(const void* id) const
+{
+    mRefs->incWeak(id);
+    return mRefs;
+}
+
+RefBase::weakref_type* RefBase::getWeakRefs() const
+{
+    return mRefs;
+}
+
+RefBase::RefBase()
+    : mRefs(new weakref_impl(this))
+{
+//    LOGV("Creating refs %p with RefBase %p\n", mRefs, this);
+}
+
+RefBase::~RefBase()
+{
+//    LOGV("Destroying RefBase %p (refs %p)\n", this, mRefs);
+    if (mRefs->mWeak == 0) {
+//        LOGV("Freeing refs %p of old RefBase %p\n", mRefs, this);
+        delete mRefs;
+    }
+}
+
+void RefBase::extendObjectLifetime(int32_t mode)
+{
+    android_atomic_or(mode, &mRefs->mFlags);
+}
+
+void RefBase::onFirstRef()
+{
+}
+
+void RefBase::onLastStrongRef(const void* /*id*/)
+{
+}
+
+bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
+{
+    return (flags&FIRST_INC_STRONG) ? true : false;
+}
+
+void RefBase::onLastWeakRef(const void* /*id*/)
+{
+}
+        
+}; // namespace android
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
new file mode 100644
index 0000000..a5fe9fb
--- /dev/null
+++ b/libs/utils/ResourceTypes.cpp
@@ -0,0 +1,3969 @@
+/*
+ * 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 "ResourceType"
+//#define LOG_NDEBUG 0
+
+#include <utils/Atomic.h>
+#include <utils/ByteOrder.h>
+#include <utils/Debug.h>
+#include <utils/ResourceTypes.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+#include <utils/TextOutput.h>
+#include <utils/Log.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#ifndef INT32_MAX
+#define INT32_MAX ((int32_t)(2147483647))
+#endif
+
+#define POOL_NOISY(x) //x
+#define XML_NOISY(x) //x
+#define TABLE_NOISY(x) //x
+#define TABLE_GETENTRY(x) //x
+#define TABLE_SUPER_NOISY(x) //x
+#define LOAD_TABLE_NOISY(x) //x
+
+namespace android {
+
+#ifdef HAVE_WINSOCK
+#undef  nhtol
+#undef  htonl
+
+#ifdef HAVE_LITTLE_ENDIAN
+#define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
+#define htonl(x)    ntohl(x)
+#define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
+#define htons(x)    ntohs(x)
+#else
+#define ntohl(x)    (x)
+#define htonl(x)    (x)
+#define ntohs(x)    (x)
+#define htons(x)    (x)
+#endif
+#endif
+
+static void printToLogFunc(void* cookie, const char* txt)
+{
+    LOGV("%s", txt);
+}
+
+// Standard C isspace() is only required to look at the low byte of its input, so
+// produces incorrect results for UTF-16 characters.  For safety's sake, assume that
+// any high-byte UTF-16 code point is not whitespace.
+inline int isspace16(char16_t c) {
+    return (c < 0x0080 && isspace(c));
+}
+
+// range checked; guaranteed to NUL-terminate within the stated number of available slots
+// NOTE: if this truncates the dst string due to running out of space, no attempt is
+// made to avoid splitting surrogate pairs.
+static void strcpy16_dtoh(uint16_t* dst, const uint16_t* src, size_t avail)
+{
+    uint16_t* last = dst + avail - 1;
+    while (*src && (dst < last)) {
+        char16_t s = dtohs(*src);
+        *dst++ = s;
+        src++;
+    }
+    *dst = 0;
+}
+
+static status_t validate_chunk(const ResChunk_header* chunk,
+                               size_t minSize,
+                               const uint8_t* dataEnd,
+                               const char* name)
+{
+    const uint16_t headerSize = dtohs(chunk->headerSize);
+    const uint32_t size = dtohl(chunk->size);
+
+    if (headerSize >= minSize) {
+        if (headerSize <= size) {
+            if (((headerSize|size)&0x3) == 0) {
+                if ((ssize_t)size <= (dataEnd-((const uint8_t*)chunk))) {
+                    return NO_ERROR;
+                }
+                LOGW("%s data size %p extends beyond resource end %p.",
+                     name, (void*)size,
+                     (void*)(dataEnd-((const uint8_t*)chunk)));
+                return BAD_TYPE;
+            }
+            LOGW("%s size 0x%x or headerSize 0x%x is not on an integer boundary.",
+                 name, (int)size, (int)headerSize);
+            return BAD_TYPE;
+        }
+        LOGW("%s size %p is smaller than header size %p.",
+             name, (void*)size, (void*)(int)headerSize);
+        return BAD_TYPE;
+    }
+    LOGW("%s header size %p is too small.",
+         name, (void*)(int)headerSize);
+    return BAD_TYPE;
+}
+
+inline void Res_value::copyFrom_dtoh(const Res_value& src)
+{
+    size = dtohs(src.size);
+    res0 = src.res0;
+    dataType = src.dataType;
+    data = dtohl(src.data);
+}
+
+void Res_png_9patch::deviceToFile()
+{
+    for (int i = 0; i < numXDivs; i++) {
+        xDivs[i] = htonl(xDivs[i]);
+    }
+    for (int i = 0; i < numYDivs; i++) {
+        yDivs[i] = htonl(yDivs[i]);
+    }
+    paddingLeft = htonl(paddingLeft);
+    paddingRight = htonl(paddingRight);
+    paddingTop = htonl(paddingTop);
+    paddingBottom = htonl(paddingBottom);
+    for (int i=0; i<numColors; i++) {
+        colors[i] = htonl(colors[i]);
+    }
+}
+
+void Res_png_9patch::fileToDevice()
+{
+    for (int i = 0; i < numXDivs; i++) {
+        xDivs[i] = ntohl(xDivs[i]);
+    }
+    for (int i = 0; i < numYDivs; i++) {
+        yDivs[i] = ntohl(yDivs[i]);
+    }
+    paddingLeft = ntohl(paddingLeft);
+    paddingRight = ntohl(paddingRight);
+    paddingTop = ntohl(paddingTop);
+    paddingBottom = ntohl(paddingBottom);
+    for (int i=0; i<numColors; i++) {
+        colors[i] = ntohl(colors[i]);
+    }
+}
+
+size_t Res_png_9patch::serializedSize()
+{
+    return sizeof(Res_png_9patch)
+            + numXDivs * sizeof(int32_t)
+            + numYDivs * sizeof(int32_t)
+            + numColors * sizeof(uint32_t);
+}
+
+void* Res_png_9patch::serialize()
+{
+    void* newData = malloc(serializedSize());
+    serialize(newData);
+    return newData;
+}
+
+void Res_png_9patch::serialize(void * outData)
+{
+    char* data = (char*) outData;
+    memmove(data, this, sizeof(Res_png_9patch));
+    data +=  sizeof(Res_png_9patch);
+    memmove(data, this->xDivs, numXDivs * sizeof(int32_t));
+    data +=  numXDivs * sizeof(int32_t);
+    memmove(data, this->yDivs, numYDivs * sizeof(int32_t));
+    data +=  numYDivs * sizeof(int32_t);
+    memmove(data, this->colors, numColors * sizeof(uint32_t));
+}
+
+Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
+{
+    deserialize(inData, (Res_png_9patch*) inData);
+    return (Res_png_9patch*) inData;
+}
+
+void Res_png_9patch::deserialize(const void* inData, Res_png_9patch* outData) {
+    Res_png_9patch* patch = (Res_png_9patch*) inData;
+    if (inData != outData) {
+        memcpy(outData, inData, patch->serializedSize());
+    }
+    outData->wasDeserialized = true;
+    char* data = (char*)outData;
+    data +=  sizeof(Res_png_9patch);
+    outData->xDivs = (int32_t*) data;
+    data +=  patch->numXDivs * sizeof(int32_t);
+    outData->yDivs = (int32_t*) data;
+    data +=  patch->numYDivs * sizeof(int32_t);
+    outData->colors = (uint32_t*) data;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+ResStringPool::ResStringPool()
+    : mError(NO_INIT), mOwnedData(NULL)
+{
+}
+
+ResStringPool::ResStringPool(const void* data, size_t size, bool copyData)
+    : mError(NO_INIT), mOwnedData(NULL)
+{
+    setTo(data, size, copyData);
+}
+
+ResStringPool::~ResStringPool()
+{
+    uninit();
+}
+
+status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
+{
+    if (!data || !size) {
+        return (mError=BAD_TYPE);
+    }
+
+    uninit();
+
+    const bool notDeviceEndian = htods(0xf0) != 0xf0;
+
+    if (copyData || notDeviceEndian) {
+        mOwnedData = malloc(size);
+        if (mOwnedData == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        memcpy(mOwnedData, data, size);
+        data = mOwnedData;
+    }
+
+    mHeader = (const ResStringPool_header*)data;
+
+    if (notDeviceEndian) {
+        ResStringPool_header* h = const_cast<ResStringPool_header*>(mHeader);
+        h->header.headerSize = dtohs(mHeader->header.headerSize);
+        h->header.type = dtohs(mHeader->header.type);
+        h->header.size = dtohl(mHeader->header.size);
+        h->stringCount = dtohl(mHeader->stringCount);
+        h->styleCount = dtohl(mHeader->styleCount);
+        h->flags = dtohl(mHeader->flags);
+        h->stringsStart = dtohl(mHeader->stringsStart);
+        h->stylesStart = dtohl(mHeader->stylesStart);
+    }
+
+    if (mHeader->header.headerSize > mHeader->header.size
+            || mHeader->header.size > size) {
+        LOGW("Bad string block: header size %d or total size %d is larger than data size %d\n",
+                (int)mHeader->header.headerSize, (int)mHeader->header.size, (int)size);
+        return (mError=BAD_TYPE);
+    }
+    mSize = mHeader->header.size;
+    mEntries = (const uint32_t*)
+        (((const uint8_t*)data)+mHeader->header.headerSize);
+
+    if (mHeader->stringCount > 0) {
+        if ((mHeader->stringCount*sizeof(uint32_t) < mHeader->stringCount)  // uint32 overflow?
+            || (mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t)))
+                > size) {
+            LOGW("Bad string block: entry of %d items extends past data size %d\n",
+                    (int)(mHeader->header.headerSize+(mHeader->stringCount*sizeof(uint32_t))),
+                    (int)size);
+            return (mError=BAD_TYPE);
+        }
+        mStrings = (const char16_t*)
+            (((const uint8_t*)data)+mHeader->stringsStart);
+        if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) {
+            LOGW("Bad string block: string pool starts at %d, after total size %d\n",
+                    (int)mHeader->stringsStart, (int)mHeader->header.size);
+            return (mError=BAD_TYPE);
+        }
+        if (mHeader->styleCount == 0) {
+            mStringPoolSize =
+                (mHeader->header.size-mHeader->stringsStart)/sizeof(uint16_t);
+        } else {
+            // check invariant: styles follow the strings
+            if (mHeader->stylesStart <= mHeader->stringsStart) {
+                LOGW("Bad style block: style block starts at %d, before strings at %d\n",
+                    (int)mHeader->stylesStart, (int)mHeader->stringsStart);
+                return (mError=BAD_TYPE);
+            }
+            mStringPoolSize =
+                (mHeader->stylesStart-mHeader->stringsStart)/sizeof(uint16_t);
+        }
+
+        // check invariant: stringCount > 0 requires a string pool to exist
+        if (mStringPoolSize == 0) {
+            LOGW("Bad string block: stringCount is %d but pool size is 0\n", (int)mHeader->stringCount);
+            return (mError=BAD_TYPE);
+        }
+
+        if (notDeviceEndian) {
+            size_t i;
+            uint32_t* e = const_cast<uint32_t*>(mEntries);
+            for (i=0; i<mHeader->stringCount; i++) {
+                e[i] = dtohl(mEntries[i]);
+            }
+            char16_t* s = const_cast<char16_t*>(mStrings);
+            for (i=0; i<mStringPoolSize; i++) {
+                s[i] = dtohs(mStrings[i]);
+            }
+        }
+
+        if (mStrings[mStringPoolSize-1] != 0) {
+            LOGW("Bad string block: last string is not 0-terminated\n");
+            return (mError=BAD_TYPE);
+        }
+    } else {
+        mStrings = NULL;
+        mStringPoolSize = 0;
+    }
+
+    if (mHeader->styleCount > 0) {
+        mEntryStyles = mEntries + mHeader->stringCount;
+        // invariant: integer overflow in calculating mEntryStyles
+        if (mEntryStyles < mEntries) {
+            LOGW("Bad string block: integer overflow finding styles\n");
+            return (mError=BAD_TYPE);
+        }
+
+        if (((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader) > (int)size) {
+            LOGW("Bad string block: entry of %d styles extends past data size %d\n",
+                    (int)((const uint8_t*)mEntryStyles-(const uint8_t*)mHeader),
+                    (int)size);
+            return (mError=BAD_TYPE);
+        }
+        mStyles = (const uint32_t*)
+            (((const uint8_t*)data)+mHeader->stylesStart);
+        if (mHeader->stylesStart >= mHeader->header.size) {
+            LOGW("Bad string block: style pool starts %d, after total size %d\n",
+                    (int)mHeader->stylesStart, (int)mHeader->header.size);
+            return (mError=BAD_TYPE);
+        }
+        mStylePoolSize =
+            (mHeader->header.size-mHeader->stylesStart)/sizeof(uint32_t);
+
+        if (notDeviceEndian) {
+            size_t i;
+            uint32_t* e = const_cast<uint32_t*>(mEntryStyles);
+            for (i=0; i<mHeader->styleCount; i++) {
+                e[i] = dtohl(mEntryStyles[i]);
+            }
+            uint32_t* s = const_cast<uint32_t*>(mStyles);
+            for (i=0; i<mStylePoolSize; i++) {
+                s[i] = dtohl(mStyles[i]);
+            }
+        }
+
+        const ResStringPool_span endSpan = {
+            { htodl(ResStringPool_span::END) },
+            htodl(ResStringPool_span::END), htodl(ResStringPool_span::END)
+        };
+        if (memcmp(&mStyles[mStylePoolSize-(sizeof(endSpan)/sizeof(uint32_t))],
+                   &endSpan, sizeof(endSpan)) != 0) {
+            LOGW("Bad string block: last style is not 0xFFFFFFFF-terminated\n");
+            return (mError=BAD_TYPE);
+        }
+    } else {
+        mEntryStyles = NULL;
+        mStyles = NULL;
+        mStylePoolSize = 0;
+    }
+
+    return (mError=NO_ERROR);
+}
+
+status_t ResStringPool::getError() const
+{
+    return mError;
+}
+
+void ResStringPool::uninit()
+{
+    mError = NO_INIT;
+    if (mOwnedData) {
+        free(mOwnedData);
+        mOwnedData = NULL;
+    }
+}
+
+const uint16_t* ResStringPool::stringAt(size_t idx, size_t* outLen) const
+{
+    if (mError == NO_ERROR && idx < mHeader->stringCount) {
+        const uint32_t off = (mEntries[idx]/sizeof(uint16_t));
+        if (off < (mStringPoolSize-1)) {
+            const char16_t* str = mStrings+off;
+            *outLen = *str;
+            if ((*str)&0x8000) {
+                str++;
+                *outLen = (((*outLen)&0x7fff)<<16) + *str;
+            }
+            if ((uint32_t)(str+1+*outLen-mStrings) < mStringPoolSize) {
+                return str+1;
+            } else {
+                LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+                        (int)idx, (int)(str+1+*outLen-mStrings), (int)mStringPoolSize);
+            }
+        } else {
+            LOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
+                    (int)idx, (int)(off*sizeof(uint16_t)),
+                    (int)(mStringPoolSize*sizeof(uint16_t)));
+        }
+    }
+    return NULL;
+}
+
+const ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const
+{
+    return styleAt(ref.index);
+}
+
+const ResStringPool_span* ResStringPool::styleAt(size_t idx) const
+{
+    if (mError == NO_ERROR && idx < mHeader->styleCount) {
+        const uint32_t off = (mEntryStyles[idx]/sizeof(uint32_t));
+        if (off < mStylePoolSize) {
+            return (const ResStringPool_span*)(mStyles+off);
+        } else {
+            LOGW("Bad string block: style #%d entry is at %d, past end at %d\n",
+                    (int)idx, (int)(off*sizeof(uint32_t)),
+                    (int)(mStylePoolSize*sizeof(uint32_t)));
+        }
+    }
+    return NULL;
+}
+
+ssize_t ResStringPool::indexOfString(const char16_t* str, size_t strLen) const
+{
+    if (mError != NO_ERROR) {
+        return mError;
+    }
+
+    size_t len;
+
+    if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
+        // Do a binary search for the string...
+        ssize_t l = 0;
+        ssize_t h = mHeader->stringCount-1;
+
+        ssize_t mid;
+        while (l <= h) {
+            mid = l + (h - l)/2;
+            const char16_t* s = stringAt(mid, &len);
+            int c = s ? strzcmp16(s, len, str, strLen) : -1;
+            POOL_NOISY(printf("Looking for %s, at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
+                         String8(str).string(),
+                         String8(s).string(),
+                         c, (int)l, (int)mid, (int)h));
+            if (c == 0) {
+                return mid;
+            } else if (c < 0) {
+                l = mid + 1;
+            } else {
+                h = mid - 1;
+            }
+        }
+    } else {
+        // It is unusual to get the ID from an unsorted string block...
+        // most often this happens because we want to get IDs for style
+        // span tags; since those always appear at the end of the string
+        // block, start searching at the back.
+        for (int i=mHeader->stringCount-1; i>=0; i--) {
+            const char16_t* s = stringAt(i, &len);
+            POOL_NOISY(printf("Looking for %s, at %s, i=%d\n",
+                         String8(str, strLen).string(),
+                         String8(s).string(),
+                         i));
+            if (s && strzcmp16(s, len, str, strLen) == 0) {
+                return i;
+            }
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+size_t ResStringPool::size() const
+{
+    return (mError == NO_ERROR) ? mHeader->stringCount : 0;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+ResXMLParser::ResXMLParser(const ResXMLTree& tree)
+    : mTree(tree), mEventCode(BAD_DOCUMENT)
+{
+}
+
+void ResXMLParser::restart()
+{
+    mCurNode = NULL;
+    mEventCode = mTree.mError == NO_ERROR ? START_DOCUMENT : BAD_DOCUMENT;
+}
+
+ResXMLParser::event_code_t ResXMLParser::getEventType() const
+{
+    return mEventCode;
+}
+
+ResXMLParser::event_code_t ResXMLParser::next()
+{
+    if (mEventCode == START_DOCUMENT) {
+        mCurNode = mTree.mRootNode;
+        mCurExt = mTree.mRootExt;
+        return (mEventCode=mTree.mRootCode);
+    } else if (mEventCode >= FIRST_CHUNK_CODE) {
+        return nextNode();
+    }
+    return mEventCode;
+}
+
+const int32_t ResXMLParser::getCommentID() const
+{
+    return mCurNode != NULL ? dtohl(mCurNode->comment.index) : -1;
+}
+
+const uint16_t* ResXMLParser::getComment(size_t* outLen) const
+{
+    int32_t id = getCommentID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const uint32_t ResXMLParser::getLineNumber() const
+{
+    return mCurNode != NULL ? dtohl(mCurNode->lineNumber) : -1;
+}
+
+const int32_t ResXMLParser::getTextID() const
+{
+    if (mEventCode == TEXT) {
+        return dtohl(((const ResXMLTree_cdataExt*)mCurExt)->data.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getText(size_t* outLen) const
+{
+    int32_t id = getTextID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+ssize_t ResXMLParser::getTextValue(Res_value* outValue) const
+{
+    if (mEventCode == TEXT) {
+        outValue->copyFrom_dtoh(((const ResXMLTree_cdataExt*)mCurExt)->typedData);
+        return sizeof(Res_value);
+    }
+    return BAD_TYPE;
+}
+
+const int32_t ResXMLParser::getNamespacePrefixID() const
+{
+    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
+        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->prefix.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const
+{
+    int32_t id = getNamespacePrefixID();
+    //printf("prefix=%d  event=%p\n", id, mEventCode);
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const int32_t ResXMLParser::getNamespaceUriID() const
+{
+    if (mEventCode == START_NAMESPACE || mEventCode == END_NAMESPACE) {
+        return dtohl(((const ResXMLTree_namespaceExt*)mCurExt)->uri.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const
+{
+    int32_t id = getNamespaceUriID();
+    //printf("uri=%d  event=%p\n", id, mEventCode);
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const int32_t ResXMLParser::getElementNamespaceID() const
+{
+    if (mEventCode == START_TAG) {
+        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->ns.index);
+    }
+    if (mEventCode == END_TAG) {
+        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->ns.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const
+{
+    int32_t id = getElementNamespaceID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const int32_t ResXMLParser::getElementNameID() const
+{
+    if (mEventCode == START_TAG) {
+        return dtohl(((const ResXMLTree_attrExt*)mCurExt)->name.index);
+    }
+    if (mEventCode == END_TAG) {
+        return dtohl(((const ResXMLTree_endElementExt*)mCurExt)->name.index);
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getElementName(size_t* outLen) const
+{
+    int32_t id = getElementNameID();
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+size_t ResXMLParser::getAttributeCount() const
+{
+    if (mEventCode == START_TAG) {
+        return dtohs(((const ResXMLTree_attrExt*)mCurExt)->attributeCount);
+    }
+    return 0;
+}
+
+const int32_t ResXMLParser::getAttributeNamespaceID(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->ns.index);
+        }
+    }
+    return -2;
+}
+
+const uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNamespaceID(idx);
+    //printf("attribute namespace=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const int32_t ResXMLParser::getAttributeNameID(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->name.index);
+        }
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNameID(idx);
+    //printf("attribute name=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+const uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const
+{
+    int32_t id = getAttributeNameID(idx);
+    if (id >= 0 && (size_t)id < mTree.mNumResIds) {
+        return dtohl(mTree.mResIds[id]);
+    }
+    return 0;
+}
+
+const int32_t ResXMLParser::getAttributeValueStringID(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->rawValue.index);
+        }
+    }
+    return -1;
+}
+
+const uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeValueStringID(idx);
+    //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
+}
+
+int32_t ResXMLParser::getAttributeDataType(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return attr->typedValue.dataType;
+        }
+    }
+    return Res_value::TYPE_NULL;
+}
+
+int32_t ResXMLParser::getAttributeData(size_t idx) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            return dtohl(attr->typedValue.data);
+        }
+    }
+    return 0;
+}
+
+ssize_t ResXMLParser::getAttributeValue(size_t idx, Res_value* outValue) const
+{
+    if (mEventCode == START_TAG) {
+        const ResXMLTree_attrExt* tag = (const ResXMLTree_attrExt*)mCurExt;
+        if (idx < dtohs(tag->attributeCount)) {
+            const ResXMLTree_attribute* attr = (const ResXMLTree_attribute*)
+                (((const uint8_t*)tag)
+                 + dtohs(tag->attributeStart)
+                 + (dtohs(tag->attributeSize)*idx));
+            outValue->copyFrom_dtoh(attr->typedValue);
+            return sizeof(Res_value);
+        }
+    }
+    return BAD_TYPE;
+}
+
+ssize_t ResXMLParser::indexOfAttribute(const char* ns, const char* attr) const
+{
+    String16 nsStr(ns != NULL ? ns : "");
+    String16 attrStr(attr);
+    return indexOfAttribute(ns ? nsStr.string() : NULL, ns ? nsStr.size() : 0,
+                            attrStr.string(), attrStr.size());
+}
+
+ssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen,
+                                       const char16_t* attr, size_t attrLen) const
+{
+    if (mEventCode == START_TAG) {
+        const size_t N = getAttributeCount();
+        for (size_t i=0; i<N; i++) {
+            size_t curNsLen, curAttrLen;
+            const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
+            const char16_t* curAttr = getAttributeName(i, &curAttrLen);
+            //printf("%d: ns=%p attr=%p curNs=%p curAttr=%p\n",
+            //       i, ns, attr, curNs, curAttr);
+            //printf(" --> attr=%s, curAttr=%s\n",
+            //       String8(attr).string(), String8(curAttr).string());
+            if (attr && curAttr && (strzcmp16(attr, attrLen, curAttr, curAttrLen) == 0)) {
+                if (ns == NULL) {
+                    if (curNs == NULL) return i;
+                } else if (curNs != NULL) {
+                    //printf(" --> ns=%s, curNs=%s\n",
+                    //       String8(ns).string(), String8(curNs).string());
+                    if (strzcmp16(ns, nsLen, curNs, curNsLen) == 0) return i;
+                }
+            }
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+ssize_t ResXMLParser::indexOfID() const
+{
+    if (mEventCode == START_TAG) {
+        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->idIndex);
+        if (idx > 0) return (idx-1);
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t ResXMLParser::indexOfClass() const
+{
+    if (mEventCode == START_TAG) {
+        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->classIndex);
+        if (idx > 0) return (idx-1);
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t ResXMLParser::indexOfStyle() const
+{
+    if (mEventCode == START_TAG) {
+        const ssize_t idx = dtohs(((const ResXMLTree_attrExt*)mCurExt)->styleIndex);
+        if (idx > 0) return (idx-1);
+    }
+    return NAME_NOT_FOUND;
+}
+
+ResXMLParser::event_code_t ResXMLParser::nextNode()
+{
+    if (mEventCode < 0) {
+        return mEventCode;
+    }
+
+    do {
+        const ResXMLTree_node* next = (const ResXMLTree_node*)
+            (((const uint8_t*)mCurNode) + dtohl(mCurNode->header.size));
+        //LOGW("Next node: prev=%p, next=%p\n", mCurNode, next);
+        
+        if (((const uint8_t*)next) >= mTree.mDataEnd) {
+            mCurNode = NULL;
+            return (mEventCode=END_DOCUMENT);
+        }
+
+        if (mTree.validateNode(next) != NO_ERROR) {
+            mCurNode = NULL;
+            return (mEventCode=BAD_DOCUMENT);
+        }
+
+        mCurNode = next;
+        const uint16_t headerSize = dtohs(next->header.headerSize);
+        const uint32_t totalSize = dtohl(next->header.size);
+        mCurExt = ((const uint8_t*)next) + headerSize;
+        size_t minExtSize = 0;
+        event_code_t eventCode = (event_code_t)dtohs(next->header.type);
+        switch ((mEventCode=eventCode)) {
+            case RES_XML_START_NAMESPACE_TYPE:
+            case RES_XML_END_NAMESPACE_TYPE:
+                minExtSize = sizeof(ResXMLTree_namespaceExt);
+                break;
+            case RES_XML_START_ELEMENT_TYPE:
+                minExtSize = sizeof(ResXMLTree_attrExt);
+                break;
+            case RES_XML_END_ELEMENT_TYPE:
+                minExtSize = sizeof(ResXMLTree_endElementExt);
+                break;
+            case RES_XML_CDATA_TYPE:
+                minExtSize = sizeof(ResXMLTree_cdataExt);
+                break;
+            default:
+                LOGW("Unknown XML block: header type %d in node at %d\n",
+                     (int)dtohs(next->header.type),
+                     (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)));
+                continue;
+        }
+        
+        if ((totalSize-headerSize) < minExtSize) {
+            LOGW("Bad XML block: header type 0x%x in node at 0x%x has size %d, need %d\n",
+                 (int)dtohs(next->header.type),
+                 (int)(((const uint8_t*)next)-((const uint8_t*)mTree.mHeader)),
+                 (int)(totalSize-headerSize), (int)minExtSize);
+            return (mEventCode=BAD_DOCUMENT);
+        }
+        
+        //printf("CurNode=%p, CurExt=%p, headerSize=%d, minExtSize=%d\n",
+        //       mCurNode, mCurExt, headerSize, minExtSize);
+        
+        return eventCode;
+    } while (true);
+}
+
+void ResXMLParser::getPosition(ResXMLParser::ResXMLPosition* pos) const
+{
+    pos->eventCode = mEventCode;
+    pos->curNode = mCurNode;
+    pos->curExt = mCurExt;
+}
+
+void ResXMLParser::setPosition(const ResXMLParser::ResXMLPosition& pos)
+{
+    mEventCode = pos.eventCode;
+    mCurNode = pos.curNode;
+    mCurExt = pos.curExt;
+}
+
+
+// --------------------------------------------------------------------
+
+static volatile int32_t gCount = 0;
+
+ResXMLTree::ResXMLTree()
+    : ResXMLParser(*this)
+    , mError(NO_INIT), mOwnedData(NULL)
+{
+    //LOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+    restart();
+}
+
+ResXMLTree::ResXMLTree(const void* data, size_t size, bool copyData)
+    : ResXMLParser(*this)
+    , mError(NO_INIT), mOwnedData(NULL)
+{
+    //LOGI("Creating ResXMLTree %p #%d\n", this, android_atomic_inc(&gCount)+1);
+    setTo(data, size, copyData);
+}
+
+ResXMLTree::~ResXMLTree()
+{
+    //LOGI("Destroying ResXMLTree in %p #%d\n", this, android_atomic_dec(&gCount)-1);
+    uninit();
+}
+
+status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData)
+{
+    uninit();
+    mEventCode = START_DOCUMENT;
+
+    if (copyData) {
+        mOwnedData = malloc(size);
+        if (mOwnedData == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        memcpy(mOwnedData, data, size);
+        data = mOwnedData;
+    }
+
+    mHeader = (const ResXMLTree_header*)data;
+    mSize = dtohl(mHeader->header.size);
+    if (dtohs(mHeader->header.headerSize) > mSize || mSize > size) {
+        LOGW("Bad XML block: header size %d or total size %d is larger than data size %d\n",
+             (int)dtohs(mHeader->header.headerSize),
+             (int)dtohl(mHeader->header.size), (int)size);
+        mError = BAD_TYPE;
+        restart();
+        return mError;
+    }
+    mDataEnd = ((const uint8_t*)mHeader) + mSize;
+
+    mStrings.uninit();
+    mRootNode = NULL;
+    mResIds = NULL;
+    mNumResIds = 0;
+
+    // First look for a couple interesting chunks: the string block
+    // and first XML node.
+    const ResChunk_header* chunk =
+        (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize));
+    const ResChunk_header* lastChunk = chunk;
+    while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) &&
+           ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) {
+        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, "XML");
+        if (err != NO_ERROR) {
+            mError = err;
+            goto done;
+        }
+        const uint16_t type = dtohs(chunk->type);
+        const size_t size = dtohl(chunk->size);
+        XML_NOISY(printf("Scanning @ %p: type=0x%x, size=0x%x\n",
+                     (void*)(((uint32_t)chunk)-((uint32_t)mHeader)), type, size));
+        if (type == RES_STRING_POOL_TYPE) {
+            mStrings.setTo(chunk, size);
+        } else if (type == RES_XML_RESOURCE_MAP_TYPE) {
+            mResIds = (const uint32_t*)
+                (((const uint8_t*)chunk)+dtohs(chunk->headerSize));
+            mNumResIds = (dtohl(chunk->size)-dtohs(chunk->headerSize))/sizeof(uint32_t);
+        } else if (type >= RES_XML_FIRST_CHUNK_TYPE
+                   && type <= RES_XML_LAST_CHUNK_TYPE) {
+            if (validateNode((const ResXMLTree_node*)chunk) != NO_ERROR) {
+                mError = BAD_TYPE;
+                goto done;
+            }
+            mCurNode = (const ResXMLTree_node*)lastChunk;
+            if (nextNode() == BAD_DOCUMENT) {
+                mError = BAD_TYPE;
+                goto done;
+            }
+            mRootNode = mCurNode;
+            mRootExt = mCurExt;
+            mRootCode = mEventCode;
+            break;
+        } else {
+            XML_NOISY(printf("Skipping unknown chunk!\n"));
+        }
+        lastChunk = chunk;
+        chunk = (const ResChunk_header*)
+            (((const uint8_t*)chunk) + size);
+    }
+
+    if (mRootNode == NULL) {
+        LOGW("Bad XML block: no root element node found\n");
+        mError = BAD_TYPE;
+        goto done;
+    }
+
+    mError = mStrings.getError();
+
+done:
+    restart();
+    return mError;
+}
+
+status_t ResXMLTree::getError() const
+{
+    return mError;
+}
+
+void ResXMLTree::uninit()
+{
+    mError = NO_INIT;
+    if (mOwnedData) {
+        free(mOwnedData);
+        mOwnedData = NULL;
+    }
+    restart();
+}
+
+const ResStringPool& ResXMLTree::getStrings() const
+{
+    return mStrings;
+}
+
+status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const
+{
+    const uint16_t eventCode = dtohs(node->header.type);
+
+    status_t err = validate_chunk(
+        &node->header, sizeof(ResXMLTree_node),
+        mDataEnd, "ResXMLTree_node");
+
+    if (err >= NO_ERROR) {
+        // Only perform additional validation on START nodes
+        if (eventCode != RES_XML_START_ELEMENT_TYPE) {
+            return NO_ERROR;
+        }
+
+        const uint16_t headerSize = dtohs(node->header.headerSize);
+        const uint32_t size = dtohl(node->header.size);
+        const ResXMLTree_attrExt* attrExt = (const ResXMLTree_attrExt*)
+            (((const uint8_t*)node) + headerSize);
+        // check for sensical values pulled out of the stream so far...
+        if ((size >= headerSize + sizeof(ResXMLTree_attrExt))
+                && ((void*)attrExt > (void*)node)) {
+            const size_t attrSize = ((size_t)dtohs(attrExt->attributeSize))
+                * dtohs(attrExt->attributeCount);
+            if ((dtohs(attrExt->attributeStart)+attrSize) <= (size-headerSize)) {
+                return NO_ERROR;
+            }
+            LOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
+                    (unsigned int)(dtohs(attrExt->attributeStart)+attrSize),
+                    (unsigned int)(size-headerSize));
+        }
+        else {
+            LOGW("Bad XML start block: node header size 0x%x, size 0x%x\n",
+                (unsigned int)headerSize, (unsigned int)size);
+        }
+        return BAD_TYPE;
+    }
+
+    return err;
+
+#if 0
+    const bool isStart = dtohs(node->header.type) == RES_XML_START_ELEMENT_TYPE;
+
+    const uint16_t headerSize = dtohs(node->header.headerSize);
+    const uint32_t size = dtohl(node->header.size);
+
+    if (headerSize >= (isStart ? sizeof(ResXMLTree_attrNode) : sizeof(ResXMLTree_node))) {
+        if (size >= headerSize) {
+            if (((const uint8_t*)node) <= (mDataEnd-size)) {
+                if (!isStart) {
+                    return NO_ERROR;
+                }
+                if ((((size_t)dtohs(node->attributeSize))*dtohs(node->attributeCount))
+                        <= (size-headerSize)) {
+                    return NO_ERROR;
+                }
+                LOGW("Bad XML block: node attributes use 0x%x bytes, only have 0x%x bytes\n",
+                        ((int)dtohs(node->attributeSize))*dtohs(node->attributeCount),
+                        (int)(size-headerSize));
+                return BAD_TYPE;
+            }
+            LOGW("Bad XML block: node at 0x%x extends beyond data end 0x%x\n",
+                    (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)), (int)mSize);
+            return BAD_TYPE;
+        }
+        LOGW("Bad XML block: node at 0x%x header size 0x%x smaller than total size 0x%x\n",
+                (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
+                (int)headerSize, (int)size);
+        return BAD_TYPE;
+    }
+    LOGW("Bad XML block: node at 0x%x header size 0x%x too small\n",
+            (int)(((const uint8_t*)node)-((const uint8_t*)mHeader)),
+            (int)headerSize);
+    return BAD_TYPE;
+#endif
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+struct ResTable::Header
+{
+    Header() : ownedData(NULL), header(NULL) { }
+
+    void*                           ownedData;
+    const ResTable_header*          header;
+    size_t                          size;
+    const uint8_t*                  dataEnd;
+    size_t                          index;
+    void*                           cookie;
+
+    ResStringPool                   values;
+};
+
+struct ResTable::Type
+{
+    Type(const Header* _header, const Package* _package, size_t count)
+        : header(_header), package(_package), entryCount(count),
+          typeSpec(NULL), typeSpecFlags(NULL) { }
+    const Header* const             header;
+    const Package* const            package;
+    const size_t                    entryCount;
+    const ResTable_typeSpec*        typeSpec;
+    const uint32_t*                 typeSpecFlags;
+    Vector<const ResTable_type*>    configs;
+};
+
+struct ResTable::Package
+{
+    Package(const Header* _header, const ResTable_package* _package)
+        : header(_header), package(_package) { }
+    ~Package()
+    {
+        size_t i = types.size();
+        while (i > 0) {
+            i--;
+            delete types[i];
+        }
+    }
+    
+    const Header* const             header;
+    const ResTable_package* const   package;
+    Vector<Type*>                   types;
+
+    const Type* getType(size_t idx) const {
+        return idx < types.size() ? types[idx] : NULL;
+    }
+};
+
+// A group of objects describing a particular resource package.
+// The first in 'package' is always the root object (from the resource
+// table that defined the package); the ones after are skins on top of it.
+struct ResTable::PackageGroup
+{
+    PackageGroup(const String16& _name, uint32_t _id)
+        : name(_name), id(_id), typeCount(0), bags(NULL) { }
+    ~PackageGroup() {
+        clearBagCache();
+        const size_t N = packages.size();
+        for (size_t i=0; i<N; i++) {
+            delete packages[i];
+        }
+    }
+
+    void clearBagCache() {
+        if (bags) {
+            TABLE_NOISY(printf("bags=%p\n", bags));
+            Package* pkg = packages[0];
+            TABLE_NOISY(printf("typeCount=%x\n", typeCount));
+            for (size_t i=0; i<typeCount; i++) {
+                TABLE_NOISY(printf("type=%d\n", i));
+                const Type* type = pkg->getType(i);
+                if (type != NULL) {
+                    bag_set** typeBags = bags[i];
+                    TABLE_NOISY(printf("typeBags=%p\n", typeBags));
+                    if (typeBags) {
+                        TABLE_NOISY(printf("type->entryCount=%x\n", type->entryCount));
+                        const size_t N = type->entryCount;
+                        for (size_t j=0; j<N; j++) {
+                            if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF)
+                                free(typeBags[j]);
+                        }
+                        free(typeBags);
+                    }
+                }
+            }
+            free(bags);
+            bags = NULL;
+        }
+    }
+    
+    String16 const                  name;
+    uint32_t const                  id;
+    Vector<Package*>                packages;
+
+    // Taken from the root package.
+    ResStringPool                   typeStrings;
+    ResStringPool                   keyStrings;
+    size_t                          typeCount;
+
+    // Computed attribute bags, first indexed by the type and second
+    // by the entry in that type.
+    bag_set***                      bags;
+};
+
+struct ResTable::bag_set
+{
+    size_t numAttrs;    // number in array
+    size_t availAttrs;  // total space in array
+    uint32_t typeSpecFlags;
+    // Followed by 'numAttr' bag_entry structures.
+};
+
+ResTable::Theme::Theme(const ResTable& table)
+    : mTable(table)
+{
+    memset(mPackages, 0, sizeof(mPackages));
+}
+
+ResTable::Theme::~Theme()
+{
+    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+        package_info* pi = mPackages[i];
+        if (pi != NULL) {
+            free_package(pi);
+        }
+    }
+}
+
+void ResTable::Theme::free_package(package_info* pi)
+{
+    for (size_t j=0; j<pi->numTypes; j++) {
+        theme_entry* te = pi->types[j].entries;
+        if (te != NULL) {
+            free(te);
+        }
+    }
+    free(pi);
+}
+
+ResTable::Theme::package_info* ResTable::Theme::copy_package(package_info* pi)
+{
+    package_info* newpi = (package_info*)malloc(
+        sizeof(package_info) + (pi->numTypes*sizeof(type_info)));
+    newpi->numTypes = pi->numTypes;
+    for (size_t j=0; j<newpi->numTypes; j++) {
+        size_t cnt = pi->types[j].numEntries;
+        newpi->types[j].numEntries = cnt;
+        theme_entry* te = pi->types[j].entries;
+        if (te != NULL) {
+            theme_entry* newte = (theme_entry*)malloc(cnt*sizeof(theme_entry));
+            newpi->types[j].entries = newte;
+            memcpy(newte, te, cnt*sizeof(theme_entry));
+        } else {
+            newpi->types[j].entries = NULL;
+        }
+    }
+    return newpi;
+}
+
+status_t ResTable::Theme::applyStyle(uint32_t resID, bool force)
+{
+    const bag_entry* bag;
+    uint32_t bagTypeSpecFlags = 0;
+    mTable.lock();
+    const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
+    TABLE_NOISY(LOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
+    if (N < 0) {
+        mTable.unlock();
+        return N;
+    }
+
+    uint32_t curPackage = 0xffffffff;
+    ssize_t curPackageIndex = 0;
+    package_info* curPI = NULL;
+    uint32_t curType = 0xffffffff;
+    size_t numEntries = 0;
+    theme_entry* curEntries = NULL;
+
+    const bag_entry* end = bag + N;
+    while (bag < end) {
+        const uint32_t attrRes = bag->map.name.ident;
+        const uint32_t p = Res_GETPACKAGE(attrRes);
+        const uint32_t t = Res_GETTYPE(attrRes);
+        const uint32_t e = Res_GETENTRY(attrRes);
+
+        if (curPackage != p) {
+            const ssize_t pidx = mTable.getResourcePackageIndex(attrRes);
+            if (pidx < 0) {
+                LOGE("Style contains key with bad package: 0x%08x\n", attrRes);
+                bag++;
+                continue;
+            }
+            curPackage = p;
+            curPackageIndex = pidx;
+            curPI = mPackages[pidx];
+            if (curPI == NULL) {
+                PackageGroup* const grp = mTable.mPackageGroups[pidx];
+                int cnt = grp->typeCount;
+                curPI = (package_info*)malloc(
+                    sizeof(package_info) + (cnt*sizeof(type_info)));
+                curPI->numTypes = cnt;
+                memset(curPI->types, 0, cnt*sizeof(type_info));
+                mPackages[pidx] = curPI;
+            }
+            curType = 0xffffffff;
+        }
+        if (curType != t) {
+            if (t >= curPI->numTypes) {
+                LOGE("Style contains key with bad type: 0x%08x\n", attrRes);
+                bag++;
+                continue;
+            }
+            curType = t;
+            curEntries = curPI->types[t].entries;
+            if (curEntries == NULL) {
+                PackageGroup* const grp = mTable.mPackageGroups[curPackageIndex];
+                const Type* type = grp->packages[0]->getType(t);
+                int cnt = type != NULL ? type->entryCount : 0;
+                curEntries = (theme_entry*)malloc(cnt*sizeof(theme_entry));
+                memset(curEntries, Res_value::TYPE_NULL, cnt*sizeof(theme_entry));
+                curPI->types[t].numEntries = cnt;
+                curPI->types[t].entries = curEntries;
+            }
+            numEntries = curPI->types[t].numEntries;
+        }
+        if (e >= numEntries) {
+            LOGE("Style contains key with bad entry: 0x%08x\n", attrRes);
+            bag++;
+            continue;
+        }
+        theme_entry* curEntry = curEntries + e;
+        TABLE_NOISY(LOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
+                   attrRes, bag->map.value.dataType, bag->map.value.data,
+             curEntry->value.dataType));
+        if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
+            curEntry->stringBlock = bag->stringBlock;
+            curEntry->typeSpecFlags |= bagTypeSpecFlags;
+            curEntry->value = bag->map.value;
+        }
+
+        bag++;
+    }
+
+    mTable.unlock();
+
+    //LOGI("Applying style 0x%08x (force=%d)  theme %p...\n", resID, force, this);
+    //dumpToLog();
+    
+    return NO_ERROR;
+}
+
+status_t ResTable::Theme::setTo(const Theme& other)
+{
+    //LOGI("Setting theme %p from theme %p...\n", this, &other);
+    //dumpToLog();
+    //other.dumpToLog();
+    
+    if (&mTable == &other.mTable) {
+        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+            if (mPackages[i] != NULL) {
+                free_package(mPackages[i]);
+            }
+            if (other.mPackages[i] != NULL) {
+                mPackages[i] = copy_package(other.mPackages[i]);
+            } else {
+                mPackages[i] = NULL;
+            }
+        }
+    } else {
+        // @todo: need to really implement this, not just copy
+        // the system package (which is still wrong because it isn't
+        // fixing up resource references).
+        for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+            if (mPackages[i] != NULL) {
+                free_package(mPackages[i]);
+            }
+            if (i == 0 && other.mPackages[i] != NULL) {
+                mPackages[i] = copy_package(other.mPackages[i]);
+            } else {
+                mPackages[i] = NULL;
+            }
+        }
+    }
+
+    //LOGI("Final theme:");
+    //dumpToLog();
+    
+    return NO_ERROR;
+}
+
+ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,
+        uint32_t* outTypeSpecFlags) const
+{
+    int cnt = 20;
+
+    if (outTypeSpecFlags != NULL) *outTypeSpecFlags = 0;
+    
+    do {
+        const ssize_t p = mTable.getResourcePackageIndex(resID);
+        const uint32_t t = Res_GETTYPE(resID);
+        const uint32_t e = Res_GETENTRY(resID);
+
+        TABLE_NOISY(LOGV("Looking up attr 0x%08x in theme %p", resID, this));
+
+        if (p >= 0) {
+            const package_info* const pi = mPackages[p];
+            if (pi != NULL) {
+                if (t < pi->numTypes) {
+                    const type_info& ti = pi->types[t];
+                    if (e < ti.numEntries) {
+                        const theme_entry& te = ti.entries[e];
+                            if (outTypeSpecFlags != NULL) {
+                                *outTypeSpecFlags |= te.typeSpecFlags;
+                            }
+                        const uint8_t type = te.value.dataType;
+                        if (type == Res_value::TYPE_ATTRIBUTE) {
+                            if (cnt > 0) {
+                                cnt--;
+                                resID = te.value.data;
+                                continue;
+                            }
+                            LOGW("Too many attribute references, stopped at: 0x%08x\n", resID);
+                            return BAD_INDEX;
+                        } else if (type != Res_value::TYPE_NULL) {
+                            *outValue = te.value;
+                            return te.stringBlock;
+                        }
+                        return BAD_INDEX;
+                    }
+                }
+            }
+        }
+        break;
+
+    } while (true);
+
+    return BAD_INDEX;
+}
+
+ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
+        ssize_t blockIndex, uint32_t* outLastRef,
+        uint32_t* inoutTypeSpecFlags) const
+{
+    //printf("Resolving type=0x%x\n", inOutValue->dataType);
+    if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
+        uint32_t newTypeSpecFlags;
+        blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
+        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
+        //printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
+        if (blockIndex < 0) {
+            return blockIndex;
+        }
+    }
+    return mTable.resolveReference(inOutValue, blockIndex, outLastRef);
+}
+
+void ResTable::Theme::dumpToLog() const
+{
+    LOGI("Theme %p:\n", this);
+    for (size_t i=0; i<Res_MAXPACKAGE; i++) {
+        package_info* pi = mPackages[i];
+        if (pi == NULL) continue;
+        
+        LOGI("  Package #0x%02x:\n", (int)(i+1));
+        for (size_t j=0; j<pi->numTypes; j++) {
+            type_info& ti = pi->types[j];
+            if (ti.numEntries == 0) continue;
+            
+            LOGI("    Type #0x%02x:\n", (int)(j+1));
+            for (size_t k=0; k<ti.numEntries; k++) {
+                theme_entry& te = ti.entries[k];
+                if (te.value.dataType == Res_value::TYPE_NULL) continue;
+                LOGI("      0x%08x: t=0x%x, d=0x%08x (block=%d)\n",
+                     (int)Res_MAKEID(i, j, k),
+                     te.value.dataType, (int)te.value.data, (int)te.stringBlock);
+            }
+        }
+    }
+}
+
+ResTable::ResTable()
+    : mError(NO_INIT)
+{
+    memset(&mParams, 0, sizeof(mParams));
+    memset(mPackageMap, 0, sizeof(mPackageMap));
+    //LOGI("Creating ResTable %p\n", this);
+}
+
+ResTable::ResTable(const void* data, size_t size, void* cookie, bool copyData)
+    : mError(NO_INIT)
+{
+    memset(&mParams, 0, sizeof(mParams));
+    memset(mPackageMap, 0, sizeof(mPackageMap));
+    add(data, size, cookie, copyData);
+    LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table");
+    //LOGI("Creating ResTable %p\n", this);
+}
+
+ResTable::~ResTable()
+{
+    //LOGI("Destroying ResTable in %p\n", this);
+    uninit();
+}
+
+inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const
+{
+    return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;
+}
+
+status_t ResTable::add(const void* data, size_t size, void* cookie, bool copyData)
+{
+    return add(data, size, cookie, NULL, copyData);
+}
+
+status_t ResTable::add(Asset* asset, void* cookie, bool copyData)
+{
+    const void* data = asset->getBuffer(true);
+    if (data == NULL) {
+        LOGW("Unable to get buffer of resource asset file");
+        return UNKNOWN_ERROR;
+    }
+    size_t size = (size_t)asset->getLength();
+    return add(data, size, cookie, asset, copyData);
+}
+
+status_t ResTable::add(const void* data, size_t size, void* cookie,
+                       Asset* asset, bool copyData)
+{
+    if (!data) return NO_ERROR;
+    Header* header = new Header;
+    header->index = mHeaders.size();
+    header->cookie = cookie;
+    mHeaders.add(header);
+
+    const bool notDeviceEndian = htods(0xf0) != 0xf0;
+
+    LOAD_TABLE_NOISY(
+        LOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d\n",
+             data, size, cookie, asset, copyData));
+    
+    if (copyData || notDeviceEndian) {
+        header->ownedData = malloc(size);
+        if (header->ownedData == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        memcpy(header->ownedData, data, size);
+        data = header->ownedData;
+    }
+
+    header->header = (const ResTable_header*)data;
+    header->size = dtohl(header->header->header.size);
+    //LOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
+    //     dtohl(header->header->header.size), header->header->header.size);
+    LOAD_TABLE_NOISY(LOGV("Loading ResTable @%p:\n", header->header));
+    LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256,
+                                  16, 16, 0, false, printToLogFunc));
+    if (dtohs(header->header->header.headerSize) > header->size
+            || header->size > size) {
+        LOGW("Bad resource table: header size 0x%x or total size 0x%x is larger than data size 0x%x\n",
+             (int)dtohs(header->header->header.headerSize),
+             (int)header->size, (int)size);
+        return (mError=BAD_TYPE);
+    }
+    if (((dtohs(header->header->header.headerSize)|header->size)&0x3) != 0) {
+        LOGW("Bad resource table: header size 0x%x or total size 0x%x is not on an integer boundary\n",
+             (int)dtohs(header->header->header.headerSize),
+             (int)header->size);
+        return (mError=BAD_TYPE);
+    }
+    header->dataEnd = ((const uint8_t*)header->header) + header->size;
+
+    // Iterate through all chunks.
+    size_t curPackage = 0;
+
+    const ResChunk_header* chunk =
+        (const ResChunk_header*)(((const uint8_t*)header->header)
+                                 + dtohs(header->header->header.headerSize));
+    while (((const uint8_t*)chunk) <= (header->dataEnd-sizeof(ResChunk_header)) &&
+           ((const uint8_t*)chunk) <= (header->dataEnd-dtohl(chunk->size))) {
+        status_t err = validate_chunk(chunk, sizeof(ResChunk_header), header->dataEnd, "ResTable");
+        if (err != NO_ERROR) {
+            return (mError=err);
+        }
+        TABLE_NOISY(LOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+                     dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
+                     (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
+        const size_t csize = dtohl(chunk->size);
+        const uint16_t ctype = dtohs(chunk->type);
+        if (ctype == RES_STRING_POOL_TYPE) {
+            if (header->values.getError() != NO_ERROR) {
+                // Only use the first string chunk; ignore any others that
+                // may appear.
+                status_t err = header->values.setTo(chunk, csize);
+                if (err != NO_ERROR) {
+                    return (mError=err);
+                }
+            } else {
+                LOGW("Multiple string chunks found in resource table.");
+            }
+        } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
+            if (curPackage >= dtohl(header->header->packageCount)) {
+                LOGW("More package chunks were found than the %d declared in the header.",
+                     dtohl(header->header->packageCount));
+                return (mError=BAD_TYPE);
+            }
+            if (parsePackage((ResTable_package*)chunk, header) != NO_ERROR) {
+                return mError;
+            }
+            curPackage++;
+        } else {
+            LOGW("Unknown chunk type %p in table at %p.\n",
+                 (void*)(int)(ctype),
+                 (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header)));
+        }
+        chunk = (const ResChunk_header*)
+            (((const uint8_t*)chunk) + csize);
+    }
+
+    if (curPackage < dtohl(header->header->packageCount)) {
+        LOGW("Fewer package chunks (%d) were found than the %d declared in the header.",
+             (int)curPackage, dtohl(header->header->packageCount));
+        return (mError=BAD_TYPE);
+    }
+    mError = header->values.getError();
+    if (mError != NO_ERROR) {
+        LOGW("No string values found in resource table!");
+    }
+    TABLE_NOISY(LOGV("Returning from add with mError=%d\n", mError));
+    return mError;
+}
+
+status_t ResTable::getError() const
+{
+    return mError;
+}
+
+void ResTable::uninit()
+{
+    mError = NO_INIT;
+    size_t N = mPackageGroups.size();
+    for (size_t i=0; i<N; i++) {
+        PackageGroup* g = mPackageGroups[i];
+        delete g;
+    }
+    N = mHeaders.size();
+    for (size_t i=0; i<N; i++) {
+        Header* header = mHeaders[i];
+        if (header->ownedData) {
+            free(header->ownedData);
+        }
+        delete header;
+    }
+
+    mPackageGroups.clear();
+    mHeaders.clear();
+}
+
+bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const
+{
+    if (mError != NO_ERROR) {
+        return false;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+    if (t < 0) {
+        LOGW("No type identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+
+    const PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        LOGW("Bad identifier when getting name for resource number 0x%08x", resID);
+        return false;
+    }
+    if (grp->packages.size() > 0) {
+        const Package* const package = grp->packages[0];
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        ssize_t offset = getEntry(package, t, e, NULL, &type, &entry, NULL);
+        if (offset <= 0) {
+            return false;
+        }
+
+        outName->package = grp->name.string();
+        outName->packageLen = grp->name.size();
+        outName->type = grp->typeStrings.stringAt(t, &outName->typeLen);
+        outName->name = grp->keyStrings.stringAt(
+            dtohl(entry->key.index), &outName->nameLen);
+        return true;
+    }
+
+    return false;
+}
+
+ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag,
+        uint32_t* outSpecFlags) const
+{
+    if (mError != NO_ERROR) {
+        return mError;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        LOGW("No package identifier when getting value for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+    if (t < 0) {
+        LOGW("No type identifier when getting value for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+
+    const Res_value* bestValue = NULL;
+    const Package* bestPackage = NULL;
+    ResTable_config bestItem;
+    memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up
+
+    if (outSpecFlags != NULL) *outSpecFlags = 0;
+    
+    // Look through all resource packages, starting with the most
+    // recently added.
+    const PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        LOGW("Bad identifier when getting value for resource number 0x%08x", resID);
+        return false;
+    }
+    size_t ip = grp->packages.size();
+    while (ip > 0) {
+        ip--;
+
+        const Package* const package = grp->packages[ip];
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        const Type* typeClass;
+        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);
+                return offset;
+            }
+            continue;
+        }
+
+        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) != 0) {
+            if (!mayBeBag) {
+                LOGW("Requesting resource %p failed because it is complex\n",
+                     (void*)resID);
+            }
+            continue;
+        }
+
+        TABLE_NOISY(aout << "Resource type data: "
+              << HexDump(type, dtohl(type->header.size)) << endl);
+        
+        if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) {
+            LOGW("ResTable_item at %d is beyond type chunk data %d",
+                 (int)offset, dtohl(type->header.size));
+            return BAD_TYPE;
+        }
+        
+        const Res_value* item =
+            (const Res_value*)(((const uint8_t*)type) + offset);
+        ResTable_config thisConfig;
+        thisConfig.copyFromDtoH(type->config);
+        
+        if (outSpecFlags != NULL) {
+            if (typeClass->typeSpecFlags != NULL) {
+                *outSpecFlags |= dtohl(typeClass->typeSpecFlags[e]);
+            } else {
+                *outSpecFlags = -1;
+            }
+        }
+        
+        if (bestPackage != NULL && bestItem.isBetterThan(thisConfig)) {
+            continue;
+        }
+        
+        bestItem = thisConfig;
+        bestValue = item;
+        bestPackage = package;
+    }
+
+    TABLE_NOISY(printf("Found result: package %p\n", bestPackage));
+
+    if (bestValue) {
+        outValue->size = dtohs(bestValue->size);
+        outValue->res0 = bestValue->res0;
+        outValue->dataType = bestValue->dataType;
+        outValue->data = dtohl(bestValue->data);
+        TABLE_NOISY(size_t len;
+              printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n",
+                     bestPackage->header->index,
+                     outValue->dataType,
+                     outValue->dataType == bestValue->TYPE_STRING
+                     ? String8(bestPackage->header->values.stringAt(
+                         outValue->data, &len)).string()
+                     : "",
+                     outValue->data));
+        return bestPackage->header->index;
+    }
+
+    return BAD_INDEX;
+}
+
+ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
+        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags) const
+{
+    int count=0;
+    while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
+           && value->data != 0 && count < 20) {
+        if (outLastRef) *outLastRef = value->data;
+        uint32_t lastRef = value->data;
+        uint32_t newFlags = 0;
+        const ssize_t newIndex = getResource(value->data, value, true, &newFlags);
+        //LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%p\n",
+        //     (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data);
+        //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
+        if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
+        if (newIndex < 0) {
+            // This can fail if the resource being referenced is a style...
+            // in this case, just return the reference, and expect the
+            // caller to deal with.
+            return blockIndex;
+        }
+        blockIndex = newIndex;
+        count++;
+    }
+    return blockIndex;
+}
+
+const char16_t* ResTable::valueToString(
+    const Res_value* value, size_t stringBlock,
+    char16_t tmpBuffer[TMP_BUFFER_SIZE], size_t* outLen)
+{
+    if (!value) {
+        return NULL;
+    }
+    if (value->dataType == value->TYPE_STRING) {
+        return getTableStringBlock(stringBlock)->stringAt(value->data, outLen);
+    }
+    // XXX do int to string conversions.
+    return NULL;
+}
+
+ssize_t ResTable::lockBag(uint32_t resID, const bag_entry** outBag) const
+{
+    mLock.lock();
+    ssize_t err = getBagLocked(resID, outBag);
+    if (err < NO_ERROR) {
+        //printf("*** get failed!  unlocking\n");
+        mLock.unlock();
+    }
+    return err;
+}
+
+void ResTable::unlockBag(const bag_entry* bag) const
+{
+    //printf("<<< unlockBag %p\n", this);
+    mLock.unlock();
+}
+
+void ResTable::lock() const
+{
+    mLock.lock();
+}
+
+void ResTable::unlock() const
+{
+    mLock.unlock();
+}
+
+ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
+        uint32_t* outTypeSpecFlags) const
+{
+    if (mError != NO_ERROR) {
+        return mError;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        LOGW("Invalid package identifier when getting bag for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+    if (t < 0) {
+        LOGW("No type identifier when getting bag for resource number 0x%08x", resID);
+        return BAD_INDEX;
+    }
+
+    //printf("Get bag: id=0x%08x, p=%d, t=%d\n", resID, p, t);
+    PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        LOGW("Bad identifier when getting bag for resource number 0x%08x", resID);
+        return false;
+    }
+
+    if (t >= (int)grp->typeCount) {
+        LOGW("Type identifier 0x%x is larger than type count 0x%x",
+             t+1, (int)grp->typeCount);
+        return BAD_INDEX;
+    }
+
+    const Package* const basePackage = grp->packages[0];
+
+    const Type* const typeConfigs = basePackage->getType(t);
+
+    const size_t NENTRY = typeConfigs->entryCount;
+    if (e >= (int)NENTRY) {
+        LOGW("Entry identifier 0x%x is larger than entry count 0x%x",
+             e, (int)typeConfigs->entryCount);
+        return BAD_INDEX;
+    }
+
+    // First see if we've already computed this bag...
+    if (grp->bags) {
+        bag_set** typeSet = grp->bags[t];
+        if (typeSet) {
+            bag_set* set = typeSet[e];
+            if (set) {
+                if (set != (bag_set*)0xFFFFFFFF) {
+                    if (outTypeSpecFlags != NULL) {
+                        *outTypeSpecFlags = set->typeSpecFlags;
+                    }
+                    *outBag = (bag_entry*)(set+1);
+                    //LOGI("Found existing bag for: %p\n", (void*)resID);
+                    return set->numAttrs;
+                }
+                LOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.",
+                     resID);
+                return BAD_INDEX;
+            }
+        }
+    }
+
+    // Bag not found, we need to compute it!
+    if (!grp->bags) {
+        grp->bags = (bag_set***)malloc(sizeof(bag_set*)*grp->typeCount);
+        if (!grp->bags) return NO_MEMORY;
+        memset(grp->bags, 0, sizeof(bag_set*)*grp->typeCount);
+    }
+
+    bag_set** typeSet = grp->bags[t];
+    if (!typeSet) {
+        typeSet = (bag_set**)malloc(sizeof(bag_set*)*NENTRY);
+        if (!typeSet) return NO_MEMORY;
+        memset(typeSet, 0, sizeof(bag_set*)*NENTRY);
+        grp->bags[t] = typeSet;
+    }
+
+    // Mark that we are currently working on this one.
+    typeSet[e] = (bag_set*)0xFFFFFFFF;
+
+    // This is what we are building.
+    bag_set* set = NULL;
+
+    TABLE_NOISY(LOGI("Building bag: %p\n", (void*)resID));
+    
+    // Now collect all bag attributes from all packages.
+    size_t ip = grp->packages.size();
+    while (ip > 0) {
+        ip--;
+
+        const Package* const package = grp->packages[ip];
+
+        const ResTable_type* type;
+        const ResTable_entry* entry;
+        const Type* typeClass;
+        LOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, t, e);
+        ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
+        LOGV("Resulting offset=%d\n", offset);
+        if (offset <= 0) {
+            if (offset < 0) {
+                if (set) free(set);
+                return offset;
+            }
+            continue;
+        }
+
+        if ((dtohs(entry->flags)&entry->FLAG_COMPLEX) == 0) {
+            LOGW("Skipping entry %p in package table %d because it is not complex!\n",
+                 (void*)resID, (int)ip);
+            continue;
+        }
+
+        const uint16_t entrySize = dtohs(entry->size);
+        const uint32_t parent = entrySize >= sizeof(ResTable_map_entry)
+            ? dtohl(((const ResTable_map_entry*)entry)->parent.ident) : 0;
+        const uint32_t count = entrySize >= sizeof(ResTable_map_entry)
+            ? dtohl(((const ResTable_map_entry*)entry)->count) : 0;
+        
+        size_t N = count;
+
+        TABLE_NOISY(LOGI("Found map: size=%p parent=%p count=%d\n",
+                         entrySize, parent, count));
+
+        if (set == NULL) {
+            // If this map inherits from another, we need to start
+            // with its parent's values.  Otherwise start out empty.
+            TABLE_NOISY(printf("Creating new bag, entrySize=0x%08x, parent=0x%08x\n",
+                         entrySize, parent));
+            if (parent) {
+                const bag_entry* parentBag;
+                uint32_t parentTypeSpecFlags = 0;
+                const ssize_t NP = getBagLocked(parent, &parentBag, &parentTypeSpecFlags);
+                const size_t NT = ((NP >= 0) ? NP : 0) + N;
+                set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*NT);
+                if (set == NULL) {
+                    return NO_MEMORY;
+                }
+                if (NP > 0) {
+                    memcpy(set+1, parentBag, NP*sizeof(bag_entry));
+                    set->numAttrs = NP;
+                    TABLE_NOISY(LOGI("Initialized new bag with %d inherited attributes.\n", NP));
+                } else {
+                    TABLE_NOISY(LOGI("Initialized new bag with no inherited attributes.\n"));
+                    set->numAttrs = 0;
+                }
+                set->availAttrs = NT;
+                set->typeSpecFlags = parentTypeSpecFlags;
+            } else {
+                set = (bag_set*)malloc(sizeof(bag_set)+sizeof(bag_entry)*N);
+                if (set == NULL) {
+                    return NO_MEMORY;
+                }
+                set->numAttrs = 0;
+                set->availAttrs = N;
+                set->typeSpecFlags = 0;
+            }
+        }
+
+        if (typeClass->typeSpecFlags != NULL) {
+            set->typeSpecFlags |= dtohl(typeClass->typeSpecFlags[e]);
+        } else {
+            set->typeSpecFlags = -1;
+        }
+        
+        // Now merge in the new attributes...
+        ssize_t curOff = offset;
+        const ResTable_map* map;
+        bag_entry* entries = (bag_entry*)(set+1);
+        size_t curEntry = 0;
+        uint32_t pos = 0;
+        TABLE_NOISY(LOGI("Starting with set %p, entries=%p, avail=%d\n",
+                     set, entries, set->availAttrs));
+        while (pos < count) {
+            TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
+
+            if ((size_t)curOff > (dtohl(type->header.size)-sizeof(ResTable_map))) {
+                LOGW("ResTable_map at %d is beyond type chunk data %d",
+                     (int)curOff, dtohl(type->header.size));
+                return BAD_TYPE;
+            }
+            map = (const ResTable_map*)(((const uint8_t*)type) + curOff);
+            N++;
+
+            const uint32_t newName = htodl(map->name.ident);
+            bool isInside;
+            uint32_t oldName = 0;
+            while ((isInside=(curEntry < set->numAttrs))
+                    && (oldName=entries[curEntry].map.name.ident) < newName) {
+                TABLE_NOISY(printf("#%d: Keeping existing attribute: 0x%08x\n",
+                             curEntry, entries[curEntry].map.name.ident));
+                curEntry++;
+            }
+
+            if ((!isInside) || oldName != newName) {
+                // This is a new attribute...  figure out what to do with it.
+                if (set->numAttrs >= set->availAttrs) {
+                    // Need to alloc more memory...
+                    const size_t newAvail = set->availAttrs+N;
+                    set = (bag_set*)realloc(set,
+                                            sizeof(bag_set)
+                                            + sizeof(bag_entry)*newAvail);
+                    if (set == NULL) {
+                        return NO_MEMORY;
+                    }
+                    set->availAttrs = newAvail;
+                    entries = (bag_entry*)(set+1);
+                    TABLE_NOISY(printf("Reallocated set %p, entries=%p, avail=%d\n",
+                                 set, entries, set->availAttrs));
+                }
+                if (isInside) {
+                    // Going in the middle, need to make space.
+                    memmove(entries+curEntry+1, entries+curEntry,
+                            sizeof(bag_entry)*(set->numAttrs-curEntry));
+                    set->numAttrs++;
+                }
+                TABLE_NOISY(printf("#%d: Inserting new attribute: 0x%08x\n",
+                             curEntry, newName));
+            } else {
+                TABLE_NOISY(printf("#%d: Replacing existing attribute: 0x%08x\n",
+                             curEntry, oldName));
+            }
+
+            bag_entry* cur = entries+curEntry;
+
+            cur->stringBlock = package->header->index;
+            cur->map.name.ident = newName;
+            cur->map.value.copyFrom_dtoh(map->value);
+            TABLE_NOISY(printf("Setting entry #%d %p: block=%d, name=0x%08x, type=%d, data=0x%08x\n",
+                         curEntry, cur, cur->stringBlock, cur->map.name.ident,
+                         cur->map.value.dataType, cur->map.value.data));
+
+            // On to the next!
+            curEntry++;
+            pos++;
+            const size_t size = dtohs(map->value.size);
+            curOff += size + sizeof(*map)-sizeof(map->value);
+        };
+        if (curEntry > set->numAttrs) {
+            set->numAttrs = curEntry;
+        }
+    }
+
+    // And this is it...
+    typeSet[e] = set;
+    if (set) {
+        if (outTypeSpecFlags != NULL) {
+            *outTypeSpecFlags = set->typeSpecFlags;
+        }
+        *outBag = (bag_entry*)(set+1);
+        TABLE_NOISY(LOGI("Returning %d attrs\n", set->numAttrs));
+        return set->numAttrs;
+    }
+    return BAD_INDEX;
+}
+
+void ResTable::setParameters(const ResTable_config* params)
+{
+    mLock.lock();
+    TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
+                        "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                       params->mcc, params->mnc,
+                       params->language[0] ? params->language[0] : '-',
+                       params->language[1] ? params->language[1] : '-',
+                       params->country[0] ? params->country[0] : '-',
+                       params->country[1] ? params->country[1] : '-',
+                       params->orientation,
+                       params->touchscreen,
+                       params->density,
+                       params->keyboard,
+                       params->inputFlags,
+                       params->navigation,
+                       params->screenWidth,
+                       params->screenHeight));
+    mParams = *params;
+    for (size_t i=0; i<mPackageGroups.size(); i++) {
+        TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i));
+        mPackageGroups[i]->clearBagCache();
+    }
+    mLock.unlock();
+}
+
+void ResTable::getParameters(ResTable_config* params) const
+{
+    mLock.lock();
+    *params = mParams;
+    mLock.unlock();
+}
+
+struct id_name_map {
+    uint32_t id;
+    size_t len;
+    char16_t name[6];
+};
+
+const static id_name_map ID_NAMES[] = {
+    { ResTable_map::ATTR_TYPE,  5, { '^', 't', 'y', 'p', 'e' } },
+    { ResTable_map::ATTR_L10N,  5, { '^', 'l', '1', '0', 'n' } },
+    { ResTable_map::ATTR_MIN,   4, { '^', 'm', 'i', 'n' } },
+    { ResTable_map::ATTR_MAX,   4, { '^', 'm', 'a', 'x' } },
+    { ResTable_map::ATTR_OTHER, 6, { '^', 'o', 't', 'h', 'e', 'r' } },
+    { ResTable_map::ATTR_ZERO,  5, { '^', 'z', 'e', 'r', 'o' } },
+    { ResTable_map::ATTR_ONE,   4, { '^', 'o', 'n', 'e' } },
+    { ResTable_map::ATTR_TWO,   4, { '^', 't', 'w', 'o' } },
+    { ResTable_map::ATTR_FEW,   4, { '^', 'f', 'e', 'w' } },
+    { ResTable_map::ATTR_MANY,  5, { '^', 'm', 'a', 'n', 'y' } },
+};
+
+uint32_t ResTable::identifierForName(const char16_t* name, size_t nameLen,
+                                     const char16_t* type, size_t typeLen,
+                                     const char16_t* package,
+                                     size_t packageLen,
+                                     uint32_t* outTypeSpecFlags) const
+{
+    TABLE_SUPER_NOISY(printf("Identifier for name: error=%d\n", mError));
+
+    // Check for internal resource identifier as the very first thing, so
+    // that we will always find them even when there are no resources.
+    if (name[0] == '^') {
+        const int N = (sizeof(ID_NAMES)/sizeof(ID_NAMES[0]));
+        size_t len;
+        for (int i=0; i<N; i++) {
+            const id_name_map* m = ID_NAMES + i;
+            len = m->len;
+            if (len != nameLen) {
+                continue;
+            }
+            for (size_t j=1; j<len; j++) {
+                if (m->name[j] != name[j]) {
+                    goto nope;
+                }
+            }
+            return m->id;
+nope:
+            ;
+        }
+        if (nameLen > 7) {
+            if (name[1] == 'i' && name[2] == 'n'
+                && name[3] == 'd' && name[4] == 'e' && name[5] == 'x'
+                && name[6] == '_') {
+                int index = atoi(String8(name + 7, nameLen - 7).string());
+                if (Res_CHECKID(index)) {
+                    LOGW("Array resource index: %d is too large.",
+                         index);
+                    return 0;
+                }
+                return  Res_MAKEARRAY(index);
+            }
+        }
+        return 0;
+    }
+
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+
+    // Figure out the package and type we are looking in...
+
+    const char16_t* packageEnd = NULL;
+    const char16_t* typeEnd = NULL;
+    const char16_t* const nameEnd = name+nameLen;
+    const char16_t* p = name;
+    while (p < nameEnd) {
+        if (*p == ':') packageEnd = p;
+        else if (*p == '/') typeEnd = p;
+        p++;
+    }
+    if (*name == '@') name++;
+    if (name >= nameEnd) {
+        return 0;
+    }
+
+    if (packageEnd) {
+        package = name;
+        packageLen = packageEnd-name;
+        name = packageEnd+1;
+    } else if (!package) {
+        return 0;
+    }
+
+    if (typeEnd) {
+        type = name;
+        typeLen = typeEnd-name;
+        name = typeEnd+1;
+    } else if (!type) {
+        return 0;
+    }
+
+    if (name >= nameEnd) {
+        return 0;
+    }
+    nameLen = nameEnd-name;
+
+    TABLE_NOISY(printf("Looking for identifier: type=%s, name=%s, package=%s\n",
+                 String8(type, typeLen).string(),
+                 String8(name, nameLen).string(),
+                 String8(package, packageLen).string()));
+
+    const size_t NG = mPackageGroups.size();
+    for (size_t ig=0; ig<NG; ig++) {
+        const PackageGroup* group = mPackageGroups[ig];
+
+        if (strzcmp16(package, packageLen,
+                      group->name.string(), group->name.size())) {
+            TABLE_NOISY(printf("Skipping package group: %s\n", String8(group->name).string()));
+            continue;
+        }
+
+        const ssize_t ti = group->typeStrings.indexOfString(type, typeLen);
+        if (ti < 0) {
+            TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string()));
+            continue;
+        }
+
+        const ssize_t ei = group->keyStrings.indexOfString(name, nameLen);
+        if (ei < 0) {
+            TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string()));
+            continue;
+        }
+
+        TABLE_NOISY(printf("Search indices: type=%d, name=%d\n", ti, ei));
+
+        const Type* const typeConfigs = group->packages[0]->getType(ti);
+        if (typeConfigs == NULL || typeConfigs->configs.size() <= 0) {
+            TABLE_NOISY(printf("Expected type structure not found in package %s for idnex %d\n",
+                               String8(group->name).string(), ti));
+        }
+        
+        size_t NTC = typeConfigs->configs.size();
+        for (size_t tci=0; tci<NTC; tci++) {
+            const ResTable_type* const ty = typeConfigs->configs[tci];
+            const uint32_t typeOffset = dtohl(ty->entriesStart);
+
+            const uint8_t* const end = ((const uint8_t*)ty) + dtohl(ty->header.size);
+            const uint32_t* const eindex = (const uint32_t*)
+                (((const uint8_t*)ty) + dtohs(ty->header.headerSize));
+
+            const size_t NE = dtohl(ty->entryCount);
+            for (size_t i=0; i<NE; i++) {
+                uint32_t offset = dtohl(eindex[i]);
+                if (offset == ResTable_type::NO_ENTRY) {
+                    continue;
+                }
+                
+                offset += typeOffset;
+                
+                if (offset > (dtohl(ty->header.size)-sizeof(ResTable_entry))) {
+                    LOGW("ResTable_entry at %d is beyond type chunk data %d",
+                         offset, dtohl(ty->header.size));
+                    return 0;
+                }
+                if ((offset&0x3) != 0) {
+                    LOGW("ResTable_entry at %d (pkg=%d type=%d ent=%d) is not on an integer boundary when looking for %s:%s/%s",
+                         (int)offset, (int)group->id, (int)ti+1, (int)i,
+                         String8(package, packageLen).string(),
+                         String8(type, typeLen).string(),
+                         String8(name, nameLen).string());
+                    return 0;
+                }
+                
+                const ResTable_entry* const entry = (const ResTable_entry*)
+                    (((const uint8_t*)ty) + offset);
+                if (dtohs(entry->size) < sizeof(*entry)) {
+                    LOGW("ResTable_entry size %d is too small", dtohs(entry->size));
+                    return BAD_TYPE;
+                }
+
+                TABLE_SUPER_NOISY(printf("Looking at entry #%d: want str %d, have %d\n",
+                                         i, ei, dtohl(entry->key.index)));
+                if (dtohl(entry->key.index) == (size_t)ei) {
+                    if (outTypeSpecFlags) {
+                        *outTypeSpecFlags = typeConfigs->typeSpecFlags[i];
+                    }
+                    return Res_MAKEID(group->id-1, ti, i);
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+bool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen,
+                                 String16* outPackage,
+                                 String16* outType,
+                                 String16* outName,
+                                 const String16* defType,
+                                 const String16* defPackage,
+                                 const char** outErrorMsg)
+{
+    const char16_t* packageEnd = NULL;
+    const char16_t* typeEnd = NULL;
+    const char16_t* p = refStr;
+    const char16_t* const end = p + refLen;
+    while (p < end) {
+        if (*p == ':') packageEnd = p;
+        else if (*p == '/') {
+            typeEnd = p;
+            break;
+        }
+        p++;
+    }
+    p = refStr;
+    if (*p == '@') p++;
+
+    if (packageEnd) {
+        *outPackage = String16(p, packageEnd-p);
+        p = packageEnd+1;
+    } else {
+        if (!defPackage) {
+            if (outErrorMsg) {
+                *outErrorMsg = "No resource package specified";
+            }
+            return false;
+        }
+        *outPackage = *defPackage;
+    }
+    if (typeEnd) {
+        *outType = String16(p, typeEnd-p);
+        p = typeEnd+1;
+    } else {
+        if (!defType) {
+            if (outErrorMsg) {
+                *outErrorMsg = "No resource type specified";
+            }
+            return false;
+        }
+        *outType = *defType;
+    }
+    *outName = String16(p, end-p);
+    return true;
+}
+
+static uint32_t get_hex(char c, bool* outError)
+{
+    if (c >= '0' && c <= '9') {
+        return c - '0';
+    } else if (c >= 'a' && c <= 'f') {
+        return c - 'a' + 0xa;
+    } else if (c >= 'A' && c <= 'F') {
+        return c - 'A' + 0xa;
+    }
+    *outError = true;
+    return 0;
+}
+
+struct unit_entry
+{
+    const char* name;
+    size_t len;
+    uint8_t type;
+    uint32_t unit;
+    float scale;
+};
+
+static const unit_entry unitNames[] = {
+    { "px", strlen("px"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PX, 1.0f },
+    { "dip", strlen("dip"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
+    { "dp", strlen("dp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_DIP, 1.0f },
+    { "sp", strlen("sp"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_SP, 1.0f },
+    { "pt", strlen("pt"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_PT, 1.0f },
+    { "in", strlen("in"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_IN, 1.0f },
+    { "mm", strlen("mm"), Res_value::TYPE_DIMENSION, Res_value::COMPLEX_UNIT_MM, 1.0f },
+    { "%", strlen("%"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION, 1.0f/100 },
+    { "%p", strlen("%p"), Res_value::TYPE_FRACTION, Res_value::COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100 },
+    { NULL, 0, 0, 0, 0 }
+};
+
+static bool parse_unit(const char* str, Res_value* outValue,
+                       float* outScale, const char** outEnd)
+{
+    const char* end = str;
+    while (*end != 0 && !isspace((unsigned char)*end)) {
+        end++;
+    }
+    const size_t len = end-str;
+
+    const char* realEnd = end;
+    while (*realEnd != 0 && isspace((unsigned char)*realEnd)) {
+        realEnd++;
+    }
+    if (*realEnd != 0) {
+        return false;
+    }
+    
+    const unit_entry* cur = unitNames;
+    while (cur->name) {
+        if (len == cur->len && strncmp(cur->name, str, len) == 0) {
+            outValue->dataType = cur->type;
+            outValue->data = cur->unit << Res_value::COMPLEX_UNIT_SHIFT;
+            *outScale = cur->scale;
+            *outEnd = end;
+            //printf("Found unit %s for %s\n", cur->name, str);
+            return true;
+        }
+        cur++;
+    }
+
+    return false;
+}
+
+
+bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue)
+{
+    while (len > 0 && isspace16(*s)) {
+        s++;
+        len--;
+    }
+
+    if (len <= 0) {
+        return false;
+    }
+
+    size_t i = 0;
+    int32_t val = 0;
+    bool neg = false;
+
+    if (*s == '-') {
+        neg = true;
+        i++;
+    }
+
+    if (s[i] < '0' || s[i] > '9') {
+        return false;
+    }
+
+    // Decimal or hex?
+    if (s[i] == '0' && s[i+1] == 'x') {
+        if (outValue)
+            outValue->dataType = outValue->TYPE_INT_HEX;
+        i += 2;
+        bool error = false;
+        while (i < len && !error) {
+            val = (val*16) + get_hex(s[i], &error);
+            i++;
+        }
+        if (error) {
+            return false;
+        }
+    } else {
+        if (outValue)
+            outValue->dataType = outValue->TYPE_INT_DEC;
+        while (i < len) {
+            if (s[i] < '0' || s[i] > '9') {
+                return false;
+            }
+            val = (val*10) + s[i]-'0';
+            i++;
+        }
+    }
+
+    if (neg) val = -val;
+
+    while (i < len && isspace16(s[i])) {
+        i++;
+    }
+
+    if (i == len) {
+        if (outValue)
+            outValue->data = val;
+        return true;
+    }
+
+    return false;
+}
+
+bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue)
+{
+    while (len > 0 && isspace16(*s)) {
+        s++;
+        len--;
+    }
+
+    if (len <= 0) {
+        return false;
+    }
+
+    char buf[128];
+    int i=0;
+    while (len > 0 && *s != 0 && i < 126) {
+        if (*s > 255) {
+            return false;
+        }
+        buf[i++] = *s++;
+        len--;
+    }
+
+    if (len > 0) {
+        return false;
+    }
+    if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
+        return false;
+    }
+
+    buf[i] = 0;
+    const char* end;
+    float f = strtof(buf, (char**)&end);
+
+    if (*end != 0 && !isspace((unsigned char)*end)) {
+        // Might be a unit...
+        float scale;
+        if (parse_unit(end, outValue, &scale, &end)) {
+            f *= scale;
+            const bool neg = f < 0;
+            if (neg) f = -f;
+            uint64_t bits = (uint64_t)(f*(1<<23)+.5f);
+            uint32_t radix;
+            uint32_t shift;
+            if ((bits&0x7fffff) == 0) {
+                // Always use 23p0 if there is no fraction, just to make
+                // things easier to read.
+                radix = Res_value::COMPLEX_RADIX_23p0;
+                shift = 23;
+            } else if ((bits&0xffffffffff800000LL) == 0) {
+                // Magnitude is zero -- can fit in 0 bits of precision.
+                radix = Res_value::COMPLEX_RADIX_0p23;
+                shift = 0;
+            } else if ((bits&0xffffffff80000000LL) == 0) {
+                // Magnitude can fit in 8 bits of precision.
+                radix = Res_value::COMPLEX_RADIX_8p15;
+                shift = 8;
+            } else if ((bits&0xffffff8000000000LL) == 0) {
+                // Magnitude can fit in 16 bits of precision.
+                radix = Res_value::COMPLEX_RADIX_16p7;
+                shift = 16;
+            } else {
+                // Magnitude needs entire range, so no fractional part.
+                radix = Res_value::COMPLEX_RADIX_23p0;
+                shift = 23;
+            }
+            int32_t mantissa = (int32_t)(
+                (bits>>shift) & Res_value::COMPLEX_MANTISSA_MASK);
+            if (neg) {
+                mantissa = (-mantissa) & Res_value::COMPLEX_MANTISSA_MASK;
+            }
+            outValue->data |= 
+                (radix<<Res_value::COMPLEX_RADIX_SHIFT)
+                | (mantissa<<Res_value::COMPLEX_MANTISSA_SHIFT);
+            //printf("Input value: %f 0x%016Lx, mult: %f, radix: %d, shift: %d, final: 0x%08x\n",
+            //       f * (neg ? -1 : 1), bits, f*(1<<23),
+            //       radix, shift, outValue->data);
+            return true;
+        }
+        return false;
+    }
+
+    while (*end != 0 && isspace((unsigned char)*end)) {
+        end++;
+    }
+
+    if (*end == 0) {
+        if (outValue) {
+            outValue->dataType = outValue->TYPE_FLOAT;
+            *(float*)(&outValue->data) = f;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool ResTable::stringToValue(Res_value* outValue, String16* outString,
+                             const char16_t* s, size_t len,
+                             bool preserveSpaces, bool coerceType,
+                             uint32_t attrID,
+                             const String16* defType,
+                             const String16* defPackage,
+                             Accessor* accessor,
+                             void* accessorCookie,
+                             uint32_t attrType,
+                             bool enforcePrivate) const
+{
+    bool localizationSetting = accessor != NULL && accessor->getLocalizationSetting();
+    const char* errorMsg = NULL;
+
+    outValue->size = sizeof(Res_value);
+    outValue->res0 = 0;
+
+    // First strip leading/trailing whitespace.  Do this before handling
+    // escapes, so they can be used to force whitespace into the string.
+    if (!preserveSpaces) {
+        while (len > 0 && isspace16(*s)) {
+            s++;
+            len--;
+        }
+        while (len > 0 && isspace16(s[len-1])) {
+            len--;
+        }
+        // If the string ends with '\', then we keep the space after it.
+        if (len > 0 && s[len-1] == '\\' && s[len] != 0) {
+            len++;
+        }
+    }
+
+    //printf("Value for: %s\n", String8(s, len).string());
+
+    uint32_t l10nReq = ResTable_map::L10N_NOT_REQUIRED;
+    uint32_t attrMin = 0x80000000, attrMax = 0x7fffffff;
+    bool fromAccessor = false;
+    if (attrID != 0 && !Res_INTERNALID(attrID)) {
+        const ssize_t p = getResourcePackageIndex(attrID);
+        const bag_entry* bag;
+        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
+        //printf("For attr 0x%08x got bag of %d\n", attrID, cnt);
+        if (cnt >= 0) {
+            while (cnt > 0) {
+                //printf("Entry 0x%08x = 0x%08x\n", bag->map.name.ident, bag->map.value.data);
+                switch (bag->map.name.ident) {
+                case ResTable_map::ATTR_TYPE:
+                    attrType = bag->map.value.data;
+                    break;
+                case ResTable_map::ATTR_MIN:
+                    attrMin = bag->map.value.data;
+                    break;
+                case ResTable_map::ATTR_MAX:
+                    attrMax = bag->map.value.data;
+                    break;
+                case ResTable_map::ATTR_L10N:
+                    l10nReq = bag->map.value.data;
+                    break;
+                }
+                bag++;
+                cnt--;
+            }
+            unlockBag(bag);
+        } else if (accessor && accessor->getAttributeType(attrID, &attrType)) {
+            fromAccessor = true;
+            if (attrType == ResTable_map::TYPE_ENUM
+                    || attrType == ResTable_map::TYPE_FLAGS
+                    || attrType == ResTable_map::TYPE_INTEGER) {
+                accessor->getAttributeMin(attrID, &attrMin);
+                accessor->getAttributeMax(attrID, &attrMax);
+            }
+            if (localizationSetting) {
+                l10nReq = accessor->getAttributeL10N(attrID);
+            }
+        }
+    }
+
+    const bool canStringCoerce =
+        coerceType && (attrType&ResTable_map::TYPE_STRING) != 0;
+
+    if (*s == '@') {
+        outValue->dataType = outValue->TYPE_REFERENCE;
+
+        // Note: we don't check attrType here because the reference can
+        // be to any other type; we just need to count on the client making
+        // sure the referenced type is correct.
+        
+        //printf("Looking up ref: %s\n", String8(s, len).string());
+
+        // It's a reference!
+        if (len == 5 && s[1]=='n' && s[2]=='u' && s[3]=='l' && s[4]=='l') {
+            outValue->data = 0;
+            return true;
+        } else {
+            bool createIfNotFound = false;
+            const char16_t* resourceRefName;
+            int resourceNameLen;
+            if (len > 2 && s[1] == '+') {
+                createIfNotFound = true;
+                resourceRefName = s + 2;
+                resourceNameLen = len - 2;
+            } else if (len > 2 && s[1] == '*') {
+                enforcePrivate = false;
+                resourceRefName = s + 2;
+                resourceNameLen = len - 2;
+            } else {
+                createIfNotFound = false;
+                resourceRefName = s + 1;
+                resourceNameLen = len - 1;
+            }
+            String16 package, type, name;
+            if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name,
+                                   defType, defPackage, &errorMsg)) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, errorMsg);
+                }
+                return false;
+            }
+
+            uint32_t specFlags = 0;
+            uint32_t rid = identifierForName(name.string(), name.size(), type.string(),
+                    type.size(), package.string(), package.size(), &specFlags);
+            if (rid != 0) {
+                if (enforcePrivate) {
+                    if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
+                        if (accessor != NULL) {
+                            accessor->reportError(accessorCookie, "Resource is not public.");
+                        }
+                        return false;
+                    }
+                }
+                if (!accessor) {
+                    outValue->data = rid;
+                    return true;
+                }
+                rid = Res_MAKEID(
+                    accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
+                    Res_GETTYPE(rid), Res_GETENTRY(rid));
+                TABLE_NOISY(printf("Incl %s:%s/%s: 0x%08x\n",
+                       String8(package).string(), String8(type).string(),
+                       String8(name).string(), rid));
+                outValue->data = rid;
+                return true;
+            }
+
+            if (accessor) {
+                uint32_t rid = accessor->getCustomResourceWithCreation(package, type, name,
+                                                                       createIfNotFound);
+                if (rid != 0) {
+                    TABLE_NOISY(printf("Pckg %s:%s/%s: 0x%08x\n",
+                           String8(package).string(), String8(type).string(),
+                           String8(name).string(), rid));
+                    outValue->data = rid;
+                    return true;
+                }
+            }
+        }
+
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, "No resource found that matches the given name");
+        }
+        return false;
+    }
+
+    // if we got to here, and localization is required and it's not a reference,
+    // complain and bail.
+    if (l10nReq == ResTable_map::L10N_SUGGESTED) {
+        if (localizationSetting) {
+            if (accessor != NULL) {
+                accessor->reportError(accessorCookie, "This attribute must be localized.");
+            }
+        }
+    }
+    
+    if (*s == '#') {
+        // It's a color!  Convert to an integer of the form 0xaarrggbb.
+        uint32_t color = 0;
+        bool error = false;
+        if (len == 4) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_RGB4;
+            color |= 0xFF000000;
+            color |= get_hex(s[1], &error) << 20;
+            color |= get_hex(s[1], &error) << 16;
+            color |= get_hex(s[2], &error) << 12;
+            color |= get_hex(s[2], &error) << 8;
+            color |= get_hex(s[3], &error) << 4;
+            color |= get_hex(s[3], &error);
+        } else if (len == 5) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB4;
+            color |= get_hex(s[1], &error) << 28;
+            color |= get_hex(s[1], &error) << 24;
+            color |= get_hex(s[2], &error) << 20;
+            color |= get_hex(s[2], &error) << 16;
+            color |= get_hex(s[3], &error) << 12;
+            color |= get_hex(s[3], &error) << 8;
+            color |= get_hex(s[4], &error) << 4;
+            color |= get_hex(s[4], &error);
+        } else if (len == 7) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_RGB8;
+            color |= 0xFF000000;
+            color |= get_hex(s[1], &error) << 20;
+            color |= get_hex(s[2], &error) << 16;
+            color |= get_hex(s[3], &error) << 12;
+            color |= get_hex(s[4], &error) << 8;
+            color |= get_hex(s[5], &error) << 4;
+            color |= get_hex(s[6], &error);
+        } else if (len == 9) {
+            outValue->dataType = outValue->TYPE_INT_COLOR_ARGB8;
+            color |= get_hex(s[1], &error) << 28;
+            color |= get_hex(s[2], &error) << 24;
+            color |= get_hex(s[3], &error) << 20;
+            color |= get_hex(s[4], &error) << 16;
+            color |= get_hex(s[5], &error) << 12;
+            color |= get_hex(s[6], &error) << 8;
+            color |= get_hex(s[7], &error) << 4;
+            color |= get_hex(s[8], &error);
+        } else {
+            error = true;
+        }
+        if (!error) {
+            if ((attrType&ResTable_map::TYPE_COLOR) == 0) {
+                if (!canStringCoerce) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie,
+                                "Color types not allowed");
+                    }
+                    return false;
+                }
+            } else {
+                outValue->data = color;
+                //printf("Color input=%s, output=0x%x\n", String8(s, len).string(), color);
+                return true;
+            }
+        } else {
+            if ((attrType&ResTable_map::TYPE_COLOR) != 0) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Color value not valid --"
+                            " must be #rgb, #argb, #rrggbb, or #aarrggbb");
+                }
+                #if 0
+                fprintf(stderr, "%s: Color ID %s value %s is not valid\n",
+                        "Resource File", //(const char*)in->getPrintableSource(),
+                        String8(*curTag).string(),
+                        String8(s, len).string());
+                #endif
+                return false;
+            }
+        }
+    }
+
+    if (*s == '?') {
+        outValue->dataType = outValue->TYPE_ATTRIBUTE;
+
+        // Note: we don't check attrType here because the reference can
+        // be to any other type; we just need to count on the client making
+        // sure the referenced type is correct.
+
+        //printf("Looking up attr: %s\n", String8(s, len).string());
+
+        static const String16 attr16("attr");
+        String16 package, type, name;
+        if (!expandResourceRef(s+1, len-1, &package, &type, &name,
+                               &attr16, defPackage, &errorMsg)) {
+            if (accessor != NULL) {
+                accessor->reportError(accessorCookie, errorMsg);
+            }
+            return false;
+        }
+
+        //printf("Pkg: %s, Type: %s, Name: %s\n",
+        //       String8(package).string(), String8(type).string(),
+        //       String8(name).string());
+        uint32_t specFlags = 0;
+        uint32_t rid = 
+            identifierForName(name.string(), name.size(),
+                              type.string(), type.size(),
+                              package.string(), package.size(), &specFlags);
+        if (rid != 0) {
+            if (enforcePrivate) {
+                if ((specFlags&ResTable_typeSpec::SPEC_PUBLIC) == 0) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie, "Attribute is not public.");
+                    }
+                    return false;
+                }
+            }
+            if (!accessor) {
+                outValue->data = rid;
+                return true;
+            }
+            rid = Res_MAKEID(
+                accessor->getRemappedPackage(Res_GETPACKAGE(rid)),
+                Res_GETTYPE(rid), Res_GETENTRY(rid));
+            //printf("Incl %s:%s/%s: 0x%08x\n",
+            //       String8(package).string(), String8(type).string(),
+            //       String8(name).string(), rid);
+            outValue->data = rid;
+            return true;
+        }
+
+        if (accessor) {
+            uint32_t rid = accessor->getCustomResource(package, type, name);
+            if (rid != 0) {
+                //printf("Mine %s:%s/%s: 0x%08x\n",
+                //       String8(package).string(), String8(type).string(),
+                //       String8(name).string(), rid);
+                outValue->data = rid;
+                return true;
+            }
+        }
+
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, "No resource found that matches the given name");
+        }
+        return false;
+    }
+
+    if (stringToInt(s, len, outValue)) {
+        if ((attrType&ResTable_map::TYPE_INTEGER) == 0) {
+            // If this type does not allow integers, but does allow floats,
+            // fall through on this error case because the float type should
+            // be able to accept any integer value.
+            if (!canStringCoerce && (attrType&ResTable_map::TYPE_FLOAT) == 0) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Integer types not allowed");
+                }
+                return false;
+            }
+        } else {
+            if (((int32_t)outValue->data) < ((int32_t)attrMin)
+                    || ((int32_t)outValue->data) > ((int32_t)attrMax)) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Integer value out of range");
+                }
+                return false;
+            }
+            return true;
+        }
+    }
+
+    if (stringToFloat(s, len, outValue)) {
+        if (outValue->dataType == Res_value::TYPE_DIMENSION) {
+            if ((attrType&ResTable_map::TYPE_DIMENSION) != 0) {
+                return true;
+            }
+            if (!canStringCoerce) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Dimension types not allowed");
+                }
+                return false;
+            }
+        } else if (outValue->dataType == Res_value::TYPE_FRACTION) {
+            if ((attrType&ResTable_map::TYPE_FRACTION) != 0) {
+                return true;
+            }
+            if (!canStringCoerce) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Fraction types not allowed");
+                }
+                return false;
+            }
+        } else if ((attrType&ResTable_map::TYPE_FLOAT) == 0) {
+            if (!canStringCoerce) {
+                if (accessor != NULL) {
+                    accessor->reportError(accessorCookie, "Float types not allowed");
+                }
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+
+    if (len == 4) {
+        if ((s[0] == 't' || s[0] == 'T') &&
+            (s[1] == 'r' || s[1] == 'R') &&
+            (s[2] == 'u' || s[2] == 'U') &&
+            (s[3] == 'e' || s[3] == 'E')) {
+            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
+                if (!canStringCoerce) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie, "Boolean types not allowed");
+                    }
+                    return false;
+                }
+            } else {
+                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
+                outValue->data = (uint32_t)-1;
+                return true;
+            }
+        }
+    }
+
+    if (len == 5) {
+        if ((s[0] == 'f' || s[0] == 'F') &&
+            (s[1] == 'a' || s[1] == 'A') &&
+            (s[2] == 'l' || s[2] == 'L') &&
+            (s[3] == 's' || s[3] == 'S') &&
+            (s[4] == 'e' || s[4] == 'E')) {
+            if ((attrType&ResTable_map::TYPE_BOOLEAN) == 0) {
+                if (!canStringCoerce) {
+                    if (accessor != NULL) {
+                        accessor->reportError(accessorCookie, "Boolean types not allowed");
+                    }
+                    return false;
+                }
+            } else {
+                outValue->dataType = outValue->TYPE_INT_BOOLEAN;
+                outValue->data = 0;
+                return true;
+            }
+        }
+    }
+
+    if ((attrType&ResTable_map::TYPE_ENUM) != 0) {
+        const ssize_t p = getResourcePackageIndex(attrID);
+        const bag_entry* bag;
+        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
+        //printf("Got %d for enum\n", cnt);
+        if (cnt >= 0) {
+            resource_name rname;
+            while (cnt > 0) {
+                if (!Res_INTERNALID(bag->map.name.ident)) {
+                    //printf("Trying attr #%08x\n", bag->map.name.ident);
+                    if (getResourceName(bag->map.name.ident, &rname)) {
+                        #if 0
+                        printf("Matching %s against %s (0x%08x)\n",
+                               String8(s, len).string(),
+                               String8(rname.name, rname.nameLen).string(),
+                               bag->map.name.ident);
+                        #endif
+                        if (strzcmp16(s, len, rname.name, rname.nameLen) == 0) {
+                            outValue->dataType = bag->map.value.dataType;
+                            outValue->data = bag->map.value.data;
+                            unlockBag(bag);
+                            return true;
+                        }
+                    }
+    
+                }
+                bag++;
+                cnt--;
+            }
+            unlockBag(bag);
+        }
+
+        if (fromAccessor) {
+            if (accessor->getAttributeEnum(attrID, s, len, outValue)) {
+                return true;
+            }
+        }
+    }
+
+    if ((attrType&ResTable_map::TYPE_FLAGS) != 0) {
+        const ssize_t p = getResourcePackageIndex(attrID);
+        const bag_entry* bag;
+        ssize_t cnt = p >= 0 ? lockBag(attrID, &bag) : -1;
+        //printf("Got %d for flags\n", cnt);
+        if (cnt >= 0) {
+            bool failed = false;
+            resource_name rname;
+            outValue->dataType = Res_value::TYPE_INT_HEX;
+            outValue->data = 0;
+            const char16_t* end = s + len;
+            const char16_t* pos = s;
+            while (pos < end && !failed) {
+                const char16_t* start = pos;
+                end++;
+                while (pos < end && *pos != '|') {
+                    pos++;
+                }
+				//printf("Looking for: %s\n", String8(start, pos-start).string());
+                const bag_entry* bagi = bag;
+				ssize_t i;
+                for (i=0; i<cnt; i++, bagi++) {
+                    if (!Res_INTERNALID(bagi->map.name.ident)) {
+                        //printf("Trying attr #%08x\n", bagi->map.name.ident);
+                        if (getResourceName(bagi->map.name.ident, &rname)) {
+                            #if 0
+                            printf("Matching %s against %s (0x%08x)\n",
+                                   String8(start,pos-start).string(),
+                                   String8(rname.name, rname.nameLen).string(),
+                                   bagi->map.name.ident);
+                            #endif
+                            if (strzcmp16(start, pos-start, rname.name, rname.nameLen) == 0) {
+                                outValue->data |= bagi->map.value.data;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (i >= cnt) {
+                    // Didn't find this flag identifier.
+                    failed = true;
+                }
+                if (pos < end) {
+                    pos++;
+                }
+            }
+            unlockBag(bag);
+            if (!failed) {
+				//printf("Final flag value: 0x%lx\n", outValue->data);
+                return true;
+            }
+        }
+
+
+        if (fromAccessor) {
+            if (accessor->getAttributeFlags(attrID, s, len, outValue)) {
+				//printf("Final flag value: 0x%lx\n", outValue->data);
+                return true;
+            }
+        }
+    }
+
+    if ((attrType&ResTable_map::TYPE_STRING) == 0) {
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, "String types not allowed");
+        }
+        return false;
+    }
+
+    // Generic string handling...
+    outValue->dataType = outValue->TYPE_STRING;
+    if (outString) {
+        bool failed = collectString(outString, s, len, preserveSpaces, &errorMsg);
+        if (accessor != NULL) {
+            accessor->reportError(accessorCookie, errorMsg);
+        }
+        return failed;
+    }
+
+    return true;
+}
+
+bool ResTable::collectString(String16* outString,
+                             const char16_t* s, size_t len,
+                             bool preserveSpaces,
+                             const char** outErrorMsg,
+                             bool append)
+{
+    String16 tmp;
+
+    char quoted = 0;
+    const char16_t* p = s;
+    while (p < (s+len)) {
+        while (p < (s+len)) {
+            const char16_t c = *p;
+            if (c == '\\') {
+                break;
+            }
+            if (!preserveSpaces) {
+                if (quoted == 0 && isspace16(c)
+                    && (c != ' ' || isspace16(*(p+1)))) {
+                    break;
+                }
+                if (c == '"' && (quoted == 0 || quoted == '"')) {
+                    break;
+                }
+                if (c == '\'' && (quoted == 0 || quoted == '\'')) {
+                    break;
+                }
+            }
+            p++;
+        }
+        if (p < (s+len)) {
+            if (p > s) {
+                tmp.append(String16(s, p-s));
+            }
+            if (!preserveSpaces && (*p == '"' || *p == '\'')) {
+                if (quoted == 0) {
+                    quoted = *p;
+                } else {
+                    quoted = 0;
+                }
+                p++;
+            } else if (!preserveSpaces && isspace16(*p)) {
+                // Space outside of a quote -- consume all spaces and
+                // leave a single plain space char.
+                tmp.append(String16(" "));
+                p++;
+                while (p < (s+len) && isspace16(*p)) {
+                    p++;
+                }
+            } else if (*p == '\\') {
+                p++;
+                if (p < (s+len)) {
+                    switch (*p) {
+                    case 't':
+                        tmp.append(String16("\t"));
+                        break;
+                    case 'n':
+                        tmp.append(String16("\n"));
+                        break;
+                    case '#':
+                        tmp.append(String16("#"));
+                        break;
+                    case '@':
+                        tmp.append(String16("@"));
+                        break;
+                    case '?':
+                        tmp.append(String16("?"));
+                        break;
+                    case '"':
+                        tmp.append(String16("\""));
+                        break;
+                    case '\'':
+                        tmp.append(String16("'"));
+                        break;
+                    case '\\':
+                        tmp.append(String16("\\"));
+                        break;
+                    case 'u':
+                    {
+                        char16_t chr = 0;
+                        int i = 0;
+                        while (i < 4 && p[1] != 0) {
+                            p++;
+                            i++;
+                            int c;
+                            if (*p >= '0' && *p <= '9') {
+                                c = *p - '0';
+                            } else if (*p >= 'a' && *p <= 'f') {
+                                c = *p - 'a' + 10;
+                            } else if (*p >= 'A' && *p <= 'F') {
+                                c = *p - 'A' + 10;
+                            } else {
+                                if (outErrorMsg) {
+                                    *outErrorMsg = "Bad character in \\u unicode escape sequence";
+                                }
+                                return false;
+                            }
+                            chr = (chr<<4) | c;
+                        }
+                        tmp.append(String16(&chr, 1));
+                    } break;
+                    default:
+                        // ignore unknown escape chars.
+                        break;
+                    }
+                    p++;
+                }
+            }
+            len -= (p-s);
+            s = p;
+        }
+    }
+
+    if (tmp.size() != 0) {
+        if (len > 0) {
+            tmp.append(String16(s, len));
+        }
+        if (append) {
+            outString->append(tmp);
+        } else {
+            outString->setTo(tmp);
+        }
+    } else {
+        if (append) {
+            outString->append(String16(s, len));
+        } else {
+            outString->setTo(s, len);
+        }
+    }
+
+    return true;
+}
+
+size_t ResTable::getBasePackageCount() const
+{
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+    return mPackageGroups.size();
+}
+
+const char16_t* ResTable::getBasePackageName(size_t idx) const
+{
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+    LOG_FATAL_IF(idx >= mPackageGroups.size(),
+                 "Requested package index %d past package count %d",
+                 (int)idx, (int)mPackageGroups.size());
+    return mPackageGroups[idx]->name.string();
+}
+
+uint32_t ResTable::getBasePackageId(size_t idx) const
+{
+    if (mError != NO_ERROR) {
+        return 0;
+    }
+    LOG_FATAL_IF(idx >= mPackageGroups.size(),
+                 "Requested package index %d past package count %d",
+                 (int)idx, (int)mPackageGroups.size());
+    return mPackageGroups[idx]->id;
+}
+
+size_t ResTable::getTableCount() const
+{
+    return mHeaders.size();
+}
+
+const ResStringPool* ResTable::getTableStringBlock(size_t index) const
+{
+    return &mHeaders[index]->values;
+}
+
+void* ResTable::getTableCookie(size_t index) const
+{
+    return mHeaders[index]->cookie;
+}
+
+void ResTable::getConfigurations(Vector<ResTable_config>* configs) const
+{
+    const size_t I = mPackageGroups.size();
+    for (size_t i=0; i<I; i++) {
+        const PackageGroup* packageGroup = mPackageGroups[i];
+        const size_t J = packageGroup->packages.size();
+        for (size_t j=0; j<J; j++) {
+            const Package* package = packageGroup->packages[j];
+            const size_t K = package->types.size();
+            for (size_t k=0; k<K; k++) {
+                const Type* type = package->types[k];
+                if (type == NULL) continue;
+                const size_t L = type->configs.size();
+                for (size_t l=0; l<L; l++) {
+                    const ResTable_type* config = type->configs[l];
+                    const ResTable_config* cfg = &config->config;
+                    // only insert unique
+                    const size_t M = configs->size();
+                    size_t m;
+                    for (m=0; m<M; m++) {
+                        if (0 == (*configs)[m].compare(*cfg)) {
+                            break;
+                        }
+                    }
+                    // if we didn't find it
+                    if (m == M) {
+                        configs->add(*cfg);
+                    }
+                }
+            }
+        }
+    }
+}
+
+void ResTable::getLocales(Vector<String8>* locales) const
+{
+    Vector<ResTable_config> configs;
+    LOGD("calling getConfigurations");
+    getConfigurations(&configs);
+    LOGD("called getConfigurations size=%d", (int)configs.size());
+    const size_t I = configs.size();
+    for (size_t i=0; i<I; i++) {
+        char locale[6];
+        configs[i].getLocale(locale);
+        const size_t J = locales->size();
+        size_t j;
+        for (j=0; j<J; j++) {
+            if (0 == strcmp(locale, (*locales)[j].string())) {
+                break;
+            }
+        }
+        if (j == J) {
+            locales->add(String8(locale));
+        }
+    }
+}
+
+ssize_t ResTable::getEntry(
+    const Package* package, int typeIndex, int entryIndex,
+    const ResTable_config* config,
+    const ResTable_type** outType, const ResTable_entry** outEntry,
+    const Type** outTypeClass) const
+{
+    LOGV("Getting entry from package %p\n", package);
+    const ResTable_package* const pkg = package->package;
+
+    const Type* allTypes = package->getType(typeIndex);
+    LOGV("allTypes=%p\n", allTypes);
+    if (allTypes == NULL) {
+        LOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);
+        return 0;
+    }
+
+    if ((size_t)entryIndex >= allTypes->entryCount) {
+        LOGW("getEntry failing because entryIndex %d is beyond type entryCount %d",
+            entryIndex, (int)allTypes->entryCount);
+        return BAD_TYPE;
+    }
+        
+    const ResTable_type* type = NULL;
+    uint32_t offset = ResTable_type::NO_ENTRY;
+    ResTable_config bestConfig;
+    memset(&bestConfig, 0, sizeof(bestConfig)); // make the compiler shut up
+    
+    const size_t NT = allTypes->configs.size();
+    for (size_t i=0; i<NT; i++) {
+        const ResTable_type* const thisType = allTypes->configs[i];
+        if (thisType == NULL) continue;
+        
+        ResTable_config thisConfig;
+        thisConfig.copyFromDtoH(thisType->config);
+        
+        TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d lang:%c%c=%c%c cnt:%c%c=%c%c "
+                            "orien:%d=%d touch:%d=%d density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d\n",
+                           entryIndex, typeIndex+1, dtohl(thisType->config.size),
+                           thisConfig.mcc, thisConfig.mnc,
+                           config ? config->mcc : 0, config ? config->mnc : 0,
+                           thisConfig.language[0] ? thisConfig.language[0] : '-',
+                           thisConfig.language[1] ? thisConfig.language[1] : '-',
+                           config && config->language[0] ? config->language[0] : '-',
+                           config && config->language[1] ? config->language[1] : '-',
+                           thisConfig.country[0] ? thisConfig.country[0] : '-',
+                           thisConfig.country[1] ? thisConfig.country[1] : '-',
+                           config && config->country[0] ? config->country[0] : '-',
+                           config && config->country[1] ? config->country[1] : '-',
+                           thisConfig.orientation,
+                           config ? config->orientation : 0,
+                           thisConfig.touchscreen,
+                           config ? config->touchscreen : 0,
+                           thisConfig.density,
+                           config ? config->density : 0,
+                           thisConfig.keyboard,
+                           config ? config->keyboard : 0,
+                           thisConfig.inputFlags,
+                           config ? config->inputFlags : 0,
+                           thisConfig.navigation,
+                           config ? config->navigation : 0,
+                           thisConfig.screenWidth,
+                           config ? config->screenWidth : 0,
+                           thisConfig.screenHeight,
+                           config ? config->screenHeight : 0));
+        
+        // Check to make sure this one is valid for the current parameters.
+        if (config && !thisConfig.match(*config)) {
+            TABLE_GETENTRY(LOGI("Does not match config!\n"));
+            continue;
+        }
+        
+        // Check if there is the desired entry in this type.
+        
+        const uint8_t* const end = ((const uint8_t*)thisType)
+            + dtohl(thisType->header.size);
+        const uint32_t* const eindex = (const uint32_t*)
+            (((const uint8_t*)thisType) + dtohs(thisType->header.headerSize));
+        
+        uint32_t thisOffset = dtohl(eindex[entryIndex]);
+        if (thisOffset == ResTable_type::NO_ENTRY) {
+            TABLE_GETENTRY(LOGI("Skipping because it is not defined!\n"));
+            continue;
+        }
+        
+        if (type != NULL) {
+            // Check if this one is less specific than the last found.  If so,
+            // we will skip it.  We check starting with things we most care
+            // about to those we least care about.
+            if (!thisConfig.isBetterThan(bestConfig, config)) {
+                TABLE_GETENTRY(LOGI("This config is worse than last!\n"));
+                continue;
+            }
+        }
+        
+        type = thisType;
+        offset = thisOffset;
+        bestConfig = thisConfig;
+        TABLE_GETENTRY(LOGI("Best entry so far -- using it!\n"));
+        if (!config) break;
+    }
+    
+    if (type == NULL) {
+        TABLE_GETENTRY(LOGI("No value found for requested entry!\n"));
+        return BAD_INDEX;
+    }
+    
+    offset += dtohl(type->entriesStart);
+    TABLE_NOISY(aout << "Looking in resource table " << package->header->header
+          << ", typeOff="
+          << (void*)(((const char*)type)-((const char*)package->header->header))
+          << ", offset=" << (void*)offset << endl);
+
+    if (offset > (dtohl(type->header.size)-sizeof(ResTable_entry))) {
+        LOGW("ResTable_entry at 0x%x is beyond type chunk data 0x%x",
+             offset, dtohl(type->header.size));
+        return BAD_TYPE;
+    }
+    if ((offset&0x3) != 0) {
+        LOGW("ResTable_entry at 0x%x is not on an integer boundary",
+             offset);
+        return BAD_TYPE;
+    }
+
+    const ResTable_entry* const entry = (const ResTable_entry*)
+        (((const uint8_t*)type) + offset);
+    if (dtohs(entry->size) < sizeof(*entry)) {
+        LOGW("ResTable_entry size 0x%x is too small", dtohs(entry->size));
+        return BAD_TYPE;
+    }
+
+    *outType = type;
+    *outEntry = entry;
+    if (outTypeClass != NULL) {
+        *outTypeClass = allTypes;
+    }
+    return offset + dtohs(entry->size);
+}
+
+status_t ResTable::parsePackage(const ResTable_package* const pkg,
+                                const Header* const header)
+{
+    const uint8_t* base = (const uint8_t*)pkg;
+    status_t err = validate_chunk(&pkg->header, sizeof(*pkg),
+                                  header->dataEnd, "ResTable_package");
+    if (err != NO_ERROR) {
+        return (mError=err);
+    }
+
+    const size_t pkgSize = dtohl(pkg->header.size);
+
+    if (dtohl(pkg->typeStrings) >= pkgSize) {
+        LOGW("ResTable_package type strings at %p are past chunk size %p.",
+             (void*)dtohl(pkg->typeStrings), (void*)pkgSize);
+        return (mError=BAD_TYPE);
+    }
+    if ((dtohl(pkg->typeStrings)&0x3) != 0) {
+        LOGW("ResTable_package type strings at %p is not on an integer boundary.",
+             (void*)dtohl(pkg->typeStrings));
+        return (mError=BAD_TYPE);
+    }
+    if (dtohl(pkg->keyStrings) >= pkgSize) {
+        LOGW("ResTable_package key strings at %p are past chunk size %p.",
+             (void*)dtohl(pkg->keyStrings), (void*)pkgSize);
+        return (mError=BAD_TYPE);
+    }
+    if ((dtohl(pkg->keyStrings)&0x3) != 0) {
+        LOGW("ResTable_package key strings at %p is not on an integer boundary.",
+             (void*)dtohl(pkg->keyStrings));
+        return (mError=BAD_TYPE);
+    }
+    
+    Package* package = NULL;
+    PackageGroup* group = NULL;
+    uint32_t id = dtohl(pkg->id);
+    if (id != 0 && id < 256) {
+        size_t idx = mPackageMap[id];
+        if (idx == 0) {
+            idx = mPackageGroups.size()+1;
+
+            char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)];
+            strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t));
+            group = new PackageGroup(String16(tmpName), id);
+            if (group == NULL) {
+                return (mError=NO_MEMORY);
+            }
+
+            err = group->typeStrings.setTo(base+dtohl(pkg->typeStrings),
+                                           header->dataEnd-(base+dtohl(pkg->typeStrings)));
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+            err = group->keyStrings.setTo(base+dtohl(pkg->keyStrings),
+                                          header->dataEnd-(base+dtohl(pkg->keyStrings)));
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+
+            //printf("Adding new package id %d at index %d\n", id, idx);
+            err = mPackageGroups.add(group);
+            if (err < NO_ERROR) {
+                return (mError=err);
+            }
+            mPackageMap[id] = (uint8_t)idx;
+        } else {
+            group = mPackageGroups.itemAt(idx-1);
+            if (group == NULL) {
+                return (mError=UNKNOWN_ERROR);
+            }
+        }
+        package = new Package(header, pkg);
+        if (package == NULL) {
+            return (mError=NO_MEMORY);
+        }
+        err = group->packages.add(package);
+        if (err < NO_ERROR) {
+            return (mError=err);
+        }
+    } else {
+        LOG_ALWAYS_FATAL("Skins not supported!");
+        return NO_ERROR;
+    }
+
+    
+    // Iterate through all chunks.
+    size_t curPackage = 0;
+    
+    const ResChunk_header* chunk =
+        (const ResChunk_header*)(((const uint8_t*)pkg)
+                                 + dtohs(pkg->header.headerSize));
+    const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
+    while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
+           ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
+        TABLE_NOISY(LOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+                         dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
+                         (void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
+        const size_t csize = dtohl(chunk->size);
+        const uint16_t ctype = dtohs(chunk->type);
+        if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {
+            const ResTable_typeSpec* typeSpec = (const ResTable_typeSpec*)(chunk);
+            err = validate_chunk(&typeSpec->header, sizeof(*typeSpec),
+                                 endPos, "ResTable_typeSpec");
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+            
+            const size_t typeSpecSize = dtohl(typeSpec->header.size);
+            
+            LOAD_TABLE_NOISY(printf("TypeSpec off %p: type=0x%x, headerSize=0x%x, size=%p\n",
+                                    (void*)(base-(const uint8_t*)chunk),
+                                    dtohs(typeSpec->header.type),
+                                    dtohs(typeSpec->header.headerSize),
+                                    (void*)typeSize));
+            // look for block overrun or int overflow when multiplying by 4
+            if ((dtohl(typeSpec->entryCount) > (INT32_MAX/sizeof(uint32_t))
+                    || dtohs(typeSpec->header.headerSize)+(sizeof(uint32_t)*dtohl(typeSpec->entryCount))
+                    > typeSpecSize)) {
+                LOGW("ResTable_typeSpec entry index to %p extends beyond chunk end %p.",
+                     (void*)(dtohs(typeSpec->header.headerSize)
+                             +(sizeof(uint32_t)*dtohl(typeSpec->entryCount))),
+                     (void*)typeSpecSize);
+                return (mError=BAD_TYPE);
+            }
+            
+            if (typeSpec->id == 0) {
+                LOGW("ResTable_type has an id of 0.");
+                return (mError=BAD_TYPE);
+            }
+            
+            while (package->types.size() < typeSpec->id) {
+                package->types.add(NULL);
+            }
+            Type* t = package->types[typeSpec->id-1];
+            if (t == NULL) {
+                t = new Type(header, package, dtohl(typeSpec->entryCount));
+                package->types.editItemAt(typeSpec->id-1) = t;
+            } else if (dtohl(typeSpec->entryCount) != t->entryCount) {
+                LOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d",
+                    (int)dtohl(typeSpec->entryCount), (int)t->entryCount);
+                return (mError=BAD_TYPE);
+            }
+            t->typeSpecFlags = (const uint32_t*)(
+                    ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));
+            t->typeSpec = typeSpec;
+            
+        } else if (ctype == RES_TABLE_TYPE_TYPE) {
+            const ResTable_type* type = (const ResTable_type*)(chunk);
+            err = validate_chunk(&type->header, sizeof(*type)-sizeof(ResTable_config)+4,
+                                 endPos, "ResTable_type");
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+            
+            const size_t typeSize = dtohl(type->header.size);
+            
+            LOAD_TABLE_NOISY(printf("Type off %p: type=0x%x, headerSize=0x%x, size=%p\n",
+                                    (void*)(base-(const uint8_t*)chunk),
+                                    dtohs(type->header.type),
+                                    dtohs(type->header.headerSize),
+                                    (void*)typeSize));
+            if (dtohs(type->header.headerSize)+(sizeof(uint32_t)*dtohl(type->entryCount))
+                > typeSize) {
+                LOGW("ResTable_type entry index to %p extends beyond chunk end %p.",
+                     (void*)(dtohs(type->header.headerSize)
+                             +(sizeof(uint32_t)*dtohl(type->entryCount))),
+                     (void*)typeSize);
+                return (mError=BAD_TYPE);
+            }
+            if (dtohl(type->entryCount) != 0
+                && dtohl(type->entriesStart) > (typeSize-sizeof(ResTable_entry))) {
+                LOGW("ResTable_type entriesStart at %p extends beyond chunk end %p.",
+                     (void*)dtohl(type->entriesStart), (void*)typeSize);
+                return (mError=BAD_TYPE);
+            }
+            if (type->id == 0) {
+                LOGW("ResTable_type has an id of 0.");
+                return (mError=BAD_TYPE);
+            }
+            
+            while (package->types.size() < type->id) {
+                package->types.add(NULL);
+            }
+            Type* t = package->types[type->id-1];
+            if (t == NULL) {
+                t = new Type(header, package, dtohl(type->entryCount));
+                package->types.editItemAt(type->id-1) = t;
+            } else if (dtohl(type->entryCount) != t->entryCount) {
+                LOGW("ResTable_type entry count inconsistent: given %d, previously %d",
+                    (int)dtohl(type->entryCount), (int)t->entryCount);
+                return (mError=BAD_TYPE);
+            }
+            
+            TABLE_GETENTRY(
+                ResTable_config thisConfig;
+                thisConfig.copyFromDtoH(type->config);
+                LOGI("Adding config to type %d: imsi:%d/%d lang:%c%c cnt:%c%c "
+                     "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+                      type->id,
+                      thisConfig.mcc, thisConfig.mnc,
+                      thisConfig.language[0] ? thisConfig.language[0] : '-',
+                      thisConfig.language[1] ? thisConfig.language[1] : '-',
+                      thisConfig.country[0] ? thisConfig.country[0] : '-',
+                      thisConfig.country[1] ? thisConfig.country[1] : '-',
+                      thisConfig.orientation,
+                      thisConfig.touchscreen,
+                      thisConfig.density,
+                      thisConfig.keyboard,
+                      thisConfig.inputFlags,
+                      thisConfig.navigation,
+                      thisConfig.screenWidth,
+                      thisConfig.screenHeight));
+            t->configs.add(type);
+        } else {
+            status_t err = validate_chunk(chunk, sizeof(ResChunk_header),
+                                          endPos, "ResTable_package:unknown");
+            if (err != NO_ERROR) {
+                return (mError=err);
+            }
+        }
+        chunk = (const ResChunk_header*)
+            (((const uint8_t*)chunk) + csize);
+    }
+
+    if (group->typeCount == 0) {
+        group->typeCount = package->types.size();
+    }
+    
+    return NO_ERROR;
+}
+
+#ifndef HAVE_ANDROID_OS
+#define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
+
+#define CHAR16_ARRAY_EQ(constant, var, len) \
+        ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))
+
+void ResTable::print() const
+{
+    printf("mError=0x%x (%s)\n", mError, strerror(mError));
+#if 0
+    printf("mParams=%c%c-%c%c,\n",
+            mParams.language[0], mParams.language[1],
+            mParams.country[0], mParams.country[1]);
+#endif
+    size_t pgCount = mPackageGroups.size();
+    printf("Package Groups (%d)\n", (int)pgCount);
+    for (size_t pgIndex=0; pgIndex<pgCount; pgIndex++) {
+        const PackageGroup* pg = mPackageGroups[pgIndex];
+        printf("Package Group %d id=%d packageCount=%d name=%s\n",
+                (int)pgIndex, pg->id, (int)pg->packages.size(),
+                String8(pg->name).string());
+        
+        size_t pkgCount = pg->packages.size();
+        for (size_t pkgIndex=0; pkgIndex<pkgCount; pkgIndex++) {
+            const Package* pkg = pg->packages[pkgIndex];
+            size_t typeCount = pkg->types.size();
+            printf("  Package %d id=%d name=%s typeCount=%d\n", (int)pkgIndex,
+                    pkg->package->id, String8(String16(pkg->package->name)).string(),
+                    (int)typeCount);
+            for (size_t typeIndex=0; typeIndex<typeCount; typeIndex++) {
+                const Type* typeConfigs = pkg->getType(typeIndex);
+                if (typeConfigs == NULL) {
+                    printf("    type %d NULL\n", (int)typeIndex);
+                    continue;
+                }
+                const size_t NTC = typeConfigs->configs.size();
+                printf("    type %d configCount=%d entryCount=%d\n",
+                       (int)typeIndex, (int)NTC, (int)typeConfigs->entryCount);
+                if (typeConfigs->typeSpecFlags != NULL) {
+                    for (size_t entryIndex=0; entryIndex<typeConfigs->entryCount; entryIndex++) {
+                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
+                                    | (0x00ff0000 & ((typeIndex+1)<<16))
+                                    | (0x0000ffff & (entryIndex));
+                        resource_name resName;
+                        this->getResourceName(resID, &resName);
+                        printf("      spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
+                            resID,
+                            CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                            CHAR16_TO_CSTR(resName.type, resName.typeLen),
+                            CHAR16_TO_CSTR(resName.name, resName.nameLen),
+                            dtohl(typeConfigs->typeSpecFlags[entryIndex]));
+                    }
+                }
+                for (size_t configIndex=0; configIndex<NTC; configIndex++) {
+                    const ResTable_type* type = typeConfigs->configs[configIndex];
+                    if ((((int)type)&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);
+                        continue;
+                    }
+                    printf("      config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d\n",
+                           (int)configIndex,
+                           type->config.language[0] ? type->config.language[0] : '-',
+                           type->config.language[1] ? type->config.language[1] : '-',
+                           type->config.country[0] ? type->config.country[0] : '-',
+                           type->config.country[1] ? type->config.country[1] : '-',
+                           type->config.orientation,
+                           type->config.touchscreen,
+                           dtohs(type->config.density),
+                           type->config.keyboard,
+                           type->config.inputFlags,
+                           type->config.navigation,
+                           dtohs(type->config.screenWidth),
+                           dtohs(type->config.screenHeight));
+                    size_t entryCount = dtohl(type->entryCount);
+                    uint32_t entriesStart = dtohl(type->entriesStart);
+                    if ((entriesStart&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type entriesStart OFFSET: %p\n", (void*)entriesStart);
+                        continue;
+                    }
+                    uint32_t typeSize = dtohl(type->header.size);
+                    if ((typeSize&0x3) != 0) {
+                        printf("      NON-INTEGER ResTable_type header.size: %p\n", (void*)typeSize);
+                        continue;
+                    }
+                    for (size_t entryIndex=0; entryIndex<entryCount; entryIndex++) {
+                        
+                        const uint8_t* const end = ((const uint8_t*)type)
+                            + dtohl(type->header.size);
+                        const uint32_t* const eindex = (const uint32_t*)
+                            (((const uint8_t*)type) + dtohs(type->header.headerSize));
+                        
+                        uint32_t thisOffset = dtohl(eindex[entryIndex]);
+                        if (thisOffset == ResTable_type::NO_ENTRY) {
+                            continue;
+                        }
+                        
+                        uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
+                                    | (0x00ff0000 & ((typeIndex+1)<<16))
+                                    | (0x0000ffff & (entryIndex));
+                        resource_name resName;
+                        this->getResourceName(resID, &resName);
+                        printf("        resource 0x%08x %s:%s/%s: ", resID,
+                                CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                                CHAR16_TO_CSTR(resName.type, resName.typeLen),
+                                CHAR16_TO_CSTR(resName.name, resName.nameLen));
+                        if ((thisOffset&0x3) != 0) {
+                            printf("NON-INTEGER OFFSET: %p\n", (void*)thisOffset);
+                            continue;
+                        }
+                        if ((thisOffset+sizeof(ResTable_entry)) > typeSize) {
+                            printf("OFFSET OUT OF BOUNDS: %p+%p (size is %p)\n",
+                                   (void*)entriesStart, (void*)thisOffset,
+                                   (void*)typeSize);
+                            continue;
+                        }
+                        
+                        const ResTable_entry* ent = (const ResTable_entry*)
+                            (((const uint8_t*)type) + entriesStart + thisOffset);
+                        if (((entriesStart + thisOffset)&0x3) != 0) {
+                            printf("NON-INTEGER ResTable_entry OFFSET: %p\n",
+                                 (void*)(entriesStart + thisOffset));
+                            continue;
+                        }
+                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {
+                            printf("<bag>");
+                        } else {
+                            uint16_t esize = dtohs(ent->size);
+                            if ((esize&0x3) != 0) {
+                                printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize);
+                                continue;
+                            }
+                            if ((thisOffset+esize) > typeSize) {
+                                printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n",
+                                       (void*)entriesStart, (void*)thisOffset,
+                                       (void*)esize, (void*)typeSize);
+                                continue;
+                            }
+                            
+                            const Res_value* value = (const Res_value*)
+                                (((const uint8_t*)ent) + esize);
+                            printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)",
+                                   (int)value->dataType, (int)dtohl(value->data),
+                                   (int)dtohs(value->size), (int)value->res0);
+                        }
+                        
+                        if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {
+                            printf(" (PUBLIC)");
+                        }
+                        printf("\n");
+                    }
+                }
+            }
+        }
+    }
+}
+
+#endif // HAVE_ANDROID_OS
+
+}   // namespace android
diff --git a/libs/utils/SharedBuffer.cpp b/libs/utils/SharedBuffer.cpp
new file mode 100644
index 0000000..3555fb7
--- /dev/null
+++ b/libs/utils/SharedBuffer.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <string.h>
+
+#include <utils/SharedBuffer.h>
+#include <utils/Atomic.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+SharedBuffer* SharedBuffer::alloc(size_t size)
+{
+    SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size));
+    if (sb) {
+        sb->mRefs = 1;
+        sb->mSize = size;
+    }
+    return sb;
+}
+
+
+ssize_t SharedBuffer::dealloc(const SharedBuffer* released)
+{
+    if (released->mRefs != 0) return -1; // XXX: invalid operation
+    free(const_cast<SharedBuffer*>(released));
+    return 0;
+}
+
+SharedBuffer* SharedBuffer::edit() const
+{
+    if (onlyOwner()) {
+        return const_cast<SharedBuffer*>(this);
+    }
+    SharedBuffer* sb = alloc(mSize);
+    if (sb) {
+        memcpy(sb->data(), data(), size());
+        release();
+    }
+    return sb;    
+}
+
+SharedBuffer* SharedBuffer::editResize(size_t newSize) const
+{
+    if (onlyOwner()) {
+        SharedBuffer* buf = const_cast<SharedBuffer*>(this);
+        if (buf->mSize == newSize) return buf;
+        buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize);
+        if (buf != NULL) {
+            buf->mSize = newSize;
+            return buf;
+        }
+    }
+    SharedBuffer* sb = alloc(newSize);
+    if (sb) {
+        const size_t mySize = mSize;
+        memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize);
+        release();
+    }
+    return sb;    
+}
+
+SharedBuffer* SharedBuffer::attemptEdit() const
+{
+    if (onlyOwner()) {
+        return const_cast<SharedBuffer*>(this);
+    }
+    return 0;
+}
+
+SharedBuffer* SharedBuffer::reset(size_t new_size) const
+{
+    // cheap-o-reset.
+    SharedBuffer* sb = alloc(new_size);
+    if (sb) {
+        release();
+    }
+    return sb;
+}
+
+void SharedBuffer::acquire() const {
+    android_atomic_inc(&mRefs);
+}
+
+int32_t SharedBuffer::release(uint32_t flags) const
+{
+    int32_t prev = 1;
+    if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) {
+        mRefs = 0;
+        if ((flags & eKeepStorage) == 0) {
+            free(const_cast<SharedBuffer*>(this));
+        }
+    }
+    return prev;
+}
+
+
+}; // namespace android
diff --git a/libs/utils/Socket.cpp b/libs/utils/Socket.cpp
new file mode 100644
index 0000000..51509a3
--- /dev/null
+++ b/libs/utils/Socket.cpp
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Internet address class.
+//
+
+#ifdef HAVE_WINSOCK
+// This needs to come first, or Cygwin gets concerned about a potential
+// clash between WinSock and <sys/types.h>.
+# include <winsock2.h>
+#endif
+
+#include <utils/Socket.h>
+#include <utils/inet_address.h>
+#include <utils/Log.h>
+#include <utils/Timers.h>
+
+#ifndef HAVE_WINSOCK
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+
+/*
+ * ===========================================================================
+ *      Socket
+ * ===========================================================================
+ */
+
+#ifndef INVALID_SOCKET
+# define INVALID_SOCKET (-1)
+#endif
+#define UNDEF_SOCKET   ((unsigned long) INVALID_SOCKET)
+
+/*static*/ bool Socket::mBootInitialized = false;
+
+/*
+ * Extract system-dependent error code.
+ */
+static inline int getSocketError(void) {
+#ifdef HAVE_WINSOCK
+    return WSAGetLastError();
+#else
+    return errno;
+#endif
+}
+
+/*
+ * One-time initialization for socket code.
+ */
+/*static*/ bool Socket::bootInit(void)
+{
+#ifdef HAVE_WINSOCK
+    WSADATA wsaData;
+    int err;
+
+    err = WSAStartup(MAKEWORD(2, 0), &wsaData);
+    if (err != 0) {
+        LOG(LOG_ERROR, "socket", "Unable to start WinSock\n");
+        return false;
+    }
+
+    LOG(LOG_INFO, "socket", "Using WinSock v%d.%d\n",
+        LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
+#endif
+
+    mBootInitialized = true;
+    return true;
+}
+
+/*
+ * One-time shutdown for socket code.
+ */
+/*static*/ void Socket::finalShutdown(void)
+{
+#ifdef HAVE_WINSOCK
+    WSACleanup();
+#endif
+    mBootInitialized = false;
+}
+
+
+/*
+ * Simple constructor.  Allow the application to create us and then make
+ * bind/connect calls.
+ */
+Socket::Socket(void)
+    : mSock(UNDEF_SOCKET)
+{
+    if (!mBootInitialized)
+        LOG(LOG_WARN, "socket", "WARNING: sockets not initialized\n");
+}
+
+/*
+ * Destructor.  Closes the socket and resets our storage.
+ */
+Socket::~Socket(void)
+{
+    close();
+}
+
+
+/*
+ * Create a socket and connect to the specified host and port.
+ */
+int Socket::connect(const char* host, int port)
+{
+    if (mSock != UNDEF_SOCKET) {
+        LOG(LOG_WARN, "socket", "Socket already connected\n");
+        return -1;
+    }
+
+    InetSocketAddress sockAddr;
+    if (!sockAddr.create(host, port))
+        return -1;
+
+    //return doConnect(sockAddr);
+    int foo;
+    foo = doConnect(sockAddr);
+    return foo;
+}
+
+/*
+ * Create a socket and connect to the specified host and port.
+ */
+int Socket::connect(const InetAddress* addr, int port)
+{
+    if (mSock != UNDEF_SOCKET) {
+        LOG(LOG_WARN, "socket", "Socket already connected\n");
+        return -1;
+    }
+
+    InetSocketAddress sockAddr;
+    if (!sockAddr.create(addr, port))
+        return -1;
+
+    return doConnect(sockAddr);
+}
+
+/*
+ * Finish creating a socket by connecting to the remote host.
+ *
+ * Returns 0 on success.
+ */
+int Socket::doConnect(const InetSocketAddress& sockAddr)
+{
+#ifdef HAVE_WINSOCK
+    SOCKET sock;
+#else
+    int sock;
+#endif
+    const InetAddress* addr = sockAddr.getAddress();
+    int port = sockAddr.getPort();
+    struct sockaddr_in inaddr;
+    DurationTimer connectTimer;
+
+    assert(sizeof(struct sockaddr_in) == addr->getAddressLength());
+    memcpy(&inaddr, addr->getAddress(), addr->getAddressLength());
+    inaddr.sin_port = htons(port);
+
+    //fprintf(stderr, "--- connecting to %s:%d\n",
+    //    sockAddr.getHostName(), port);
+
+    sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (sock == INVALID_SOCKET) {
+        int err = getSocketError();
+        LOG(LOG_ERROR, "socket", "Unable to create socket (err=%d)\n", err);
+        return (err != 0) ? err : -1;
+    }
+
+    connectTimer.start();
+
+    if (::connect(sock, (struct sockaddr*) &inaddr, sizeof(inaddr)) != 0) {
+        int err = getSocketError();
+        LOG(LOG_WARN, "socket", "Connect to %s:%d failed: %d\n",
+            sockAddr.getHostName(), port, err);
+        return (err != 0) ? err : -1;
+    }
+
+    connectTimer.stop();
+    if ((long) connectTimer.durationUsecs() > 100000) {
+        LOG(LOG_INFO, "socket",
+            "Connect to %s:%d took %.3fs\n", sockAddr.getHostName(),
+            port, ((long) connectTimer.durationUsecs()) / 1000000.0);
+    }
+
+    mSock = (unsigned long) sock;
+    LOG(LOG_VERBOSE, "socket",
+        "--- connected to %s:%d\n", sockAddr.getHostName(), port);
+    return 0;
+}
+
+
+/*
+ * Close the socket if it needs closing.
+ */
+bool Socket::close(void)
+{
+    if (mSock != UNDEF_SOCKET) {
+        //fprintf(stderr, "--- closing socket %lu\n", mSock);
+#ifdef HAVE_WINSOCK
+        if (::closesocket((SOCKET) mSock) != 0)
+            return false;
+#else
+        if (::close((int) mSock) != 0)
+            return false;
+#endif
+    }
+
+    mSock = UNDEF_SOCKET;
+
+    return true;
+}
+
+/*
+ * Read data from socket.
+ *
+ * Standard semantics: read up to "len" bytes into "buf".  Returns the
+ * number of bytes read, or less than zero on error.
+ */
+int Socket::read(void* buf, ssize_t len) const
+{
+    if (mSock == UNDEF_SOCKET) {
+        LOG(LOG_ERROR, "socket", "ERROR: read on invalid socket\n");
+        return -500;
+    }
+
+#ifdef HAVE_WINSOCK
+    SOCKET sock = (SOCKET) mSock;
+#else
+    int sock = (int) mSock;
+#endif
+    int cc;
+
+    cc = recv(sock, (char*)buf, len, 0);
+    if (cc < 0) {
+        int err = getSocketError();
+        return (err > 0) ? -err : -1;
+    }
+
+    return cc;
+}
+
+/*
+ * Write data to a socket.
+ *
+ * Standard semantics: write up to "len" bytes into "buf".  Returns the
+ * number of bytes written, or less than zero on error.
+ */
+int Socket::write(const void* buf, ssize_t len) const
+{
+    if (mSock == UNDEF_SOCKET) {
+        LOG(LOG_ERROR, "socket", "ERROR: write on invalid socket\n");
+        return -500;
+    }
+
+#ifdef HAVE_WINSOCK
+    SOCKET sock = (SOCKET) mSock;
+#else
+    int sock = (int) mSock;
+#endif
+    int cc;
+
+    cc = send(sock, (const char*)buf, len, 0);
+    if (cc < 0) {
+        int err = getSocketError();
+        return (err > 0) ? -err : -1;
+    }
+
+    return cc;
+}
+
+
+/*
+ * ===========================================================================
+ *      Socket tests
+ * ===========================================================================
+ */
+
+/*
+ * Read all data from the socket.  The data is read into a buffer that
+ * expands as needed.
+ *
+ * On exit, the buffer is returned, and the length of the data is stored
+ * in "*sz".  A null byte is added to the end, but is not included in
+ * the length.
+ */
+static char* socketReadAll(const Socket& s, int *sz)
+{
+    int max, r;
+    char *data, *ptr, *tmp;
+
+    data = (char*) malloc(max = 32768);
+    if (data == NULL)
+        return NULL;
+
+    ptr = data;
+    
+    for (;;) {
+        if ((ptr - data) == max) {
+            tmp = (char*) realloc(data, max *= 2);
+            if(tmp == 0) {
+                free(data);
+                return 0;
+            }
+        }
+        r = s.read(ptr, max - (ptr - data));
+        if (r == 0)
+            break;
+        if (r < 0) {
+            LOG(LOG_WARN, "socket", "WARNING: socket read failed (res=%d)\n",r);
+            break;
+        }
+        ptr += r;
+    }
+
+    if ((ptr - data) == max) {
+        tmp = (char*) realloc(data, max + 1);
+        if (tmp == NULL) {
+            free(data);
+            return NULL;
+        }
+    }
+    *ptr = '\0';
+    *sz = (ptr - data);
+    return data;
+}
+
+/*
+ * Exercise the Socket class.
+ */
+void android::TestSockets(void)
+{
+    printf("----- SOCKET TEST ------\n");
+    Socket::bootInit();
+
+    char* buf = NULL;
+    int len, cc;
+    const char* kTestStr =
+        "GET / HTTP/1.0\n"
+        "Connection: close\n"
+        "\n";
+
+    Socket sock;
+    if (sock.connect("www.google.com", 80) != 0) {
+        fprintf(stderr, "socket connected failed\n");
+        goto bail;
+    }
+
+    cc = sock.write(kTestStr, strlen(kTestStr));
+    if (cc != (int) strlen(kTestStr)) {
+        fprintf(stderr, "write failed, res=%d\n", cc);
+        goto bail;
+    }
+    buf = socketReadAll(sock, &len);
+
+    printf("GOT '%s'\n", buf);
+
+bail:
+    sock.close();
+    free(buf);
+}
+
diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp
new file mode 100644
index 0000000..93f7e4f
--- /dev/null
+++ b/libs/utils/Static.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+// All static variables go here, to control initialization and
+// destruction order in the library.
+
+#include <private/utils/Static.h>
+
+#include <utils/BufferedTextOutput.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Log.h>
+
+namespace android {
+
+class LibUtilsFirstStatics
+{
+public:
+    LibUtilsFirstStatics()
+    {
+        initialize_string8();
+        initialize_string16();
+    }
+    
+    ~LibUtilsFirstStatics()
+    {
+        terminate_string16();
+        terminate_string8();
+    }
+};
+
+static LibUtilsFirstStatics gFirstStatics;
+int gDarwinCantLoadAllObjects = 1;
+
+// ------------ Text output streams
+
+Vector<int32_t> gTextBuffers;
+
+class LogTextOutput : public BufferedTextOutput
+{
+public:
+    LogTextOutput() : BufferedTextOutput(MULTITHREADED) { }
+    virtual ~LogTextOutput() { };
+
+protected:
+    virtual status_t writeLines(const struct iovec& vec, size_t N)
+    {
+        android_writevLog(&vec, N);
+        return NO_ERROR;
+    }
+};
+
+class FdTextOutput : public BufferedTextOutput
+{
+public:
+    FdTextOutput(int fd) : BufferedTextOutput(MULTITHREADED), mFD(fd) { }
+    virtual ~FdTextOutput() { };
+
+protected:
+    virtual status_t writeLines(const struct iovec& vec, size_t N)
+    {
+        writev(mFD, &vec, N);
+        return NO_ERROR;
+    }
+
+private:
+    int mFD;
+};
+
+static LogTextOutput gLogTextOutput;
+static FdTextOutput gStdoutTextOutput(STDOUT_FILENO);
+static FdTextOutput gStderrTextOutput(STDERR_FILENO);
+
+TextOutput& alog(gLogTextOutput);
+TextOutput& aout(gStdoutTextOutput);
+TextOutput& aerr(gStderrTextOutput);
+
+#ifndef LIBUTILS_NATIVE
+
+// ------------ ProcessState.cpp
+
+Mutex gProcessMutex;
+sp<ProcessState> gProcess;
+
+class LibUtilsIPCtStatics
+{
+public:
+    LibUtilsIPCtStatics()
+    {
+    }
+    
+    ~LibUtilsIPCtStatics()
+    {
+        IPCThreadState::shutdown();
+    }
+};
+
+static LibUtilsIPCtStatics gIPCStatics;
+
+// ------------ ServiceManager.cpp
+
+Mutex gDefaultServiceManagerLock;
+sp<IServiceManager> gDefaultServiceManager;
+sp<IPermissionController> gPermissionController;
+
+#endif
+
+}   // namespace android
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
new file mode 100644
index 0000000..68a1c52
--- /dev/null
+++ b/libs/utils/StopWatch.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "StopWatch"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/StopWatch.h>
+
+/*****************************************************************************/
+
+namespace android {
+
+
+StopWatch::StopWatch(const char *name, int clock, uint32_t flags)
+    :   mName(name), mClock(clock), mFlags(flags),
+        mStartTime(0), mNumLaps(0)
+{
+    mStartTime = systemTime(mClock);
+}
+
+StopWatch::~StopWatch()
+{
+    nsecs_t elapsed = elapsedTime();
+    const int n = mNumLaps;
+    LOGD("StopWatch %s (us): %lld ", mName, ns2us(elapsed));
+    for (int i=0 ; i<n ; i++) {
+        const nsecs_t soFar = mLaps[i].soFar;
+        const nsecs_t thisLap = mLaps[i].thisLap;
+        LOGD(" [%d: %lld, %lld]", i, ns2us(soFar), ns2us(thisLap));
+    }
+}
+
+const char* StopWatch::name() const
+{
+    return mName;
+}
+
+nsecs_t StopWatch::lap()
+{
+    nsecs_t elapsed = elapsedTime();
+    if (mNumLaps >= 8) {
+        elapsed = 0;
+    } else {
+        const int n = mNumLaps;
+        mLaps[n].soFar   = elapsed;
+        mLaps[n].thisLap = n ? (elapsed - mLaps[n-1].soFar) : elapsed;
+        mNumLaps = n+1;
+    }
+    return elapsed;
+}
+
+nsecs_t StopWatch::elapsedTime() const
+{
+    return systemTime(mClock) - mStartTime;
+}
+
+
+/*****************************************************************************/
+
+}; // namespace android
+
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
new file mode 100644
index 0000000..1f81cad
--- /dev/null
+++ b/libs/utils/String16.cpp
@@ -0,0 +1,609 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/String16.h>
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/utils/Static.h>
+
+#ifdef HAVE_WINSOCK
+# undef  nhtol
+# undef  htonl
+# undef  nhtos
+# undef  htons
+
+# ifdef HAVE_LITTLE_ENDIAN
+#  define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
+#  define htonl(x)    ntohl(x)
+#  define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
+#  define htons(x)    ntohs(x)
+# else
+#  define ntohl(x)    (x)
+#  define htonl(x)    (x)
+#  define ntohs(x)    (x)
+#  define htons(x)    (x)
+# endif
+#else
+# include <netinet/in.h>
+#endif
+
+#include <memory.h>
+#include <stdio.h>
+#include <ctype.h>
+
+// ---------------------------------------------------------------------------
+
+int strcmp16(const char16_t *s1, const char16_t *s2)
+{
+  char16_t ch;
+  int d = 0;
+
+  while ( 1 ) {
+    d = (int)(ch = *s1++) - (int)*s2++;
+    if ( d || !ch )
+      break;
+  }
+
+  return d;
+}
+
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
+{
+  char16_t ch;
+  int d = 0;
+
+  while ( n-- ) {
+    d = (int)(ch = *s1++) - (int)*s2++;
+    if ( d || !ch )
+      break;
+  }
+
+  return d;
+}
+
+char16_t *strcpy16(char16_t *dst, const char16_t *src)
+{
+  char16_t *q = dst;
+  const char16_t *p = src;
+  char16_t ch;
+
+  do {
+    *q++ = ch = *p++;
+  } while ( ch );
+
+  return dst;
+}
+
+size_t strlen16(const char16_t *s)
+{
+  const char16_t *ss = s;
+  while ( *ss )
+    ss++;
+  return ss-s;
+}
+
+
+char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
+{
+  char16_t *q = dst;
+  const char16_t *p = src;
+  char ch;
+
+  while (n) {
+    n--;
+    *q++ = ch = *p++;
+    if ( !ch )
+      break;
+  }
+
+  *q = 0;
+
+  return dst;
+}
+
+size_t strnlen16(const char16_t *s, size_t maxlen)
+{
+  const char16_t *ss = s;
+
+  /* Important: the maxlen test must precede the reference through ss;
+     since the byte beyond the maximum may segfault */
+  while ((maxlen > 0) && *ss) {
+    ss++;
+    maxlen--;
+  }
+  return ss-s;
+}
+
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
+{
+    const char16_t* e1 = s1+n1;
+    const char16_t* e2 = s2+n2;
+
+    while (s1 < e1 && s2 < e2) {
+        const int d = (int)*s1++ - (int)*s2++;
+        if (d) {
+            return d;
+        }
+    }
+
+    return n1 < n2
+        ? (0 - (int)*s2)
+        : (n1 > n2
+           ? ((int)*s1 - 0)
+           : 0);
+}
+
+int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
+{
+    const char16_t* e1 = s1H+n1;
+    const char16_t* e2 = s2N+n2;
+
+    while (s1H < e1 && s2N < e2) {
+        const char16_t c2 = ntohs(*s2N);
+        const int d = (int)*s1H++ - (int)c2;
+        s2N++;
+        if (d) {
+            return d;
+        }
+    }
+
+    return n1 < n2
+        ? (0 - (int)ntohs(*s2N))
+        : (n1 > n2
+           ? ((int)*s1H - 0)
+           : 0);
+}
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+static inline size_t
+utf8_char_len(uint8_t ch)
+{
+    return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
+}
+
+#define UTF8_SHIFT_AND_MASK(unicode, byte)  (unicode)<<=6; (unicode) |= (0x3f & (byte));
+
+static inline uint32_t
+utf8_to_utf32(const uint8_t *src, size_t length)
+{
+    uint32_t unicode;
+
+    switch (length)
+    {
+        case 1:
+            return src[0];
+        case 2:
+            unicode = src[0] & 0x1f;
+            UTF8_SHIFT_AND_MASK(unicode, src[1])
+            return unicode;
+        case 3:
+            unicode = src[0] & 0x0f;
+            UTF8_SHIFT_AND_MASK(unicode, src[1])
+            UTF8_SHIFT_AND_MASK(unicode, src[2])
+            return unicode;
+        case 4:
+            unicode = src[0] & 0x07;
+            UTF8_SHIFT_AND_MASK(unicode, src[1])
+            UTF8_SHIFT_AND_MASK(unicode, src[2])
+            UTF8_SHIFT_AND_MASK(unicode, src[3])
+            return unicode;
+        default:
+            return 0xffff;
+    }
+    
+    //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
+}
+
+// ---------------------------------------------------------------------------
+
+static SharedBuffer* gEmptyStringBuf = NULL;
+static char16_t* gEmptyString = NULL;
+
+static inline char16_t* getEmptyString()
+{
+    gEmptyStringBuf->acquire();
+   return gEmptyString;
+}
+
+void initialize_string16()
+{
+    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
+    char16_t* str = (char16_t*)buf->data();
+    *str = 0;
+    gEmptyStringBuf = buf;
+    gEmptyString = str;
+}
+
+void terminate_string16()
+{
+    SharedBuffer::bufferFromData(gEmptyString)->release();
+    gEmptyStringBuf = NULL;
+    gEmptyString = NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+// Note: not dealing with generating surrogate pairs.
+static char16_t* allocFromUTF8(const char* in, size_t len)
+{
+    if (len == 0) return getEmptyString();
+    
+    size_t chars = 0;
+    const char* end = in+len;
+    const char* p = in;
+    
+    while (p < end) {
+        chars++;
+        p += utf8_char_len(*p);
+    }
+    
+    SharedBuffer* buf = SharedBuffer::alloc((chars+1)*sizeof(char16_t));
+    if (buf) {
+        p = in;
+        char16_t* str = (char16_t*)buf->data();
+        char16_t* d = str;
+        while (p < end) {
+            size_t len = utf8_char_len(*p);
+            *d++ = (char16_t)utf8_to_utf32((const uint8_t*)p, len);
+            p += len;
+        }
+        *d = 0;
+        
+        //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
+        //printHexData(1, str, buf->size(), 16, 1);
+        //printf("\n");
+        
+        return str;
+    }
+    
+    return getEmptyString();
+}
+
+// ---------------------------------------------------------------------------
+
+String16::String16()
+    : mString(getEmptyString())
+{
+}
+
+String16::String16(const String16& o)
+    : mString(o.mString)
+{
+    SharedBuffer::bufferFromData(mString)->acquire();
+}
+
+String16::String16(const String16& o, size_t len, size_t begin)
+    : mString(getEmptyString())
+{
+    setTo(o, len, begin);
+}
+
+String16::String16(const char16_t* o)
+{
+    size_t len = strlen16(o);
+    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        strcpy16(str, o);
+        mString = str;
+        return;
+    }
+    
+    mString = getEmptyString();
+}
+
+String16::String16(const char16_t* o, size_t len)
+{
+    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str, o, len*sizeof(char16_t));
+        str[len] = 0;
+        mString = str;
+        return;
+    }
+    
+    mString = getEmptyString();
+}
+
+String16::String16(const String8& o)
+    : mString(allocFromUTF8(o.string(), o.size()))
+{
+}
+
+String16::String16(const char* o)
+    : mString(allocFromUTF8(o, strlen(o)))
+{
+}
+
+String16::String16(const char* o, size_t len)
+    : mString(allocFromUTF8(o, len))
+{
+}
+
+String16::~String16()
+{
+    SharedBuffer::bufferFromData(mString)->release();
+}
+
+void String16::setTo(const String16& other)
+{
+    SharedBuffer::bufferFromData(other.mString)->acquire();
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = other.mString;
+}
+
+status_t String16::setTo(const String16& other, size_t len, size_t begin)
+{
+    const size_t N = other.size();
+    if (begin >= N) {
+        SharedBuffer::bufferFromData(mString)->release();
+        mString = getEmptyString();
+        return NO_ERROR;
+    }
+    if ((begin+len) > N) len = N-begin;
+    if (begin == 0 && len == N) {
+        setTo(other);
+        return NO_ERROR;
+    }
+
+    if (&other == this) {
+        LOG_ALWAYS_FATAL("Not implemented");
+    }
+
+    return setTo(other.string()+begin, len);
+}
+
+status_t String16::setTo(const char16_t* other)
+{
+    return setTo(other, strlen16(other));
+}
+
+status_t String16::setTo(const char16_t* other, size_t len)
+{
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((len+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str, other, len*sizeof(char16_t));
+        str[len] = 0;
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+status_t String16::append(const String16& other)
+{
+    const size_t myLen = size();
+    const size_t otherLen = other.size();
+    if (myLen == 0) {
+        setTo(other);
+        return NO_ERROR;
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+    
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+status_t String16::append(const char16_t* chrs, size_t otherLen)
+{
+    const size_t myLen = size();
+    if (myLen == 0) {
+        setTo(chrs, otherLen);
+        return NO_ERROR;
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+    
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
+        str[myLen+otherLen] = 0;
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+status_t String16::insert(size_t pos, const char16_t* chrs)
+{
+    return insert(pos, chrs, strlen16(chrs));
+}
+
+status_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
+{
+    const size_t myLen = size();
+    if (myLen == 0) {
+        return setTo(chrs, len);
+        return NO_ERROR;
+    } else if (len == 0) {
+        return NO_ERROR;
+    }
+
+    if (pos > myLen) pos = myLen;
+
+    #if 0
+    printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
+           String8(*this).string(), pos,
+           len, myLen, String8(chrs, len).string());
+    #endif
+
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((myLen+len+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        if (pos < myLen) {
+            memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
+        }
+        memcpy(str+pos, chrs, len*sizeof(char16_t));
+        str[myLen+len] = 0;
+        mString = str;
+        #if 0
+        printf("Result (%d chrs): %s\n", size(), String8(*this).string());
+        #endif
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+ssize_t String16::findFirst(char16_t c) const
+{
+    const char16_t* str = string();
+    const char16_t* p = str;
+    const char16_t* e = p + size();
+    while (p < e) {
+        if (*p == c) {
+            return p-str;
+        }
+        p++;
+    }
+    return -1;
+}
+
+ssize_t String16::findLast(char16_t c) const
+{
+    const char16_t* str = string();
+    const char16_t* p = str;
+    const char16_t* e = p + size();
+    while (p < e) {
+        e--;
+        if (*e == c) {
+            return e-str;
+        }
+    }
+    return -1;
+}
+
+bool String16::startsWith(const String16& prefix) const
+{
+    const size_t ps = prefix.size();
+    if (ps > size()) return false;
+    return strzcmp16(mString, ps, prefix.string(), ps) == 0;
+}
+
+bool String16::startsWith(const char16_t* prefix) const
+{
+    const size_t ps = strlen16(prefix);
+    if (ps > size()) return false;
+    return strncmp16(mString, prefix, ps) == 0;
+}
+
+status_t String16::makeLower()
+{
+    const size_t N = size();
+    const char16_t* str = string();
+    char16_t* edit = NULL;
+    for (size_t i=0; i<N; i++) {
+        const char16_t v = str[i];
+        if (v >= 'A' && v <= 'Z') {
+            if (!edit) {
+                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
+                if (!buf) {
+                    return NO_MEMORY;
+                }
+                edit = (char16_t*)buf->data();
+                mString = str = edit;
+            }
+            edit[i] = tolower((char)v);
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
+{
+    const size_t N = size();
+    const char16_t* str = string();
+    char16_t* edit = NULL;
+    for (size_t i=0; i<N; i++) {
+        if (str[i] == replaceThis) {
+            if (!edit) {
+                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
+                if (!buf) {
+                    return NO_MEMORY;
+                }
+                edit = (char16_t*)buf->data();
+                mString = str = edit;
+            }
+            edit[i] = withThis;
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t String16::remove(size_t len, size_t begin)
+{
+    const size_t N = size();
+    if (begin >= N) {
+        SharedBuffer::bufferFromData(mString)->release();
+        mString = getEmptyString();
+        return NO_ERROR;
+    }
+    if ((begin+len) > N) len = N-begin;
+    if (begin == 0 && len == N) {
+        return NO_ERROR;
+    }
+
+    if (begin > 0) {
+        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+            ->editResize((N+1)*sizeof(char16_t));
+        if (!buf) {
+            return NO_MEMORY;
+        }
+        char16_t* str = (char16_t*)buf->data();
+        memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
+        mString = str;
+    }
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize((len+1)*sizeof(char16_t));
+    if (buf) {
+        char16_t* str = (char16_t*)buf->data();
+        str[len] = 0;
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+TextOutput& operator<<(TextOutput& to, const String16& val)
+{
+    to << String8(val).string();
+    return to;
+}
+
+}; // namespace android
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
new file mode 100644
index 0000000..ab843f6
--- /dev/null
+++ b/libs/utils/String8.cpp
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/String8.h>
+
+#include <utils/Log.h>
+#include <utils/String16.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/utils/Static.h>
+
+#include <ctype.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+static const uint32_t kByteMask = 0x000000BF;
+static const uint32_t kByteMark = 0x00000080;
+
+// Surrogates aren't valid for UTF-32 characters, so define some
+// constants that will let us screen them out.
+static const uint32_t kUnicodeSurrogateHighStart  = 0x0000D800;
+static const uint32_t kUnicodeSurrogateHighEnd    = 0x0000DBFF;
+static const uint32_t kUnicodeSurrogateLowStart   = 0x0000DC00;
+static const uint32_t kUnicodeSurrogateLowEnd     = 0x0000DFFF;
+static const uint32_t kUnicodeSurrogateStart      = kUnicodeSurrogateHighStart;
+static const uint32_t kUnicodeSurrogateEnd        = kUnicodeSurrogateLowEnd;
+
+// Mask used to set appropriate bits in first byte of UTF-8 sequence,
+// indexed by number of bytes in the sequence.
+static const uint32_t kFirstByteMark[] = {
+    0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
+};
+
+// Separator used by resource paths. This is not platform dependent contrary
+// to OS_PATH_SEPARATOR.
+#define RES_PATH_SEPARATOR '/'
+
+// Return number of utf8 bytes required for the character.
+static size_t utf32_to_utf8_bytes(uint32_t srcChar)
+{
+    size_t bytesToWrite;
+
+    // Figure out how many bytes the result will require.
+    if (srcChar < 0x00000080)
+    {
+        bytesToWrite = 1;
+    }
+    else if (srcChar < 0x00000800)
+    {
+        bytesToWrite = 2;
+    }
+    else if (srcChar < 0x00010000)
+    {
+        if ((srcChar < kUnicodeSurrogateStart)
+         || (srcChar > kUnicodeSurrogateEnd))
+        {
+            bytesToWrite = 3;
+        }
+        else
+        {
+            // Surrogates are invalid UTF-32 characters.
+            return 0;
+        }
+    }
+    // Max code point for Unicode is 0x0010FFFF.
+    else if (srcChar < 0x00110000)
+    {
+        bytesToWrite = 4;
+    }
+    else
+    {
+        // Invalid UTF-32 character.
+        return 0;
+    }
+
+    return bytesToWrite;
+}
+
+// Write out the source character to <dstP>.
+
+static void utf32_to_utf8(uint8_t* dstP, uint32_t srcChar, size_t bytes)
+{
+    dstP += bytes;
+    switch (bytes)
+    {   /* note: everything falls through. */
+        case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+static SharedBuffer* gEmptyStringBuf = NULL;
+static char* gEmptyString = NULL;
+
+extern int gDarwinCantLoadAllObjects;
+int gDarwinIsReallyAnnoying;
+
+static inline char* getEmptyString()
+{
+    gEmptyStringBuf->acquire();
+    return gEmptyString;
+}
+
+void initialize_string8()
+{
+#ifdef LIBUTILS_NATIVE
+	  // Bite me, Darwin!
+		gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects;
+#endif
+			
+    SharedBuffer* buf = SharedBuffer::alloc(1);
+    char* str = (char*)buf->data();
+    *str = 0;
+    gEmptyStringBuf = buf;
+    gEmptyString = str;
+}
+
+void terminate_string8()
+{
+    SharedBuffer::bufferFromData(gEmptyString)->release();
+    gEmptyStringBuf = NULL;
+    gEmptyString = NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+static char* allocFromUTF8(const char* in, size_t len)
+{
+    if (len > 0) {
+        SharedBuffer* buf = SharedBuffer::alloc(len+1);
+        LOG_ASSERT(buf, "Unable to allocate shared buffer");
+        if (buf) {
+            char* str = (char*)buf->data();
+            memcpy(str, in, len);
+            str[len] = 0;
+            return str;
+        }
+        return NULL;
+    }
+
+    return getEmptyString();
+}
+
+// Note: not dealing with expanding surrogate pairs.
+static char* allocFromUTF16(const char16_t* in, size_t len)
+{
+    if (len == 0) return getEmptyString();
+    
+    size_t bytes = 0;
+    const char16_t* end = in+len;
+    const char16_t* p = in;
+    
+    while (p < end) {
+        bytes += utf32_to_utf8_bytes(*p);
+        p++;
+    }
+    
+    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        p = in;
+        char* str = (char*)buf->data();
+        char* d = str;
+        while (p < end) {
+            uint32_t c = *p++;
+            size_t len = utf32_to_utf8_bytes(c);
+            utf32_to_utf8((uint8_t*)d, c, len);
+            d += len;
+        }
+        *d = 0;
+        
+        return str;
+    }
+    
+    return getEmptyString();
+}
+
+// ---------------------------------------------------------------------------
+
+String8::String8()
+    : mString(getEmptyString())
+{
+}
+
+String8::String8(const String8& o)
+    : mString(o.mString)
+{
+    SharedBuffer::bufferFromData(mString)->acquire();
+}
+
+String8::String8(const char* o)
+    : mString(allocFromUTF8(o, strlen(o)))
+{
+    if (mString == NULL) {
+        mString = getEmptyString();
+    }
+}
+
+String8::String8(const char* o, size_t len)
+    : mString(allocFromUTF8(o, len))
+{
+    if (mString == NULL) {
+        mString = getEmptyString();
+    }
+}
+
+String8::String8(const String16& o)
+    : mString(allocFromUTF16(o.string(), o.size()))
+{
+}
+
+String8::String8(const char16_t* o)
+    : mString(allocFromUTF16(o, strlen16(o)))
+{
+}
+
+String8::String8(const char16_t* o, size_t len)
+    : mString(allocFromUTF16(o, len))
+{
+}
+
+String8::~String8()
+{
+    SharedBuffer::bufferFromData(mString)->release();
+}
+
+void String8::setTo(const String8& other)
+{
+    SharedBuffer::bufferFromData(other.mString)->acquire();
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = other.mString;
+}
+
+status_t String8::setTo(const char* other)
+{
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = allocFromUTF8(other, strlen(other));
+    if (mString) return NO_ERROR;
+
+    mString = getEmptyString();
+    return NO_MEMORY;
+}
+
+status_t String8::setTo(const char* other, size_t len)
+{
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = allocFromUTF8(other, len);
+    if (mString) return NO_ERROR;
+
+    mString = getEmptyString();
+    return NO_MEMORY;
+}
+
+status_t String8::setTo(const char16_t* other, size_t len)
+{
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = allocFromUTF16(other, len);
+    if (mString) return NO_ERROR;
+
+    mString = getEmptyString();
+    return NO_MEMORY;
+}
+
+status_t String8::append(const String8& other)
+{
+    const size_t otherLen = other.bytes();
+    if (bytes() == 0) {
+        setTo(other);
+        return NO_ERROR;
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+
+    return real_append(other.string(), otherLen);
+}
+
+status_t String8::append(const char* other)
+{
+    return append(other, strlen(other));
+}
+
+status_t String8::append(const char* other, size_t otherLen)
+{
+    if (bytes() == 0) {
+        return setTo(other, otherLen);
+    } else if (otherLen == 0) {
+        return NO_ERROR;
+    }
+
+    return real_append(other, otherLen);
+}
+
+status_t String8::real_append(const char* other, size_t otherLen)
+{
+    const size_t myLen = bytes();
+    
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize(myLen+otherLen+1);
+    if (buf) {
+        char* str = (char*)buf->data();
+        memcpy(str+myLen, other, otherLen+1);
+        mString = str;
+        return NO_ERROR;
+    }
+    return NO_MEMORY;
+}
+
+char* String8::lockBuffer(size_t size)
+{
+    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
+        ->editResize(size+1);
+    if (buf) {
+        char* str = (char*)buf->data();
+        mString = str;
+        return str;
+    }
+    return NULL;
+}
+
+void String8::unlockBuffer()
+{
+    unlockBuffer(strlen(mString));
+}
+
+status_t String8::unlockBuffer(size_t size)
+{
+    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;
+        }
+    }
+    
+    return NO_MEMORY;
+}
+
+ssize_t String8::find(const char* other, size_t start) const
+{
+    size_t len = size();
+    if (start >= len) {
+        return -1;
+    }
+    const char* s = mString+start;
+    const char* p = strstr(s, other);
+    return p ? p-mString : -1;
+}
+
+void String8::toLower()
+{
+    toLower(0, size());
+}
+
+void String8::toLower(size_t start, size_t length)
+{
+    const size_t len = size();
+    if (start >= len) {
+        return;
+    }
+    if (start+length > len) {
+        length = len-start;
+    }
+    char* buf = lockBuffer(len);
+    buf += start;
+    while (length > 0) {
+        *buf = tolower(*buf);
+        buf++;
+        length--;
+    }
+    unlockBuffer(len);
+}
+
+void String8::toUpper()
+{
+    toUpper(0, size());
+}
+
+void String8::toUpper(size_t start, size_t length)
+{
+    const size_t len = size();
+    if (start >= len) {
+        return;
+    }
+    if (start+length > len) {
+        length = len-start;
+    }
+    char* buf = lockBuffer(len);
+    buf += start;
+    while (length > 0) {
+        *buf = toupper(*buf);
+        buf++;
+        length--;
+    }
+    unlockBuffer(len);
+}
+
+TextOutput& operator<<(TextOutput& to, const String8& val)
+{
+    to << val.string();
+    return to;
+}
+
+// ---------------------------------------------------------------------------
+// Path functions
+
+
+void String8::setPathName(const char* name)
+{
+    setPathName(name, strlen(name));
+}
+
+void String8::setPathName(const char* name, size_t len)
+{
+    char* buf = lockBuffer(len);
+
+    memcpy(buf, name, len);
+
+    // remove trailing path separator, if present
+    if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR)
+        len--;
+
+    buf[len] = '\0';
+
+    unlockBuffer(len);
+}
+
+String8 String8::getPathLeaf(void) const
+{
+    const char* cp;
+    const char*const buf = mString;
+
+    cp = strrchr(buf, OS_PATH_SEPARATOR);
+    if (cp == NULL)
+        return String8(*this);
+    else
+        return String8(cp+1);
+}
+
+String8 String8::getPathDir(void) const
+{
+    const char* cp;
+    const char*const str = mString;
+
+    cp = strrchr(str, OS_PATH_SEPARATOR);
+    if (cp == NULL)
+        return String8("");
+    else
+        return String8(str, cp - str);
+}
+
+String8 String8::walkPath(String8* outRemains) const
+{
+    const char* cp;
+    const char*const str = mString;
+    const char* buf = str;
+
+    cp = strchr(buf, OS_PATH_SEPARATOR);
+    if (cp == buf) {
+        // don't include a leading '/'.
+        buf = buf+1;
+        cp = strchr(buf, OS_PATH_SEPARATOR);
+    }
+
+    if (cp == NULL) {
+        String8 res = buf != str ? String8(buf) : *this;
+        if (outRemains) *outRemains = String8("");
+        return res;
+    }
+
+    String8 res(buf, cp-buf);
+    if (outRemains) *outRemains = String8(cp+1);
+    return res;
+}
+
+/*
+ * Helper function for finding the start of an extension in a pathname.
+ *
+ * Returns a pointer inside mString, or NULL if no extension was found.
+ */
+char* String8::find_extension(void) const
+{
+    const char* lastSlash;
+    const char* lastDot;
+    int extLen;
+    const char* const str = mString;
+
+    // only look at the filename
+    lastSlash = strrchr(str, OS_PATH_SEPARATOR);
+    if (lastSlash == NULL)
+        lastSlash = str;
+    else
+        lastSlash++;
+
+    // find the last dot
+    lastDot = strrchr(lastSlash, '.');
+    if (lastDot == NULL)
+        return NULL;
+
+    // looks good, ship it
+    return const_cast<char*>(lastDot);
+}
+
+String8 String8::getPathExtension(void) const
+{
+    char* ext;
+
+    ext = find_extension();
+    if (ext != NULL)
+        return String8(ext);
+    else
+        return String8("");
+}
+
+String8 String8::getBasePath(void) const
+{
+    char* ext;
+    const char* const str = mString;
+
+    ext = find_extension();
+    if (ext == NULL)
+        return String8(*this);
+    else
+        return String8(str, ext - str);
+}
+
+String8& String8::appendPath(const char* name)
+{
+    // TODO: The test below will fail for Win32 paths. Fix later or ignore.
+    if (name[0] != OS_PATH_SEPARATOR) {
+        if (*name == '\0') {
+            // nothing to do
+            return *this;
+        }
+
+        size_t len = length();
+        if (len == 0) {
+            // no existing filename, just use the new one
+            setPathName(name);
+            return *this;
+        }
+
+        // make room for oldPath + '/' + newPath
+        int newlen = strlen(name);
+
+        char* buf = lockBuffer(len+1+newlen);
+
+        // insert a '/' if needed
+        if (buf[len-1] != OS_PATH_SEPARATOR)
+            buf[len++] = OS_PATH_SEPARATOR;
+
+        memcpy(buf+len, name, newlen+1);
+        len += newlen;
+
+        unlockBuffer(len);
+
+        return *this;
+    } else {
+        setPathName(name);
+        return *this;
+    }
+}
+
+String8& String8::convertToResPath()
+{
+#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR
+    size_t len = length();
+    if (len > 0) {
+        char * buf = lockBuffer(len);
+        for (char * end = buf + len; buf < end; ++buf) {
+            if (*buf == OS_PATH_SEPARATOR)
+                *buf = RES_PATH_SEPARATOR;
+        }
+        unlockBuffer(len);
+    }
+#endif
+    return *this;
+}
+
+
+}; // namespace android
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
new file mode 100644
index 0000000..2bdc0ce
--- /dev/null
+++ b/libs/utils/SystemClock.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * System clock functions.
+ */
+
+#if HAVE_ANDROID_OS
+#include <linux/ioctl.h>
+#include <linux/rtc.h>
+#include <utils/Atomic.h>
+#include <linux/android_alarm.h>
+#endif
+
+#include <sys/time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <utils/SystemClock.h>
+#include <utils/Timers.h>
+
+#define LOG_TAG "SystemClock"
+#include "utils/Log.h"
+
+namespace android {
+
+/*
+ * Set the current time.  This only works when running as root.
+ */
+int setCurrentTimeMillis(int64_t millis)
+{
+#if WIN32
+    // not implemented
+    return -1;
+#else
+    struct timeval tv;
+#if HAVE_ANDROID_OS
+    struct timespec ts;
+    int fd;
+    int res;
+#endif
+    int ret = 0;
+
+    if (millis <= 0 || millis / 1000LL >= INT_MAX) {
+        return -1;
+    }
+
+    tv.tv_sec = (time_t) (millis / 1000LL);
+    tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
+
+    LOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
+
+#if HAVE_ANDROID_OS
+    fd = open("/dev/alarm", O_RDWR);
+    if(fd < 0) {
+        LOGW("Unable to open alarm driver: %s\n", strerror(errno));
+        return -1;
+    }
+    ts.tv_sec = tv.tv_sec;
+    ts.tv_nsec = tv.tv_usec * 1000;
+    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
+    if(res < 0) {
+        LOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
+        ret = -1;
+    }
+    close(fd);
+#else
+    if (settimeofday(&tv, NULL) != 0) {
+        LOGW("Unable to set clock to %d.%d: %s\n",
+            (int) tv.tv_sec, (int) tv.tv_usec, strerror(errno));
+        ret = -1;
+    }
+#endif
+
+    return ret;
+#endif // WIN32
+}
+
+/*
+ * native public static long uptimeMillis();
+ */
+int64_t uptimeMillis()
+{
+    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+    return (int64_t) nanoseconds_to_milliseconds(when);
+}
+
+/*
+ * native public static long elapsedRealtime();
+ */
+int64_t elapsedRealtime()
+{
+#if HAVE_ANDROID_OS
+    static int s_fd = -1;
+
+    if (s_fd == -1) {
+        int fd = open("/dev/alarm", O_RDONLY);
+        if (android_atomic_cmpxchg(-1, fd, &s_fd)) {
+            close(fd);
+        }
+    }
+
+    struct timespec ts;
+    int result = ioctl(s_fd,
+            ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts);
+
+    if (result == 0) {
+        int64_t when = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec;
+        return (int64_t) nanoseconds_to_milliseconds(when);
+    } else {
+        // XXX: there was an error, probably because the driver didn't
+        // exist ... this should return
+        // a real error, like an exception!
+        int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+        return (int64_t) nanoseconds_to_milliseconds(when);
+    }
+#else
+    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+    return (int64_t) nanoseconds_to_milliseconds(when);
+#endif
+}
+
+}; // namespace android
diff --git a/libs/utils/TextOutput.cpp b/libs/utils/TextOutput.cpp
new file mode 100644
index 0000000..cebee99
--- /dev/null
+++ b/libs/utils/TextOutput.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/TextOutput.h>
+
+#include <utils/Debug.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+TextOutput& operator<<(TextOutput& to, bool val)
+{
+    if (val) to.print("true", 4);
+    else to.print("false", 5);
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, int val)
+{
+    char buf[16];
+    sprintf(buf, "%d", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, long val)
+{
+    char buf[16];
+    sprintf(buf, "%ld", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, unsigned int val)
+{
+    char buf[16];
+    sprintf(buf, "%u", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, unsigned long val)
+{
+    char buf[16];
+    sprintf(buf, "%lu", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, long long val)
+{
+    char buf[32];
+    sprintf(buf, "%Ld", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, unsigned long long val)
+{
+    char buf[32];
+    sprintf(buf, "%Lu", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+static TextOutput& print_float(TextOutput& to, double value)
+{
+    char buf[64];
+    sprintf(buf, "%g", value);
+    if( !strchr(buf, '.') && !strchr(buf, 'e') &&
+        !strchr(buf, 'E') ) {
+        strncat(buf, ".0", sizeof(buf)-1);
+    }
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, float val)
+{
+    return print_float(to,val);
+}
+
+TextOutput& operator<<(TextOutput& to, double val)
+{
+    return print_float(to,val);
+}
+
+TextOutput& operator<<(TextOutput& to, const void* val)
+{
+    char buf[16];
+    sprintf(buf, "%p", val);
+    to.print(buf, strlen(buf));
+    return to;
+}
+
+static void textOutputPrinter(void* cookie, const char* txt)
+{
+    ((TextOutput*)cookie)->print(txt, strlen(txt));
+}
+
+TextOutput& operator<<(TextOutput& to, const TypeCode& val)
+{
+    printTypeCode(val.typeCode(), textOutputPrinter, (void*)&to);
+    return to;
+}
+
+HexDump::HexDump(const void *buf, size_t size, size_t bytesPerLine)
+    : mBuffer(buf)
+    , mSize(size)
+    , mBytesPerLine(bytesPerLine)
+    , mSingleLineCutoff(16)
+    , mAlignment(4)
+    , mCArrayStyle(false)
+{
+    if (bytesPerLine >= 16) mAlignment = 4;
+    else if (bytesPerLine >= 8) mAlignment = 2;
+    else mAlignment = 1;
+}
+
+TextOutput& operator<<(TextOutput& to, const HexDump& val)
+{
+    printHexData(0, val.buffer(), val.size(), val.bytesPerLine(),
+        val.singleLineCutoff(), val.alignment(), val.carrayStyle(),
+        textOutputPrinter, (void*)&to);
+    return to;
+}
+
+}; // namespace android
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
new file mode 100644
index 0000000..74271ba
--- /dev/null
+++ b/libs/utils/Threads.cpp
@@ -0,0 +1,1126 @@
+/*
+ * 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 "libutils.threads"
+
+#include <utils/threads.h>
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+# include <sched.h>
+# include <sys/resource.h>
+#elif defined(HAVE_WIN32_THREADS)
+# include <windows.h>
+# include <stdint.h>
+# include <process.h>
+# define HAVE_CREATETHREAD  // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW
+#endif
+
+#if defined(HAVE_FUTEX)
+#include <private/utils/futex_synchro.h>
+#endif
+
+#if defined(HAVE_PRCTL)
+#include <sys/prctl.h>
+#endif
+
+/*
+ * ===========================================================================
+ *      Thread wrappers
+ * ===========================================================================
+ */
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+#if defined(HAVE_PTHREADS)
+#if 0
+#pragma mark -
+#pragma mark PTHREAD
+#endif
+// ----------------------------------------------------------------------------
+
+/*
+ * Create and run a new thead.
+ *
+ * We create it "detached", so it cleans up after itself.
+ */
+
+typedef void* (*android_pthread_entry)(void*);
+
+struct thread_data_t {
+    thread_func_t   entryFunction;
+    void*           userData;
+    int             priority;
+    char *          threadName;
+
+    // we use this trampoline when we need to set the priority with
+    // nice/setpriority.
+    static int trampoline(const thread_data_t* t) {
+        thread_func_t f = t->entryFunction;
+        void* u = t->userData;
+        int prio = t->priority;
+        char * name = t->threadName;
+        delete t;
+        setpriority(PRIO_PROCESS, 0, prio);
+        if (name) {
+#if defined(HAVE_PRCTL)
+            // Mac OS doesn't have this, and we build libutil for the host too
+            int hasAt = 0;
+            int hasDot = 0;
+            char *s = name;
+            while (*s) {
+                if (*s == '.') hasDot = 1;
+                else if (*s == '@') hasAt = 1;
+                s++;
+            }
+            int len = s - name;
+            if (len < 15 || hasAt || !hasDot) {
+                s = name;
+            } else {
+                s = name + len - 15;
+            }
+            prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
+#endif
+            free(name);
+        }
+        return f(u);
+    }
+};
+
+int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
+                               void *userData,
+                               const char* threadName,
+                               int32_t threadPriority,
+                               size_t threadStackSize,
+                               android_thread_id_t *threadId)
+{
+    pthread_attr_t attr; 
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+#ifdef HAVE_ANDROID_OS  /* valgrind is rejecting RT-priority create reqs */
+    if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
+        // We could avoid the trampoline if there was a way to get to the
+        // android_thread_id_t (pid) from pthread_t
+        thread_data_t* t = new thread_data_t;
+        t->priority = threadPriority;
+        t->threadName = threadName ? strdup(threadName) : NULL;
+        t->entryFunction = entryFunction;
+        t->userData = userData;
+        entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
+        userData = t;            
+    }
+#endif
+
+    if (threadStackSize) {
+        pthread_attr_setstacksize(&attr, threadStackSize);
+    }
+    
+    errno = 0;
+    pthread_t thread;
+    int result = pthread_create(&thread, &attr,
+                    (android_pthread_entry)entryFunction, userData);
+    if (result != 0) {
+        LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
+             "(android threadPriority=%d)",
+            entryFunction, result, errno, threadPriority);
+        return 0;
+    }
+
+    if (threadId != NULL) {
+        *threadId = (android_thread_id_t)thread; // XXX: this is not portable
+    }
+    return 1;
+}
+
+android_thread_id_t androidGetThreadId()
+{
+    return (android_thread_id_t)pthread_self();
+}
+
+// ----------------------------------------------------------------------------
+#elif defined(HAVE_WIN32_THREADS)
+#if 0
+#pragma mark -
+#pragma mark WIN32_THREADS
+#endif
+// ----------------------------------------------------------------------------
+
+/*
+ * Trampoline to make us __stdcall-compliant.
+ *
+ * We're expected to delete "vDetails" when we're done.
+ */
+struct threadDetails {
+    int (*func)(void*);
+    void* arg;
+};
+static __stdcall unsigned int threadIntermediary(void* vDetails)
+{
+    struct threadDetails* pDetails = (struct threadDetails*) vDetails;
+    int result;
+
+    result = (*(pDetails->func))(pDetails->arg);
+
+    delete pDetails;
+
+    LOG(LOG_VERBOSE, "thread", "thread exiting\n");
+    return (unsigned int) result;
+}
+
+/*
+ * Create and run a new thread.
+ */
+static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id)
+{
+    HANDLE hThread;
+    struct threadDetails* pDetails = new threadDetails; // must be on heap
+    unsigned int thrdaddr;
+
+    pDetails->func = fn;
+    pDetails->arg = arg;
+
+#if defined(HAVE__BEGINTHREADEX)
+    hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,
+                    &thrdaddr);
+    if (hThread == 0)
+#elif defined(HAVE_CREATETHREAD)
+    hThread = CreateThread(NULL, 0,
+                    (LPTHREAD_START_ROUTINE) threadIntermediary,
+                    (void*) pDetails, 0, (DWORD*) &thrdaddr);
+    if (hThread == NULL)
+#endif
+    {
+        LOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
+        return false;
+    }
+
+#if defined(HAVE_CREATETHREAD)
+    /* close the management handle */
+    CloseHandle(hThread);
+#endif
+
+    if (id != NULL) {
+      	*id = (android_thread_id_t)thrdaddr;
+    }
+
+    return true;
+}
+
+int androidCreateRawThreadEtc(android_thread_func_t fn,
+                               void *userData,
+                               const char* threadName,
+                               int32_t threadPriority,
+                               size_t threadStackSize,
+                               android_thread_id_t *threadId)
+{
+    return doCreateThread(  fn, userData, threadId);
+}
+
+android_thread_id_t androidGetThreadId()
+{
+    return (android_thread_id_t)GetCurrentThreadId();
+}
+
+// ----------------------------------------------------------------------------
+#else
+#error "Threads not supported"
+#endif
+
+// ----------------------------------------------------------------------------
+
+#if 0
+#pragma mark -
+#pragma mark Common Thread functions
+#endif
+
+int androidCreateThread(android_thread_func_t fn, void* arg)
+{
+    return createThreadEtc(fn, arg);
+}
+
+int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id)
+{
+    return createThreadEtc(fn, arg, "android:unnamed_thread",
+                           PRIORITY_DEFAULT, 0, id);
+}
+
+static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
+
+int androidCreateThreadEtc(android_thread_func_t entryFunction,
+                            void *userData,
+                            const char* threadName,
+                            int32_t threadPriority,
+                            size_t threadStackSize,
+                            android_thread_id_t *threadId)
+{
+    return gCreateThreadFn(entryFunction, userData, threadName,
+        threadPriority, threadStackSize, threadId);
+}
+
+void androidSetCreateThreadFunc(android_create_thread_fn func)
+{
+    gCreateThreadFn = func;
+}
+
+namespace android {
+
+/*
+ * ===========================================================================
+ *      Mutex class
+ * ===========================================================================
+ */
+
+#if 0
+#pragma mark -
+#pragma mark Mutex
+#endif
+
+#if defined(HAVE_PTHREADS) && !defined(HAVE_FUTEX)
+/*
+ * Simple pthread wrapper.
+ */
+
+Mutex::Mutex()
+{
+    _init();
+}
+
+Mutex::Mutex(const char* name)
+{
+    // XXX: name not used for now
+    _init();
+}
+
+void Mutex::_init()
+{
+    pthread_mutex_t* pMutex = new pthread_mutex_t;
+    pthread_mutex_init(pMutex, NULL);
+    mState = pMutex;
+}
+
+Mutex::~Mutex()
+{
+    delete (pthread_mutex_t*) mState;
+}
+
+status_t Mutex::lock()
+{
+    int res;
+    while ((res=pthread_mutex_lock((pthread_mutex_t*) mState)) == EINTR) ;
+    return -res;
+}
+
+void Mutex::unlock()
+{
+    pthread_mutex_unlock((pthread_mutex_t*) mState);
+}
+
+status_t Mutex::tryLock()
+{
+    int res;
+    while ((res=pthread_mutex_trylock((pthread_mutex_t*) mState)) == EINTR) ;
+    return -res;
+}
+
+#elif defined(HAVE_FUTEX)
+#if 0
+#pragma mark -
+#endif
+
+#define STATE ((futex_mutex_t*) (&mState))
+
+Mutex::Mutex()
+{
+    _init();
+}
+
+Mutex::Mutex(const char* name)
+{
+    _init();
+}
+
+void
+Mutex::_init()
+{
+    futex_mutex_init(STATE);
+}
+
+Mutex::~Mutex()
+{
+}
+
+status_t Mutex::lock()
+{
+    int res;
+    while ((res=futex_mutex_lock(STATE, FUTEX_WAIT_INFINITE)) == EINTR) ;
+    return -res;
+}
+
+void Mutex::unlock()
+{
+    futex_mutex_unlock(STATE);
+}
+
+status_t Mutex::tryLock()
+{
+    int res;
+    while ((res=futex_mutex_trylock(STATE)) == EINTR) ;
+    return -res;
+}
+#undef STATE
+
+#elif defined(HAVE_WIN32_THREADS)
+#if 0
+#pragma mark -
+#endif
+
+Mutex::Mutex()
+{
+    HANDLE hMutex;
+
+    assert(sizeof(hMutex) == sizeof(mState));
+
+    hMutex = CreateMutex(NULL, FALSE, NULL);
+    mState = (void*) hMutex;
+}
+
+Mutex::Mutex(const char* name)
+{
+    // XXX: name not used for now
+    HANDLE hMutex;
+
+    hMutex = CreateMutex(NULL, FALSE, NULL);
+    mState = (void*) hMutex;
+}
+
+Mutex::~Mutex()
+{
+    CloseHandle((HANDLE) mState);
+}
+
+status_t Mutex::lock()
+{
+    DWORD dwWaitResult;
+    dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE);
+    return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR;
+}
+
+void Mutex::unlock()
+{
+    if (!ReleaseMutex((HANDLE) mState))
+        LOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
+}
+
+status_t Mutex::tryLock()
+{
+    DWORD dwWaitResult;
+
+    dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
+    if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
+        LOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
+    return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
+}
+
+#else
+#error "Somebody forgot to implement threads for this platform."
+#endif
+
+
+/*
+ * ===========================================================================
+ *      Condition class
+ * ===========================================================================
+ */
+
+#if 0
+#pragma mark -
+#pragma mark Condition
+#endif
+
+#if defined(HAVE_PTHREADS) && !defined(HAVE_FUTEX)
+
+/*
+ * Constructor.  This is a simple pthread wrapper.
+ */
+Condition::Condition()
+{
+    pthread_cond_t* pCond = new pthread_cond_t;
+
+    pthread_cond_init(pCond, NULL);
+    mState = pCond;
+}
+
+/*
+ * Destructor.
+ */
+Condition::~Condition()
+{
+    pthread_cond_destroy((pthread_cond_t*) mState);
+    delete (pthread_cond_t*) mState;
+}
+
+/*
+ * Wait on a condition variable.  Lock the mutex before calling.
+ */
+
+status_t Condition::wait(Mutex& mutex)
+{
+    assert(mutex.mState != NULL);
+
+    int cc;
+    while ((cc = pthread_cond_wait((pthread_cond_t*)mState,
+                (pthread_mutex_t*) mutex.mState)) == EINTR) ;
+    return -cc;
+}
+
+status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
+{
+    assert(mutex.mState != NULL);
+
+    struct timespec ts;
+    ts.tv_sec = abstime/1000000000;
+    ts.tv_nsec = abstime-(ts.tv_sec*1000000000);
+    
+    int cc;
+    while ((cc = pthread_cond_timedwait((pthread_cond_t*)mState,
+            (pthread_mutex_t*) mutex.mState, &ts)) == EINTR) ;
+    return -cc;
+}
+
+status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
+{
+    return wait(mutex, systemTime()+reltime);
+}
+
+/*
+ * Signal the condition variable, allowing one thread to continue.
+ */
+void Condition::signal()
+{
+    pthread_cond_signal((pthread_cond_t*) mState);
+}
+
+/*
+ * Signal the condition variable, allowing all threads to continue.
+ */
+void Condition::broadcast()
+{
+    pthread_cond_broadcast((pthread_cond_t*) mState);
+}
+
+#elif defined(HAVE_FUTEX)
+#if 0
+#pragma mark -
+#endif
+
+#define STATE ((futex_cond_t*) (&mState))
+
+/*
+ * Constructor.  This is a simple pthread wrapper.
+ */
+Condition::Condition()
+{
+    futex_cond_init(STATE);
+}
+
+/*
+ * Destructor.
+ */
+Condition::~Condition()
+{
+}
+
+/*
+ * Wait on a condition variable.  Lock the mutex before calling.
+ */
+
+status_t Condition::wait(Mutex& mutex)
+{
+    assert(mutex.mState != NULL);
+
+    int res;
+    while ((res = futex_cond_wait(STATE,
+        (futex_mutex_t*)(&mutex.mState), FUTEX_WAIT_INFINITE)) == -EINTR) ;
+
+    return -res;
+}
+
+status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
+{
+    nsecs_t reltime = abstime - systemTime();
+    if (reltime <= 0) return true;
+    return waitRelative(mutex, reltime);
+}
+
+status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
+{
+    assert(mutex.mState != NULL);
+    int res;
+    unsigned msec = ns2ms(reltime);
+    if(msec == 0)
+        return true;
+    // This code will not time out at the correct time if interrupted by signals
+    while ((res = futex_cond_wait(STATE,
+        (futex_mutex_t*)(&mutex.mState), msec)) == -EINTR) ;
+    return res;
+}
+
+/*
+ * Signal the condition variable, allowing one thread to continue.
+ */
+void Condition::signal()
+{
+    futex_cond_signal(STATE);
+}
+
+/*
+ * Signal the condition variable, allowing all threads to continue.
+ */
+void Condition::broadcast()
+{
+    futex_cond_broadcast(STATE);
+}
+
+#undef STATE
+
+#elif defined(HAVE_WIN32_THREADS)
+#if 0
+#pragma mark -
+#endif
+
+/*
+ * Windows doesn't have a condition variable solution.  It's possible
+ * to create one, but it's easy to get it wrong.  For a discussion, and
+ * the origin of this implementation, see:
+ *
+ *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ *
+ * The implementation shown on the page does NOT follow POSIX semantics.
+ * As an optimization they require acquiring the external mutex before
+ * calling signal() and broadcast(), whereas POSIX only requires grabbing
+ * it before calling wait().  The implementation here has been un-optimized
+ * to have the correct behavior.
+ */
+typedef struct WinCondition {
+    // Number of waiting threads.
+    int                 waitersCount;
+
+    // Serialize access to waitersCount.
+    CRITICAL_SECTION    waitersCountLock;
+
+    // Semaphore used to queue up threads waiting for the condition to
+    // become signaled.
+    HANDLE              sema;
+
+    // An auto-reset event used by the broadcast/signal thread to wait
+    // for all the waiting thread(s) to wake up and be released from
+    // the semaphore.
+    HANDLE              waitersDone;
+
+    // This mutex wouldn't be necessary if we required that the caller
+    // lock the external mutex before calling signal() and broadcast().
+    // I'm trying to mimic pthread semantics though.
+    HANDLE              internalMutex;
+
+    // Keeps track of whether we were broadcasting or signaling.  This
+    // allows us to optimize the code if we're just signaling.
+    bool                wasBroadcast;
+
+    status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime)
+    {
+        // Increment the wait count, avoiding race conditions.
+        EnterCriticalSection(&condState->waitersCountLock);
+        condState->waitersCount++;
+        //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n",
+        //    condState->waitersCount, getThreadId());
+        LeaveCriticalSection(&condState->waitersCountLock);
+    
+        DWORD timeout = INFINITE;
+        if (abstime) {
+            nsecs_t reltime = *abstime - systemTime();
+            if (reltime < 0)
+                reltime = 0;
+            timeout = reltime/1000000;
+        }
+        
+        // Atomically release the external mutex and wait on the semaphore.
+        DWORD res =
+            SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE);
+    
+        //printf("+++ wait: awake (tid=%ld)\n", getThreadId());
+    
+        // Reacquire lock to avoid race conditions.
+        EnterCriticalSection(&condState->waitersCountLock);
+    
+        // No longer waiting.
+        condState->waitersCount--;
+    
+        // Check to see if we're the last waiter after a broadcast.
+        bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0);
+    
+        //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n",
+        //    lastWaiter, condState->wasBroadcast, condState->waitersCount);
+    
+        LeaveCriticalSection(&condState->waitersCountLock);
+    
+        // If we're the last waiter thread during this particular broadcast
+        // then signal broadcast() that we're all awake.  It'll drop the
+        // internal mutex.
+        if (lastWaiter) {
+            // Atomically signal the "waitersDone" event and wait until we
+            // can acquire the internal mutex.  We want to do this in one step
+            // because it ensures that everybody is in the mutex FIFO before
+            // any thread has a chance to run.  Without it, another thread
+            // could wake up, do work, and hop back in ahead of us.
+            SignalObjectAndWait(condState->waitersDone, condState->internalMutex,
+                INFINITE, FALSE);
+        } else {
+            // Grab the internal mutex.
+            WaitForSingleObject(condState->internalMutex, INFINITE);
+        }
+    
+        // Release the internal and grab the external.
+        ReleaseMutex(condState->internalMutex);
+        WaitForSingleObject(hMutex, INFINITE);
+    
+        return res == WAIT_OBJECT_0 ? NO_ERROR : -1;
+    }
+} WinCondition;
+
+/*
+ * Constructor.  Set up the WinCondition stuff.
+ */
+Condition::Condition()
+{
+    WinCondition* condState = new WinCondition;
+
+    condState->waitersCount = 0;
+    condState->wasBroadcast = false;
+    // semaphore: no security, initial value of 0
+    condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
+    InitializeCriticalSection(&condState->waitersCountLock);
+    // auto-reset event, not signaled initially
+    condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
+    // used so we don't have to lock external mutex on signal/broadcast
+    condState->internalMutex = CreateMutex(NULL, FALSE, NULL);
+
+    mState = condState;
+}
+
+/*
+ * Destructor.  Free Windows resources as well as our allocated storage.
+ */
+Condition::~Condition()
+{
+    WinCondition* condState = (WinCondition*) mState;
+    if (condState != NULL) {
+        CloseHandle(condState->sema);
+        CloseHandle(condState->waitersDone);
+        delete condState;
+    }
+}
+
+
+status_t Condition::wait(Mutex& mutex)
+{
+    WinCondition* condState = (WinCondition*) mState;
+    HANDLE hMutex = (HANDLE) mutex.mState;
+    
+    return ((WinCondition*)mState)->wait(condState, hMutex, NULL);
+}
+
+status_t Condition::wait(Mutex& mutex, nsecs_t abstime)
+{
+    WinCondition* condState = (WinCondition*) mState;
+    HANDLE hMutex = (HANDLE) mutex.mState;
+
+    return ((WinCondition*)mState)->wait(condState, hMutex, &abstime);
+}
+
+status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
+{
+    return wait(mutex, systemTime()+reltime);
+}
+
+/*
+ * Signal the condition variable, allowing one thread to continue.
+ */
+void Condition::signal()
+{
+    WinCondition* condState = (WinCondition*) mState;
+
+    // Lock the internal mutex.  This ensures that we don't clash with
+    // broadcast().
+    WaitForSingleObject(condState->internalMutex, INFINITE);
+
+    EnterCriticalSection(&condState->waitersCountLock);
+    bool haveWaiters = (condState->waitersCount > 0);
+    LeaveCriticalSection(&condState->waitersCountLock);
+
+    // If no waiters, then this is a no-op.  Otherwise, knock the semaphore
+    // down a notch.
+    if (haveWaiters)
+        ReleaseSemaphore(condState->sema, 1, 0);
+
+    // Release internal mutex.
+    ReleaseMutex(condState->internalMutex);
+}
+
+/*
+ * Signal the condition variable, allowing all threads to continue.
+ *
+ * First we have to wake up all threads waiting on the semaphore, then
+ * we wait until all of the threads have actually been woken before
+ * releasing the internal mutex.  This ensures that all threads are woken.
+ */
+void Condition::broadcast()
+{
+    WinCondition* condState = (WinCondition*) mState;
+
+    // Lock the internal mutex.  This keeps the guys we're waking up
+    // from getting too far.
+    WaitForSingleObject(condState->internalMutex, INFINITE);
+
+    EnterCriticalSection(&condState->waitersCountLock);
+    bool haveWaiters = false;
+
+    if (condState->waitersCount > 0) {
+        haveWaiters = true;
+        condState->wasBroadcast = true;
+    }
+
+    if (haveWaiters) {
+        // Wake up all the waiters.
+        ReleaseSemaphore(condState->sema, condState->waitersCount, 0);
+
+        LeaveCriticalSection(&condState->waitersCountLock);
+
+        // Wait for all awakened threads to acquire the counting semaphore.
+        // The last guy who was waiting sets this.
+        WaitForSingleObject(condState->waitersDone, INFINITE);
+
+        // Reset wasBroadcast.  (No crit section needed because nobody
+        // else can wake up to poke at it.)
+        condState->wasBroadcast = 0;
+    } else {
+        // nothing to do
+        LeaveCriticalSection(&condState->waitersCountLock);
+    }
+
+    // Release internal mutex.
+    ReleaseMutex(condState->internalMutex);
+}
+
+#else
+#error "condition variables not supported on this platform"
+#endif
+
+
+/*
+ * ===========================================================================
+ *      ReadWriteLock class
+ * ===========================================================================
+ */
+
+#if 0
+#pragma mark -
+#pragma mark ReadWriteLock
+#endif
+
+/*
+ * Add a reader.  Readers are nice.  They share.
+ */
+void ReadWriteLock::lockForRead()
+{
+    mLock.lock();
+    while (mNumWriters > 0) {
+        LOG(LOG_DEBUG, "thread", "+++ lockForRead: waiting\n");
+        mReadWaiter.wait(mLock);
+    }
+    assert(mNumWriters == 0);
+    mNumReaders++;
+#if defined(PRINT_RENDER_TIMES)
+    if (mNumReaders == 1)
+        mDebugTimer.start();
+#endif
+    mLock.unlock();
+}
+
+/*
+ * Try to add a reader.  If it doesn't work right away, return "false".
+ */
+bool ReadWriteLock::tryLockForRead()
+{
+    mLock.lock();
+    if (mNumWriters > 0) {
+        mLock.unlock();
+        return false;
+    }
+    assert(mNumWriters == 0);
+    mNumReaders++;
+#if defined(PRINT_RENDER_TIMES)
+    if (mNumReaders == 1)
+        mDebugTimer.start();
+#endif
+    mLock.unlock();
+    return true;
+}
+
+/*
+ * Remove a reader.
+ */
+void ReadWriteLock::unlockForRead()
+{
+    mLock.lock();
+    if (mNumReaders == 0) {
+        LOG(LOG_WARN, "thread",
+            "WARNING: unlockForRead requested, but not locked\n");
+        return;
+    }
+    assert(mNumReaders > 0);
+    assert(mNumWriters == 0);
+    mNumReaders--;
+    if (mNumReaders == 0) {           // last reader?
+#if defined(PRINT_RENDER_TIMES)
+        mDebugTimer.stop();
+        printf(" rdlk held %.3f msec\n",
+            (double) mDebugTimer.durationUsecs() / 1000.0);
+#endif
+        //printf("+++ signaling writers (if any)\n");
+        mWriteWaiter.signal();      // wake one writer (if any)
+    }
+    mLock.unlock();
+}
+
+/*
+ * Add a writer.  This requires exclusive access to the object.
+ */
+void ReadWriteLock::lockForWrite()
+{
+    mLock.lock();
+    while (mNumReaders > 0 || mNumWriters > 0) {
+        LOG(LOG_DEBUG, "thread", "+++ lockForWrite: waiting\n");
+        mWriteWaiter.wait(mLock);
+    }
+    assert(mNumReaders == 0);
+    assert(mNumWriters == 0);
+    mNumWriters++;
+#if defined(PRINT_RENDER_TIMES)
+    mDebugTimer.start();
+#endif
+    mLock.unlock();
+}
+
+/*
+ * Try to add a writer.  If it doesn't work right away, return "false".
+ */
+bool ReadWriteLock::tryLockForWrite()
+{
+    mLock.lock();
+    if (mNumReaders > 0 || mNumWriters > 0) {
+        mLock.unlock();
+        return false;
+    }
+    assert(mNumReaders == 0);
+    assert(mNumWriters == 0);
+    mNumWriters++;
+#if defined(PRINT_RENDER_TIMES)
+    mDebugTimer.start();
+#endif
+    mLock.unlock();
+    return true;
+}
+
+/*
+ * Remove a writer.
+ */
+void ReadWriteLock::unlockForWrite()
+{
+    mLock.lock();
+    if (mNumWriters == 0) {
+        LOG(LOG_WARN, "thread",
+            "WARNING: unlockForWrite requested, but not locked\n");
+        return;
+    }
+    assert(mNumWriters == 1);
+    mNumWriters--;
+#if defined(PRINT_RENDER_TIMES)
+    mDebugTimer.stop();
+    //printf(" wrlk held %.3f msec\n",
+    //    (double) mDebugTimer.durationUsecs() / 1000.0);
+#endif
+    // mWriteWaiter.signal();       // should other writers get first dibs?
+    //printf("+++ signaling readers (if any)\n");
+    mReadWaiter.broadcast();        // wake all readers (if any)
+    mLock.unlock();
+}
+
+// ----------------------------------------------------------------------------
+
+#if 0
+#pragma mark -
+#pragma mark Thread::Thread
+#endif
+
+/*
+ * This is our thread object!
+ */
+
+Thread::Thread(bool canCallJava)
+    :   mCanCallJava(canCallJava),
+        mThread(thread_id_t(-1)),
+        mLock("Thread::mLock"),
+        mStatus(NO_ERROR),
+        mExitPending(false), mRunning(false)
+{
+}
+
+Thread::~Thread()
+{
+}
+
+status_t Thread::readyToRun()
+{
+    return NO_ERROR;
+}
+
+status_t Thread::run(const char* name, int32_t priority, size_t stack)
+{
+    Mutex::Autolock _l(mLock);
+
+    if (mRunning) {
+        // thread already started
+        return INVALID_OPERATION;
+    }
+
+    // reset status and exitPending to their default value, so we can
+    // try again after an error happened (either below, or in readyToRun())
+    mStatus = NO_ERROR;
+    mExitPending = false;
+    mThread = thread_id_t(-1);
+    
+    // hold a strong reference on ourself
+    mHoldSelf = this;
+
+    bool res;
+    if (mCanCallJava) {
+        res = createThreadEtc(_threadLoop,
+                this, name, priority, stack, &mThread);
+    } else {
+        res = androidCreateRawThreadEtc(_threadLoop,
+                this, name, priority, stack, &mThread);
+    }
+    
+    if (res == false) {
+        mStatus = UNKNOWN_ERROR;   // something happened!
+        mRunning = false;
+        mThread = thread_id_t(-1);
+    }
+    
+    if (mStatus < 0) {
+        // something happened, don't leak
+        mHoldSelf.clear();
+    }
+    
+    return mStatus;
+}
+
+int Thread::_threadLoop(void* user)
+{
+    Thread* const self = static_cast<Thread*>(user);
+    sp<Thread> strong(self->mHoldSelf);
+    wp<Thread> weak(strong);
+    self->mHoldSelf.clear();
+
+    // we're about to run...
+    self->mStatus = self->readyToRun();
+    if (self->mStatus!=NO_ERROR || self->mExitPending) {
+        // pretend the thread never started...
+        self->mExitPending = false;
+        self->mRunning = false;
+        return 0;
+    }
+    
+    // thread is running now
+    self->mRunning = true;
+
+    do {
+        bool result = self->threadLoop();
+        if (result == false || self->mExitPending) {
+            self->mExitPending = true;
+            self->mLock.lock();
+            self->mRunning = false;
+            self->mThreadExitedCondition.signal();
+            self->mLock.unlock();
+            break;
+        }
+        
+        // Release our strong reference, to let a chance to the thread
+        // to die a peaceful death.
+        strong.clear();
+        // And immediately, reacquire a strong reference for the next loop
+        strong = weak.promote();
+    } while(strong != 0);
+    
+    return 0;
+}
+
+void Thread::requestExit()
+{
+    mExitPending = true;
+}
+
+status_t Thread::requestExitAndWait()
+{
+    if (mStatus == OK) {
+
+        if (mThread == getThreadId()) {
+            LOGW(
+            "Thread (this=%p): don't call waitForExit() from this "
+            "Thread object's thread. It's a guaranteed deadlock!",
+            this);
+            return WOULD_BLOCK;
+        }
+        
+        requestExit();
+
+        Mutex::Autolock _l(mLock);
+        while (mRunning == true) {
+            mThreadExitedCondition.wait(mLock);
+        }
+        mExitPending = false;
+    }
+    return mStatus;
+}
+
+bool Thread::exitPending() const
+{
+    return mExitPending;
+}
+
+
+
+};  // namespace android
diff --git a/libs/utils/TimerProbe.cpp b/libs/utils/TimerProbe.cpp
new file mode 100644
index 0000000..835480d
--- /dev/null
+++ b/libs/utils/TimerProbe.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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 <utils/TimerProbe.h>
+ 
+#if ENABLE_TIMER_PROBE
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "time"
+
+namespace android {
+
+Vector<TimerProbe::Bucket> TimerProbe::gBuckets;
+TimerProbe* TimerProbe::gExecuteChain;
+int TimerProbe::gIndent;
+timespec TimerProbe::gRealBase;
+
+TimerProbe::TimerProbe(const char tag[], int* slot) : mTag(tag)
+{
+    mNext = gExecuteChain;
+    gExecuteChain = this;
+    mIndent = gIndent;
+    gIndent += 1;
+    if (mIndent > 0) {
+        if (*slot == 0) {
+            int count = gBuckets.add();
+            *slot = count;
+            Bucket& bucket = gBuckets.editItemAt(count);
+            memset(&bucket, 0, sizeof(Bucket));
+            bucket.mTag = tag;
+            bucket.mSlotPtr = slot;
+            bucket.mIndent = mIndent;
+        }
+        mBucket = *slot;
+    }
+    clock_gettime(CLOCK_REALTIME, &mRealStart);
+    if (gRealBase.tv_sec == 0)
+        gRealBase = mRealStart;
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &mPStart);
+    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &mTStart);
+}
+
+void TimerProbe::end()
+{
+    timespec realEnd, pEnd, tEnd;
+    clock_gettime(CLOCK_REALTIME, &realEnd);
+    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &pEnd);
+    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tEnd);
+    print(realEnd, pEnd, tEnd);
+    mTag = NULL;
+}
+
+TimerProbe::~TimerProbe()
+{
+    if (mTag != NULL)
+        end();
+    gExecuteChain = mNext;
+    gIndent--;
+}
+
+
+uint32_t TimerProbe::ElapsedTime(const timespec& start, const timespec& end)
+{
+    int sec = end.tv_sec - start.tv_sec;
+    int nsec = end.tv_nsec - start.tv_nsec;
+    if (nsec < 0) {
+        sec--;
+        nsec += 1000000000;
+    }
+    return sec * 1000000 + nsec / 1000;
+}
+
+void TimerProbe::print(const timespec& r, const timespec& p,
+        const timespec& t) const
+{
+    uint32_t es = ElapsedTime(gRealBase, mRealStart);
+    uint32_t er = ElapsedTime(mRealStart, r);
+    uint32_t ep = ElapsedTime(mPStart, p);
+    uint32_t et = ElapsedTime(mTStart, t);
+    if (mIndent > 0) {
+        Bucket& bucket = gBuckets.editItemAt(mBucket);
+        if (bucket.mStart == 0)
+            bucket.mStart = es;
+        bucket.mReal += er;
+        bucket.mProcess += ep;
+        bucket.mThread += et;
+        bucket.mCount++;
+        return;
+    }
+    int index = 0;
+    int buckets = gBuckets.size();
+    int count = 1;
+    const char* tag = mTag;
+    int indent = mIndent;
+    do {
+        LOGD("%-30.30s: (%3d) %-5.*s time=%-10.3f real=%7dus process=%7dus (%3d%%) thread=%7dus (%3d%%)\n", 
+            tag, count, indent > 5 ? 5 : indent, "+++++", es / 1000000.0,
+            er, ep, ep * 100 / er, et, et * 100 / er);
+        if (index >= buckets)
+            break;
+        Bucket& bucket = gBuckets.editItemAt(index);
+        count = bucket.mCount;
+        es = bucket.mStart;
+        er = bucket.mReal;
+        ep = bucket.mProcess;
+        et = bucket.mThread;
+        tag = bucket.mTag;
+        indent = bucket.mIndent;
+        *bucket.mSlotPtr = 0;
+    } while (++index); // always true
+    gBuckets.clear();
+}
+
+}; // namespace android
+
+#endif
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
new file mode 100644
index 0000000..2abc811
--- /dev/null
+++ b/libs/utils/Timers.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Timer functions.
+//
+#include <utils/Timers.h>
+#include <utils/ported.h>     // may need usleep
+#include <utils/Log.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+#ifdef HAVE_WIN32_THREADS
+#include <windows.h>
+#endif
+
+nsecs_t systemTime(int clock)
+{
+#if defined(HAVE_POSIX_CLOCKS)
+    static const clockid_t clocks[] = {
+            CLOCK_REALTIME,
+            CLOCK_MONOTONIC,
+            CLOCK_PROCESS_CPUTIME_ID,
+            CLOCK_THREAD_CPUTIME_ID
+    };
+    struct timespec t;
+    t.tv_sec = t.tv_nsec = 0;
+    clock_gettime(clocks[clock], &t);
+    return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
+#else
+    // we don't support the clocks here.
+    struct timeval t;
+    t.tv_sec = t.tv_usec = 0;
+    gettimeofday(&t, NULL);
+    return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
+#endif
+}
+
+//#define MONITOR_USLEEP
+
+/*
+ * Sleep long enough that we'll wake up "interval" milliseconds after
+ * the previous snooze.
+ *
+ * The "nextTick" argument is updated on each call, and should be passed
+ * in every time.  Set its fields to zero on the first call.
+ *
+ * Returns the #of intervals we have overslept, which will be zero if we're
+ * on time.  [Currently just returns 0 or 1.]
+ */
+int sleepForInterval(long interval, struct timeval* pNextTick)
+{
+    struct timeval now;
+    long long timeBeforeNext;
+    long sleepTime = 0;
+    bool overSlept = false;
+    //int usleepBias = 0;
+
+#ifdef USLEEP_BIAS
+    /*
+     * Linux likes to add 9000ms or so.
+     * [not using this for now]
+     */
+    //usleepBias = USLEEP_BIAS;
+#endif
+
+    gettimeofday(&now, NULL);
+
+    if (pNextTick->tv_sec == 0) {
+        /* special-case for first time through */
+        *pNextTick = now;
+        sleepTime = interval;
+        android::DurationTimer::addToTimeval(pNextTick, interval);
+    } else {
+        /*
+         * Compute how much time there is before the next tick.  If this
+         * value is negative, we've run over.  If we've run over a little
+         * bit we can shorten the next frame to keep the pace steady, but
+         * if we've dramatically overshot we need to re-sync.
+         */
+        timeBeforeNext = android::DurationTimer::subtractTimevals(pNextTick, &now);
+        //printf("TOP: now=%ld.%ld next=%ld.%ld diff=%ld\n",
+        //    now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
+        //    (long) timeBeforeNext);
+        if (timeBeforeNext < -interval) {
+            /* way over */
+            overSlept = true;
+            sleepTime = 0;
+            *pNextTick = now;
+        } else if (timeBeforeNext <= 0) {
+            /* slightly over, keep the pace steady */
+            overSlept = true;
+            sleepTime = 0;
+        } else if (timeBeforeNext <= interval) {
+            /* right on schedule */
+            sleepTime = timeBeforeNext;
+        } else if (timeBeforeNext > interval && timeBeforeNext <= 2*interval) {
+            /* sleep call returned early; do a longer sleep this time */
+            sleepTime = timeBeforeNext;
+        } else if (timeBeforeNext > interval) {
+            /* we went back in time -- somebody updated system clock? */
+            /* (could also be a *seriously* broken usleep()) */
+            LOG(LOG_DEBUG, "",
+                " Impossible: timeBeforeNext = %ld\n", (long)timeBeforeNext);
+            sleepTime = 0;
+            *pNextTick = now;
+        }
+        android::DurationTimer::addToTimeval(pNextTick, interval);
+    }
+    //printf(" Before sleep: now=%ld.%ld next=%ld.%ld sleepTime=%ld\n",
+    //    now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
+    //    sleepTime);
+
+    /*
+     * Sleep for the designated period of time.
+     *
+     * Linux tends to sleep for longer than requested, often by 17-18ms.
+     * MinGW tends to sleep for less than requested, by as much as 14ms,
+     * but occasionally oversleeps for 40+ms (looks like some external
+     * factors plus round-off on a 64Hz clock).  Cygwin is pretty steady.
+     *
+     * If you start the MinGW version, and then launch the Cygwin version,
+     * the MinGW clock becomes more erratic.  Not entirely sure why.
+     *
+     * (There's a lot of stuff here; it's really just a usleep() call with
+     * a bunch of instrumentation.)
+     */
+    if (sleepTime > 0) {
+#if defined(MONITOR_USLEEP)
+        struct timeval before, after;
+        long long actual;
+
+        gettimeofday(&before, NULL);
+        usleep((long) sleepTime);
+        gettimeofday(&after, NULL);
+
+        /* check usleep() accuracy; default Linux threads are pretty sloppy */
+        actual = android::DurationTimer::subtractTimevals(&after, &before);
+        if ((long) actual < sleepTime - 14000 /*(sleepTime/10)*/ ||
+            (long) actual > sleepTime + 20000 /*(sleepTime/10)*/)
+        {
+            LOG(LOG_DEBUG, "", " Odd usleep: req=%ld, actual=%ld\n", sleepTime,
+                (long) actual);
+        }
+#else
+#ifdef HAVE_WIN32_THREADS
+        Sleep( sleepTime/1000 );
+#else        
+        usleep((long) sleepTime);
+#endif        
+#endif
+    }
+
+    //printf("slept %d\n", sleepTime);
+
+    if (overSlept)
+        return 1;       // close enough
+    else
+        return 0;
+}
+
+
+/*
+ * ===========================================================================
+ *      DurationTimer
+ * ===========================================================================
+ */
+
+using namespace android;
+
+// Start the timer.
+void DurationTimer::start(void)
+{
+    gettimeofday(&mStartWhen, NULL);
+}
+
+// Stop the timer.
+void DurationTimer::stop(void)
+{
+    gettimeofday(&mStopWhen, NULL);
+}
+
+// Get the duration in microseconds.
+long long DurationTimer::durationUsecs(void) const
+{
+    return (long) subtractTimevals(&mStopWhen, &mStartWhen);
+}
+
+// Subtract two timevals.  Returns the difference (ptv1-ptv2) in
+// microseconds.
+/*static*/ long long DurationTimer::subtractTimevals(const struct timeval* ptv1,
+    const struct timeval* ptv2)
+{
+    long long stop  = ((long long) ptv1->tv_sec) * 1000000LL +
+                      ((long long) ptv1->tv_usec);
+    long long start = ((long long) ptv2->tv_sec) * 1000000LL +
+                      ((long long) ptv2->tv_usec);
+    return stop - start;
+}
+
+// Add the specified amount of time to the timeval.
+/*static*/ void DurationTimer::addToTimeval(struct timeval* ptv, long usec)
+{
+    if (usec < 0) {
+        LOG(LOG_WARN, "", "Negative values not supported in addToTimeval\n");
+        return;
+    }
+
+    // normalize tv_usec if necessary
+    if (ptv->tv_usec >= 1000000) {
+        ptv->tv_sec += ptv->tv_usec / 1000000;
+        ptv->tv_usec %= 1000000;
+    }
+
+    ptv->tv_usec += usec % 1000000;
+    if (ptv->tv_usec >= 1000000) {
+        ptv->tv_usec -= 1000000;
+        ptv->tv_sec++;
+    }
+    ptv->tv_sec += usec / 1000000;
+}
+
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
new file mode 100644
index 0000000..33f535f
--- /dev/null
+++ b/libs/utils/Unicode.cpp
@@ -0,0 +1,193 @@
+/*
+ * 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 "utils/AndroidUnicode.h"
+#include "characterData.h"
+
+#define LOG_TAG "Unicode"
+#include "utils/Log.h"
+
+// ICU headers for using macros
+#include <unicode/utf16.h>
+
+#define MIN_RADIX 2
+#define MAX_RADIX 36
+
+#define TYPE_SHIFT 0
+#define TYPE_MASK ((1<<5)-1)
+
+#define DIRECTION_SHIFT (TYPE_SHIFT+5)
+#define DIRECTION_MASK ((1<<5)-1)
+
+#define MIRRORED_SHIFT (DIRECTION_SHIFT+5)
+#define MIRRORED_MASK ((1<<1)-1)
+
+#define TOUPPER_SHIFT (MIRRORED_SHIFT+1)
+#define TOUPPER_MASK ((1<<6)-1)
+
+#define TOLOWER_SHIFT (TOUPPER_SHIFT+6)
+#define TOLOWER_MASK ((1<<6)-1)
+
+#define TOTITLE_SHIFT (TOLOWER_SHIFT+6)
+#define TOTITLE_MASK ((1<<2)-1)
+
+#define MIRROR_SHIFT (TOTITLE_SHIFT+2)
+#define MIRROR_MASK ((1<<5)-1)
+
+#define NUMERIC_SHIFT (TOTITLE_SHIFT+2)
+#define NUMERIC_MASK ((1<<7)-1)
+
+#define DECOMPOSITION_SHIFT (11)
+#define DECOMPOSITION_MASK ((1<<5)-1)
+
+/*
+ * Returns the value stored in the CharacterData tables that contains
+ * an index into the packed data table and the decomposition type.
+ */
+static uint16_t findCharacterValue(UChar32 c)
+{
+    LOG_ASSERT(c >= 0 && c <= 0x10FFFF, "findCharacterValue received an invalid codepoint");
+    if (c < 256)
+        return CharacterData::LATIN1_DATA[c];
+
+    // Rotate the bits because the tables are separated into even and odd codepoints
+    c = (c >> 1) | ((c & 1) << 20);
+
+    CharacterData::Range search = CharacterData::FULL_DATA[c >> 16];
+    const uint32_t* array = search.array;
+ 
+    // This trick is so that that compare in the while loop does not
+    // need to shift the array entry down by 16
+    c <<= 16;
+    c |= 0xFFFF;
+
+    int high = (int)search.length - 1;
+    int low = 0;
+
+    if (high < 0)
+        return 0;
+    
+    while (low < high - 1)
+    {
+        int probe = (high + low) >> 1;
+
+        // The entries contain the codepoint in the high 16 bits and the index
+        // into PACKED_DATA in the low 16.
+        if (array[probe] > (unsigned)c)
+            high = probe;
+        else
+            low = probe;
+    }
+
+    LOG_ASSERT((array[low] <= (unsigned)c), "A suitable range was not found");
+    return array[low] & 0xFFFF;
+}
+
+uint32_t android::Unicode::getPackedData(UChar32 c)
+{
+    // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
+    // and the remaining bits containing an index.
+    return CharacterData::PACKED_DATA[findCharacterValue(c) & 0x7FF];
+}
+
+android::Unicode::CharType android::Unicode::getType(UChar32 c)
+{
+    if (c < 0 || c >= 0x10FFFF)
+        return CHARTYPE_UNASSIGNED;
+    return (CharType)((getPackedData(c) >> TYPE_SHIFT) & TYPE_MASK);
+}
+
+android::Unicode::DecompositionType android::Unicode::getDecompositionType(UChar32 c)
+{
+    // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
+    // and the remaining bits containing an index.
+    return (DecompositionType)((findCharacterValue(c) >> DECOMPOSITION_SHIFT) & DECOMPOSITION_MASK);
+}
+
+int android::Unicode::getDigitValue(UChar32 c, int radix)
+{
+    if (radix < MIN_RADIX || radix > MAX_RADIX)
+        return -1;
+
+    int tempValue = radix;
+    
+    if (c >= '0' && c <= '9')
+        tempValue = c - '0';
+    else if (c >= 'a' && c <= 'z')
+        tempValue = c - 'a' + 10;
+    else if (c >= 'A' && c <= 'Z')
+        tempValue = c - 'A' + 10;
+    
+    return tempValue < radix ? tempValue : -1;
+}
+
+int android::Unicode::getNumericValue(UChar32 c)
+{
+    if (isMirrored(c))
+        return -1;
+    
+    return (int) CharacterData::NUMERICS[((getPackedData(c) >> NUMERIC_SHIFT) & NUMERIC_MASK)];
+}
+
+UChar32 android::Unicode::toLower(UChar32 c)
+{
+    return c + CharacterData::LCDIFF[(getPackedData(c) >> TOLOWER_SHIFT) & TOLOWER_MASK];
+}
+
+UChar32 android::Unicode::toUpper(UChar32 c)
+{
+    return c + CharacterData::UCDIFF[(getPackedData(c) >> TOUPPER_SHIFT) & TOUPPER_MASK];
+}
+
+android::Unicode::Direction android::Unicode::getDirectionality(UChar32 c)
+{
+    uint32_t data = getPackedData(c);
+
+    if (0 == data)
+        return DIRECTIONALITY_UNDEFINED;
+
+    Direction d = (Direction) ((data >> DIRECTION_SHIFT) & DIRECTION_MASK);
+
+    if (DIRECTION_MASK == d)
+        return DIRECTIONALITY_UNDEFINED;
+    
+    return d;
+}
+
+bool android::Unicode::isMirrored(UChar32 c)
+{
+    return ((getPackedData(c) >> MIRRORED_SHIFT) & MIRRORED_MASK) != 0;
+}
+
+UChar32 android::Unicode::toMirror(UChar32 c)
+{
+    if (!isMirrored(c))
+        return c;
+
+    return c + CharacterData::MIRROR_DIFF[(getPackedData(c) >> MIRROR_SHIFT) & MIRROR_MASK];
+}
+
+UChar32 android::Unicode::toTitle(UChar32 c)
+{
+    int32_t diff = CharacterData::TCDIFF[(getPackedData(c) >> TOTITLE_SHIFT) & TOTITLE_MASK];
+
+    if (TOTITLE_MASK == diff)
+        return toUpper(c);
+    
+    return c + diff;
+}
+
+
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
new file mode 100644
index 0000000..2c2d667
--- /dev/null
+++ b/libs/utils/VectorImpl.cpp
@@ -0,0 +1,611 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "Vector"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/SharedBuffer.h>
+#include <utils/VectorImpl.h>
+
+/*****************************************************************************/
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+const size_t kMinVectorCapacity = 4;
+
+static inline size_t max(size_t a, size_t b) {
+    return a>b ? a : b;
+}
+
+// ----------------------------------------------------------------------------
+
+VectorImpl::VectorImpl(size_t itemSize, uint32_t flags)
+    : mStorage(0), mCount(0), mFlags(flags), mItemSize(itemSize)
+{
+}
+
+VectorImpl::VectorImpl(const VectorImpl& rhs)
+    :   mStorage(rhs.mStorage), mCount(rhs.mCount),
+        mFlags(rhs.mFlags), mItemSize(rhs.mItemSize)
+{
+    if (mStorage) {
+        SharedBuffer::sharedBuffer(mStorage)->acquire();
+    }
+}
+
+VectorImpl::~VectorImpl()
+{
+    LOG_ASSERT(!mCount,
+        "[%p] "
+        "subclasses of VectorImpl must call finish_vector()"
+        " in their destructor. Leaking %d bytes.",
+        this, (int)(mCount*mItemSize));
+    // We can't call _do_destroy() here because the vtable is already gone. 
+}
+
+VectorImpl& VectorImpl::operator = (const VectorImpl& rhs)
+{
+    LOG_ASSERT(mItemSize == rhs.mItemSize,
+        "Vector<> have different types (this=%p, rhs=%p)", this, &rhs);
+    if (this != &rhs) {
+        release_storage();
+        if (rhs.mCount) {
+            mStorage = rhs.mStorage;
+            mCount = rhs.mCount;
+            SharedBuffer::sharedBuffer(mStorage)->acquire();
+        } else {
+            mStorage = 0;
+            mCount = 0;
+        }
+    }
+    return *this;
+}
+
+void* VectorImpl::editArrayImpl()
+{
+    if (mStorage) {
+        SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage)->attemptEdit();
+        if (sb == 0) {
+            sb = SharedBuffer::alloc(capacity() * mItemSize);
+            if (sb) {
+                _do_copy(sb->data(), mStorage, mCount);
+                release_storage();
+                mStorage = sb->data();
+            }
+        }
+    }
+    return mStorage;
+}
+
+size_t VectorImpl::capacity() const
+{
+    if (mStorage) {
+        return SharedBuffer::sharedBuffer(mStorage)->size() / mItemSize;
+    }
+    return 0;
+}
+
+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;
+}
+
+ssize_t VectorImpl::appendVector(const VectorImpl& vector)
+{
+    return insertVectorAt(vector, size());
+}
+
+ssize_t VectorImpl::insertAt(size_t index, size_t numItems)
+{
+    return insertAt(0, index, numItems);
+}
+
+ssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems)
+{
+    if (index > size())
+        return BAD_INDEX;
+    void* where = _grow(index, numItems);
+    if (where) {
+        if (item) {
+            _do_splat(where, item, numItems);
+        } else {
+            _do_construct(where, numItems);
+        }
+    }
+    return where ? index : (ssize_t)NO_MEMORY;
+}
+
+static int sortProxy(const void* lhs, const void* rhs, void* func)
+{
+    return (*(VectorImpl::compar_t)func)(lhs, rhs);
+}
+
+status_t VectorImpl::sort(VectorImpl::compar_t cmp)
+{
+    return sort(sortProxy, (void*)cmp);
+}
+
+status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state)
+{
+    // the sort must be stable. we're using insertion sort which
+    // is well suited for small and already sorted arrays
+    // for big arrays, it could be better to use mergesort
+    const ssize_t count = size();
+    if (count > 1) {
+        void* array = const_cast<void*>(arrayImpl());
+        void* temp = 0;
+        ssize_t i = 1;
+        while (i < count) {
+            void* item = reinterpret_cast<char*>(array) + mItemSize*(i);
+            void* curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
+            if (cmp(curr, item, state) > 0) {
+
+                if (!temp) {
+                    // we're going to have to modify the array...
+                    array = editArrayImpl();
+                    if (!array) return NO_MEMORY;
+                    temp = malloc(mItemSize);
+                    if (!temp) return NO_MEMORY;
+                    _do_construct(temp, 1);
+                    item = reinterpret_cast<char*>(array) + mItemSize*(i);
+                    curr = reinterpret_cast<char*>(array) + mItemSize*(i-1);
+                }
+
+                _do_copy(temp, item, 1);
+
+                ssize_t j = i-1;
+                void* next = reinterpret_cast<char*>(array) + mItemSize*(i);                    
+                do {
+                    _do_copy(next, curr, 1);
+                    next = curr;
+                    --j;
+                    curr = reinterpret_cast<char*>(array) + mItemSize*(j);                    
+                } while (j>=0 && (cmp(curr, temp, state) > 0));
+
+                _do_copy(next, temp, 1);
+            }
+            i++;
+        }
+        
+        if (temp) {
+            _do_destroy(temp, 1);
+            free(temp);
+        }
+    }
+    return NO_ERROR;
+}
+
+void VectorImpl::pop()
+{
+    if (size())
+        removeItemsAt(size()-1, 1);
+}
+
+void VectorImpl::push()
+{
+    push(0);
+}
+
+void VectorImpl::push(const void* item)
+{
+    insertAt(item, size());
+}
+
+ssize_t VectorImpl::add()
+{
+    return add(0);
+}
+
+ssize_t VectorImpl::add(const void* item)
+{
+    return insertAt(item, size());
+}
+
+ssize_t VectorImpl::replaceAt(size_t index)
+{
+    return replaceAt(0, index);
+}
+
+ssize_t VectorImpl::replaceAt(const void* prototype, size_t index)
+{
+    LOG_ASSERT(index<size(),
+        "[%p] replace: index=%d, size=%d", this, (int)index, (int)size());
+
+    void* item = editItemLocation(index);
+    if (item == 0)
+        return NO_MEMORY;
+    _do_destroy(item, 1);
+    if (prototype == 0) {
+        _do_construct(item, 1);
+    } else {
+        _do_copy(item, prototype, 1);
+    }
+    return ssize_t(index);
+}
+
+ssize_t VectorImpl::removeItemsAt(size_t index, size_t count)
+{
+    LOG_ASSERT((index+count)<=size(),
+        "[%p] remove: index=%d, count=%d, size=%d",
+               this, (int)index, (int)count, (int)size());
+
+    if ((index+count) > size())
+        return BAD_VALUE;
+   _shrink(index, count);
+   return index;
+}
+
+void VectorImpl::finish_vector()
+{
+    release_storage();
+    mStorage = 0;
+    mCount = 0;
+}
+
+void VectorImpl::clear()
+{
+    _shrink(0, mCount);
+}
+
+void* VectorImpl::editItemLocation(size_t index)
+{
+    LOG_ASSERT(index<capacity(),
+        "[%p] itemLocation: index=%d, capacity=%d, count=%d",
+        this, (int)index, (int)capacity(), (int)mCount);
+            
+    void* buffer = editArrayImpl();
+    if (buffer)
+        return reinterpret_cast<char*>(buffer) + index*mItemSize;
+    return 0;
+}
+
+const void* VectorImpl::itemLocation(size_t index) const
+{
+    LOG_ASSERT(index<capacity(),
+        "[%p] editItemLocation: index=%d, capacity=%d, count=%d",
+        this, (int)index, (int)capacity(), (int)mCount);
+
+    const  void* buffer = arrayImpl();
+    if (buffer)
+        return reinterpret_cast<const char*>(buffer) + index*mItemSize;
+    return 0;
+}
+
+ssize_t VectorImpl::setCapacity(size_t new_capacity)
+{
+    size_t current_capacity = capacity();
+    ssize_t amount = new_capacity - size();
+    if (amount <= 0) {
+        // we can't reduce the capacity
+        return current_capacity;
+    } 
+    SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
+    if (sb) {
+        void* array = sb->data();
+        _do_copy(array, mStorage, size());
+        release_storage();
+        mStorage = const_cast<void*>(array);
+    } else {
+        return NO_MEMORY;
+    }
+    return new_capacity;
+}
+
+void VectorImpl::release_storage()
+{
+    if (mStorage) {
+        const SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage);
+        if (sb->release(SharedBuffer::eKeepStorage) == 1) {
+            _do_destroy(mStorage, mCount);
+            SharedBuffer::dealloc(sb);
+        } 
+    }
+}
+
+void* VectorImpl::_grow(size_t where, size_t amount)
+{
+//    LOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
+//        this, (int)where, (int)amount, (int)mCount, (int)capacity());
+
+    if (where > mCount)
+        where = mCount;
+      
+    const size_t new_size = mCount + amount;
+    if (capacity() < new_size) {
+        const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2);
+//        LOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
+        if ((mStorage) &&
+            (mCount==where) &&
+            (mFlags & HAS_TRIVIAL_COPY) &&
+            (mFlags & HAS_TRIVIAL_DTOR))
+        {
+            const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
+            SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
+            mStorage = sb->data();
+        } else {
+            SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
+            if (sb) {
+                void* array = sb->data();
+                if (where>0) {
+                    _do_copy(array, mStorage, where);
+                }
+                if (mCount>where) {
+                    const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize;
+                    void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+                    _do_copy(dest, from, mCount-where);
+                }
+                release_storage();
+                mStorage = const_cast<void*>(array);
+            }
+        }
+    } else {
+        ssize_t s = mCount-where;
+        if (s>0) {
+            void* array = editArrayImpl();    
+            void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+            const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize;
+            _do_move_forward(to, from, s);
+        }
+    }
+    mCount += amount;
+    void* free_space = const_cast<void*>(itemLocation(where));
+    return free_space;
+}
+
+void VectorImpl::_shrink(size_t where, size_t amount)
+{
+    if (!mStorage)
+        return;
+
+//    LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
+//        this, (int)where, (int)amount, (int)mCount, (int)capacity());
+
+    if (where >= mCount)
+        where = mCount - amount;
+
+    const size_t new_size = mCount - amount;
+    if (new_size*3 < capacity()) {
+        const size_t new_capacity = max(kMinVectorCapacity, new_size*2);
+//        LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
+        if ((where == mCount-amount) &&
+            (mFlags & HAS_TRIVIAL_COPY) &&
+            (mFlags & HAS_TRIVIAL_DTOR))
+        {
+            const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage);
+            SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize);
+            mStorage = sb->data();
+        } else {
+            SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
+            if (sb) {
+                void* array = sb->data();
+                if (where>0) {
+                    _do_copy(array, mStorage, where);
+                }
+                if (mCount > where+amount) {
+                    const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize;
+                    void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
+                    _do_copy(dest, from, mCount-(where+amount));
+                }
+                release_storage();
+                mStorage = const_cast<void*>(array);
+            }
+        }
+    } else {
+        void* array = editArrayImpl();    
+        void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
+        _do_destroy(to, amount);
+        ssize_t s = mCount-(where+amount);
+        if (s>0) {
+            const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+            _do_move_backward(to, from, s);
+        }
+    }
+
+    // adjust the number of items...
+    mCount -= amount;
+}
+
+size_t VectorImpl::itemSize() const {
+    return mItemSize;
+}
+
+void VectorImpl::_do_construct(void* storage, size_t num) const
+{
+    if (!(mFlags & HAS_TRIVIAL_CTOR)) {
+        do_construct(storage, num);
+    }
+}
+
+void VectorImpl::_do_destroy(void* storage, size_t num) const
+{
+    if (!(mFlags & HAS_TRIVIAL_DTOR)) {
+        do_destroy(storage, num);
+    }
+}
+
+void VectorImpl::_do_copy(void* dest, const void* from, size_t num) const
+{
+    if (!(mFlags & HAS_TRIVIAL_COPY)) {
+        do_copy(dest, from, num);
+    } else {
+        memcpy(dest, from, num*itemSize());
+    }
+}
+
+void VectorImpl::_do_splat(void* dest, const void* item, size_t num) const {
+    do_splat(dest, item, num);
+}
+
+void VectorImpl::_do_move_forward(void* dest, const void* from, size_t num) const {
+    do_move_forward(dest, from, num);
+}
+
+void VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) const {
+    do_move_backward(dest, from, num);
+}
+
+void VectorImpl::reservedVectorImpl1() { }
+void VectorImpl::reservedVectorImpl2() { }
+void VectorImpl::reservedVectorImpl3() { }
+void VectorImpl::reservedVectorImpl4() { }
+void VectorImpl::reservedVectorImpl5() { }
+void VectorImpl::reservedVectorImpl6() { }
+void VectorImpl::reservedVectorImpl7() { }
+void VectorImpl::reservedVectorImpl8() { }
+
+/*****************************************************************************/
+
+SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags)
+    : VectorImpl(itemSize, flags)
+{
+}
+
+SortedVectorImpl::SortedVectorImpl(const VectorImpl& rhs)
+: VectorImpl(rhs)
+{
+}
+
+SortedVectorImpl::~SortedVectorImpl()
+{
+}
+
+SortedVectorImpl& SortedVectorImpl::operator = (const SortedVectorImpl& rhs)
+{
+    return static_cast<SortedVectorImpl&>( VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)) );
+}
+
+ssize_t SortedVectorImpl::indexOf(const void* item) const
+{
+    return _indexOrderOf(item);
+}
+
+size_t SortedVectorImpl::orderOf(const void* item) const
+{
+    size_t o;
+    _indexOrderOf(item, &o);
+    return o;
+}
+
+ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const
+{
+    // binary search
+    ssize_t err = NAME_NOT_FOUND;
+    ssize_t l = 0;
+    ssize_t h = size()-1;
+    ssize_t mid;
+    const void* a = arrayImpl();
+    const size_t s = itemSize();
+    while (l <= h) {
+        mid = l + (h - l)/2;
+        const void* const curr = reinterpret_cast<const char *>(a) + (mid*s);
+        const int c = do_compare(curr, item);
+        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 SortedVectorImpl::add(const void* item)
+{
+    size_t order;
+    ssize_t index = _indexOrderOf(item, &order);
+    if (index < 0) {
+        index = VectorImpl::insertAt(item, order, 1);
+    } else {
+        index = VectorImpl::replaceAt(item, index);
+    }
+    return index;
+}
+
+ssize_t SortedVectorImpl::merge(const VectorImpl& vector)
+{
+    // naive merge...
+    if (!vector.isEmpty()) {
+        const void* buffer = vector.arrayImpl();
+        const size_t is = itemSize();
+        size_t s = vector.size();
+        for (size_t i=0 ; i<s ; i++) {
+            ssize_t err = add( reinterpret_cast<const char*>(buffer) + i*is );
+            if (err<0) {
+                return err;
+            }
+        }
+    }
+    return NO_ERROR;
+}
+
+ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector)
+{
+    // we've merging a sorted vector... nice!
+    ssize_t err = NO_ERROR;
+    if (!vector.isEmpty()) {
+        // first take care of the case where the vectors are sorted together
+        if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) {
+            err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&>(vector), 0);
+        } else if (do_compare(vector.arrayImpl(), itemLocation(size()-1)) >= 0) {
+            err = VectorImpl::appendVector(static_cast<const VectorImpl&>(vector));
+        } else {
+            // this could be made a little better
+            err = merge(static_cast<const VectorImpl&>(vector));
+        }
+    }
+    return err;
+}
+
+ssize_t SortedVectorImpl::remove(const void* item)
+{
+    ssize_t i = indexOf(item);
+    if (i>=0) {
+        VectorImpl::removeItemsAt(i, 1);
+    }
+    return i;
+}
+
+void SortedVectorImpl::reservedSortedVectorImpl1() { };
+void SortedVectorImpl::reservedSortedVectorImpl2() { };
+void SortedVectorImpl::reservedSortedVectorImpl3() { };
+void SortedVectorImpl::reservedSortedVectorImpl4() { };
+void SortedVectorImpl::reservedSortedVectorImpl5() { };
+void SortedVectorImpl::reservedSortedVectorImpl6() { };
+void SortedVectorImpl::reservedSortedVectorImpl7() { };
+void SortedVectorImpl::reservedSortedVectorImpl8() { };
+
+
+/*****************************************************************************/
+
+}; // namespace android
+
diff --git a/libs/utils/ZipEntry.cpp b/libs/utils/ZipEntry.cpp
new file mode 100644
index 0000000..fbc9e67
--- /dev/null
+++ b/libs/utils/ZipEntry.cpp
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Access to entries in a Zip archive.
+//
+
+#define LOG_TAG "zip"
+
+#include "utils/ZipEntry.h"
+#include "utils/Log.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Initialize a new ZipEntry structure from a FILE* positioned at a
+ * CentralDirectoryEntry.
+ *
+ * On exit, the file pointer will be at the start of the next CDE or
+ * at the EOCD.
+ */
+status_t ZipEntry::initFromCDE(FILE* fp)
+{
+    status_t result;
+    long posn;
+    bool hasDD;
+
+    //LOGV("initFromCDE ---\n");
+
+    /* read the CDE */
+    result = mCDE.read(fp);
+    if (result != NO_ERROR) {
+        LOGD("mCDE.read failed\n");
+        return result;
+    }
+
+    //mCDE.dump();
+
+    /* using the info in the CDE, go load up the LFH */
+    posn = ftell(fp);
+    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
+        LOGD("local header seek failed (%ld)\n",
+            mCDE.mLocalHeaderRelOffset);
+        return UNKNOWN_ERROR;
+    }
+
+    result = mLFH.read(fp);
+    if (result != NO_ERROR) {
+        LOGD("mLFH.read failed\n");
+        return result;
+    }
+
+    if (fseek(fp, posn, SEEK_SET) != 0)
+        return UNKNOWN_ERROR;
+
+    //mLFH.dump();
+
+    /*
+     * We *might* need to read the Data Descriptor at this point and
+     * integrate it into the LFH.  If this bit is set, the CRC-32,
+     * compressed size, and uncompressed size will be zero.  In practice
+     * these seem to be rare.
+     */
+    hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
+    if (hasDD) {
+        // do something clever
+        //LOGD("+++ has data descriptor\n");
+    }
+
+    /*
+     * Sanity-check the LFH.  Note that this will fail if the "kUsesDataDescr"
+     * flag is set, because the LFH is incomplete.  (Not a problem, since we
+     * prefer the CDE values.)
+     */
+    if (!hasDD && !compareHeaders()) {
+        LOGW("WARNING: header mismatch\n");
+        // keep going?
+    }
+
+    /*
+     * If the mVersionToExtract is greater than 20, we may have an
+     * issue unpacking the record -- could be encrypted, compressed
+     * with something we don't support, or use Zip64 extensions.  We
+     * can defer worrying about that to when we're extracting data.
+     */
+
+    return NO_ERROR;
+}
+
+/*
+ * Initialize a new entry.  Pass in the file name and an optional comment.
+ *
+ * Initializes the CDE and the LFH.
+ */
+void ZipEntry::initNew(const char* fileName, const char* comment)
+{
+    assert(fileName != NULL && *fileName != '\0');  // name required
+
+    /* most fields are properly initialized by constructor */
+    mCDE.mVersionMadeBy = kDefaultMadeBy;
+    mCDE.mVersionToExtract = kDefaultVersion;
+    mCDE.mCompressionMethod = kCompressStored;
+    mCDE.mFileNameLength = strlen(fileName);
+    if (comment != NULL)
+        mCDE.mFileCommentLength = strlen(comment);
+    mCDE.mExternalAttrs = 0x81b60020;   // matches what WinZip does
+
+    if (mCDE.mFileNameLength > 0) {
+        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
+        strcpy((char*) mCDE.mFileName, fileName);
+    }
+    if (mCDE.mFileCommentLength > 0) {
+        /* TODO: stop assuming null-terminated ASCII here? */
+        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
+        strcpy((char*) mCDE.mFileComment, comment);
+    }
+
+    copyCDEtoLFH();
+}
+
+/*
+ * Initialize a new entry, starting with the ZipEntry from a different
+ * archive.
+ *
+ * Initializes the CDE and the LFH.
+ */
+status_t ZipEntry::initFromExternal(const ZipFile* pZipFile,
+    const ZipEntry* pEntry)
+{
+    /*
+     * Copy everything in the CDE over, then fix up the hairy bits.
+     */
+    memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));
+
+    if (mCDE.mFileNameLength > 0) {
+        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
+        if (mCDE.mFileName == NULL)
+            return NO_MEMORY;
+        strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);
+    }
+    if (mCDE.mFileCommentLength > 0) {
+        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
+        if (mCDE.mFileComment == NULL)
+            return NO_MEMORY;
+        strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);
+    }
+    if (mCDE.mExtraFieldLength > 0) {
+        /* we null-terminate this, though it may not be a string */
+        mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1];
+        if (mCDE.mExtraField == NULL)
+            return NO_MEMORY;
+        memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,
+            mCDE.mExtraFieldLength+1);
+    }
+
+    /* construct the LFH from the CDE */
+    copyCDEtoLFH();
+
+    /*
+     * The LFH "extra" field is independent of the CDE "extra", so we
+     * handle it here.
+     */
+    assert(mLFH.mExtraField == NULL);
+    mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;
+    if (mLFH.mExtraFieldLength > 0) {
+        mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1];
+        if (mLFH.mExtraField == NULL)
+            return NO_MEMORY;
+        memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,
+            mLFH.mExtraFieldLength+1);
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Insert pad bytes in the LFH by tweaking the "extra" field.  This will
+ * potentially confuse something that put "extra" data in here earlier,
+ * but I can't find an actual problem.
+ */
+status_t ZipEntry::addPadding(int padding)
+{
+    if (padding <= 0)
+        return INVALID_OPERATION;
+
+    //LOGI("HEY: adding %d pad bytes to existing %d in %s\n",
+    //    padding, mLFH.mExtraFieldLength, mCDE.mFileName);
+
+    if (mLFH.mExtraFieldLength > 0) {
+        /* extend existing field */
+        unsigned char* newExtra;
+
+        newExtra = new unsigned char[mLFH.mExtraFieldLength + padding];
+        if (newExtra == NULL)
+            return NO_MEMORY;
+        memset(newExtra + mLFH.mExtraFieldLength, 0, padding);
+        memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);
+
+        delete[] mLFH.mExtraField;
+        mLFH.mExtraField = newExtra;
+        mLFH.mExtraFieldLength += padding;
+    } else {
+        /* create new field */
+        mLFH.mExtraField = new unsigned char[padding];
+        memset(mLFH.mExtraField, 0, padding);
+        mLFH.mExtraFieldLength = padding;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Set the fields in the LFH equal to the corresponding fields in the CDE.
+ *
+ * This does not touch the LFH "extra" field.
+ */
+void ZipEntry::copyCDEtoLFH(void)
+{
+    mLFH.mVersionToExtract  = mCDE.mVersionToExtract;
+    mLFH.mGPBitFlag         = mCDE.mGPBitFlag;
+    mLFH.mCompressionMethod = mCDE.mCompressionMethod;
+    mLFH.mLastModFileTime   = mCDE.mLastModFileTime;
+    mLFH.mLastModFileDate   = mCDE.mLastModFileDate;
+    mLFH.mCRC32             = mCDE.mCRC32;
+    mLFH.mCompressedSize    = mCDE.mCompressedSize;
+    mLFH.mUncompressedSize  = mCDE.mUncompressedSize;
+    mLFH.mFileNameLength    = mCDE.mFileNameLength;
+    // the "extra field" is independent
+
+    delete[] mLFH.mFileName;
+    if (mLFH.mFileNameLength > 0) {
+        mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1];
+        strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);
+    } else {
+        mLFH.mFileName = NULL;
+    }
+}
+
+/*
+ * Set some information about a file after we add it.
+ */
+void ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32,
+    int compressionMethod)
+{
+    mCDE.mCompressionMethod = compressionMethod;
+    mCDE.mCRC32 = crc32;
+    mCDE.mCompressedSize = compLen;
+    mCDE.mUncompressedSize = uncompLen;
+    mCDE.mCompressionMethod = compressionMethod;
+    if (compressionMethod == kCompressDeflated) {
+        mCDE.mGPBitFlag |= 0x0002;      // indicates maximum compression used
+    }
+    copyCDEtoLFH();
+}
+
+/*
+ * See if the data in mCDE and mLFH match up.  This is mostly useful for
+ * debugging these classes, but it can be used to identify damaged
+ * archives.
+ *
+ * Returns "false" if they differ.
+ */
+bool ZipEntry::compareHeaders(void) const
+{
+    if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {
+        LOGV("cmp: VersionToExtract\n");
+        return false;
+    }
+    if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {
+        LOGV("cmp: GPBitFlag\n");
+        return false;
+    }
+    if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {
+        LOGV("cmp: CompressionMethod\n");
+        return false;
+    }
+    if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {
+        LOGV("cmp: LastModFileTime\n");
+        return false;
+    }
+    if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {
+        LOGV("cmp: LastModFileDate\n");
+        return false;
+    }
+    if (mCDE.mCRC32 != mLFH.mCRC32) {
+        LOGV("cmp: CRC32\n");
+        return false;
+    }
+    if (mCDE.mCompressedSize != mLFH.mCompressedSize) {
+        LOGV("cmp: CompressedSize\n");
+        return false;
+    }
+    if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {
+        LOGV("cmp: UncompressedSize\n");
+        return false;
+    }
+    if (mCDE.mFileNameLength != mLFH.mFileNameLength) {
+        LOGV("cmp: FileNameLength\n");
+        return false;
+    }
+#if 0       // this seems to be used for padding, not real data
+    if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {
+        LOGV("cmp: ExtraFieldLength\n");
+        return false;
+    }
+#endif
+    if (mCDE.mFileName != NULL) {
+        if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {
+            LOGV("cmp: FileName\n");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
+/*
+ * Convert the DOS date/time stamp into a UNIX time stamp.
+ */
+time_t ZipEntry::getModWhen(void) const
+{
+    struct tm parts;
+
+    parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;
+    parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;
+    parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;
+    parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);
+    parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;
+    parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;
+    parts.tm_wday = parts.tm_yday = 0;
+    parts.tm_isdst = -1;        // DST info "not available"
+
+    return mktime(&parts);
+}
+
+/*
+ * Set the CDE/LFH timestamp from UNIX time.
+ */
+void ZipEntry::setModWhen(time_t when)
+{
+#ifdef HAVE_LOCALTIME_R
+    struct tm tmResult;
+#endif
+    time_t even;
+    unsigned short zdate, ztime;
+
+    struct tm* ptm;
+
+    /* round up to an even number of seconds */
+    even = (time_t)(((unsigned long)(when) + 1) & (~1));
+
+    /* expand */
+#ifdef HAVE_LOCALTIME_R
+    ptm = localtime_r(&even, &tmResult);
+#else
+    ptm = localtime(&even);
+#endif
+
+    int year;
+    year = ptm->tm_year;
+    if (year < 80)
+        year = 80;
+
+    zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;
+    ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
+
+    mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;
+    mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;
+}
+
+
+/*
+ * ===========================================================================
+ *      ZipEntry::LocalFileHeader
+ * ===========================================================================
+ */
+
+/*
+ * Read a local file header.
+ *
+ * On entry, "fp" points to the signature at the start of the header.
+ * On exit, "fp" points to the start of data.
+ */
+status_t ZipEntry::LocalFileHeader::read(FILE* fp)
+{
+    status_t result = NO_ERROR;
+    unsigned char buf[kLFHLen];
+
+    assert(mFileName == NULL);
+    assert(mExtraField == NULL);
+
+    if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
+        LOGD("whoops: didn't find expected signature\n");
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);
+    mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);
+    mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);
+    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);
+    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);
+    mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);
+    mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);
+    mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);
+    mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);
+    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);
+
+    // TODO: validate sizes
+
+    /* grab filename */
+    if (mFileNameLength != 0) {
+        mFileName = new unsigned char[mFileNameLength+1];
+        if (mFileName == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mFileName[mFileNameLength] = '\0';
+    }
+
+    /* grab extra field */
+    if (mExtraFieldLength != 0) {
+        mExtraField = new unsigned char[mExtraFieldLength+1];
+        if (mExtraField == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mExtraField[mExtraFieldLength] = '\0';
+    }
+
+bail:
+    return result;
+}
+
+/*
+ * Write a local file header.
+ */
+status_t ZipEntry::LocalFileHeader::write(FILE* fp)
+{
+    unsigned char buf[kLFHLen];
+
+    ZipEntry::putLongLE(&buf[0x00], kSignature);
+    ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);
+    ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);
+    ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);
+    ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);
+    ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);
+    ZipEntry::putLongLE(&buf[0x0e], mCRC32);
+    ZipEntry::putLongLE(&buf[0x12], mCompressedSize);
+    ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);
+    ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);
+    ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);
+
+    if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)
+        return UNKNOWN_ERROR;
+
+    /* write filename */
+    if (mFileNameLength != 0) {
+        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
+            return UNKNOWN_ERROR;
+    }
+
+    /* write "extra field" */
+    if (mExtraFieldLength != 0) {
+        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
+            return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+
+/*
+ * Dump the contents of a LocalFileHeader object.
+ */
+void ZipEntry::LocalFileHeader::dump(void) const
+{
+    LOGD(" LocalFileHeader contents:\n");
+    LOGD("  versToExt=%u gpBits=0x%04x compression=%u\n",
+        mVersionToExtract, mGPBitFlag, mCompressionMethod);
+    LOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
+        mLastModFileTime, mLastModFileDate, mCRC32);
+    LOGD("  compressedSize=%lu uncompressedSize=%lu\n",
+        mCompressedSize, mUncompressedSize);
+    LOGD("  filenameLen=%u extraLen=%u\n",
+        mFileNameLength, mExtraFieldLength);
+    if (mFileName != NULL)
+        LOGD("  filename: '%s'\n", mFileName);
+}
+
+
+/*
+ * ===========================================================================
+ *      ZipEntry::CentralDirEntry
+ * ===========================================================================
+ */
+
+/*
+ * Read the central dir entry that appears next in the file.
+ *
+ * On entry, "fp" should be positioned on the signature bytes for the
+ * entry.  On exit, "fp" will point at the signature word for the next
+ * entry or for the EOCD.
+ */
+status_t ZipEntry::CentralDirEntry::read(FILE* fp)
+{
+    status_t result = NO_ERROR;
+    unsigned char buf[kCDELen];
+
+    /* no re-use */
+    assert(mFileName == NULL);
+    assert(mExtraField == NULL);
+    assert(mFileComment == NULL);
+
+    if (fread(buf, 1, kCDELen, fp) != kCDELen) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
+        LOGD("Whoops: didn't find expected signature\n");
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);
+    mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);
+    mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);
+    mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);
+    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);
+    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);
+    mCRC32 = ZipEntry::getLongLE(&buf[0x10]);
+    mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);
+    mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);
+    mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);
+    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);
+    mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);
+    mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);
+    mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);
+    mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);
+    mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);
+
+    // TODO: validate sizes and offsets
+
+    /* grab filename */
+    if (mFileNameLength != 0) {
+        mFileName = new unsigned char[mFileNameLength+1];
+        if (mFileName == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mFileName[mFileNameLength] = '\0';
+    }
+
+    /* read "extra field" */
+    if (mExtraFieldLength != 0) {
+        mExtraField = new unsigned char[mExtraFieldLength+1];
+        if (mExtraField == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mExtraField[mExtraFieldLength] = '\0';
+    }
+
+
+    /* grab comment, if any */
+    if (mFileCommentLength != 0) {
+        mFileComment = new unsigned char[mFileCommentLength+1];
+        if (mFileComment == NULL) {
+            result = NO_MEMORY;
+            goto bail;
+        }
+        if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
+        {
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        mFileComment[mFileCommentLength] = '\0';
+    }
+
+bail:
+    return result;
+}
+
+/*
+ * Write a central dir entry.
+ */
+status_t ZipEntry::CentralDirEntry::write(FILE* fp)
+{
+    unsigned char buf[kCDELen];
+
+    ZipEntry::putLongLE(&buf[0x00], kSignature);
+    ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);
+    ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);
+    ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);
+    ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);
+    ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);
+    ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);
+    ZipEntry::putLongLE(&buf[0x10], mCRC32);
+    ZipEntry::putLongLE(&buf[0x14], mCompressedSize);
+    ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);
+    ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);
+    ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);
+    ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);
+    ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);
+    ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);
+    ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);
+    ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);
+
+    if (fwrite(buf, 1, kCDELen, fp) != kCDELen)
+        return UNKNOWN_ERROR;
+
+    /* write filename */
+    if (mFileNameLength != 0) {
+        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
+            return UNKNOWN_ERROR;
+    }
+
+    /* write "extra field" */
+    if (mExtraFieldLength != 0) {
+        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
+            return UNKNOWN_ERROR;
+    }
+
+    /* write comment */
+    if (mFileCommentLength != 0) {
+        if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
+            return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Dump the contents of a CentralDirEntry object.
+ */
+void ZipEntry::CentralDirEntry::dump(void) const
+{
+    LOGD(" CentralDirEntry contents:\n");
+    LOGD("  versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n",
+        mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);
+    LOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
+        mLastModFileTime, mLastModFileDate, mCRC32);
+    LOGD("  compressedSize=%lu uncompressedSize=%lu\n",
+        mCompressedSize, mUncompressedSize);
+    LOGD("  filenameLen=%u extraLen=%u commentLen=%u\n",
+        mFileNameLength, mExtraFieldLength, mFileCommentLength);
+    LOGD("  diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n",
+        mDiskNumberStart, mInternalAttrs, mExternalAttrs,
+        mLocalHeaderRelOffset);
+
+    if (mFileName != NULL)
+        LOGD("  filename: '%s'\n", mFileName);
+    if (mFileComment != NULL)
+        LOGD("  comment: '%s'\n", mFileComment);
+}
+
diff --git a/libs/utils/ZipFile.cpp b/libs/utils/ZipFile.cpp
new file mode 100644
index 0000000..89aa874
--- /dev/null
+++ b/libs/utils/ZipFile.cpp
@@ -0,0 +1,1296 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Access to Zip archives.
+//
+
+#define LOG_TAG "zip"
+
+#include "utils/ZipFile.h"
+#include "utils/ZipUtils.h"
+#include "utils/Log.h"
+
+#include <zlib.h>
+#define DEF_MEM_LEVEL 8                // normally in zutil.h?
+
+#include <memory.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Some environments require the "b", some choke on it.
+ */
+#define FILE_OPEN_RO        "rb"
+#define FILE_OPEN_RW        "r+b"
+#define FILE_OPEN_RW_CREATE "w+b"
+
+/* should live somewhere else? */
+static status_t errnoToStatus(int err)
+{
+    if (err == ENOENT)
+        return NAME_NOT_FOUND;
+    else if (err == EACCES)
+        return PERMISSION_DENIED;
+    else
+        return UNKNOWN_ERROR;
+}
+
+/*
+ * Open a file and parse its guts.
+ */
+status_t ZipFile::open(const char* zipFileName, int flags)
+{
+    bool newArchive = false;
+
+    assert(mZipFp == NULL);     // no reopen
+
+    if ((flags & kOpenTruncate))
+        flags |= kOpenCreate;           // trunc implies create
+
+    if ((flags & kOpenReadOnly) && (flags & kOpenReadWrite))
+        return INVALID_OPERATION;       // not both
+    if (!((flags & kOpenReadOnly) || (flags & kOpenReadWrite)))
+        return INVALID_OPERATION;       // not neither
+    if ((flags & kOpenCreate) && !(flags & kOpenReadWrite))
+        return INVALID_OPERATION;       // create requires write
+
+    if (flags & kOpenTruncate) {
+        newArchive = true;
+    } else {
+        newArchive = (access(zipFileName, F_OK) != 0);
+        if (!(flags & kOpenCreate) && newArchive) {
+            /* not creating, must already exist */
+            LOGD("File %s does not exist", zipFileName);
+            return NAME_NOT_FOUND;
+        }
+    }
+
+    /* open the file */
+    const char* openflags;
+    if (flags & kOpenReadWrite) {
+        if (newArchive)
+            openflags = FILE_OPEN_RW_CREATE;
+        else
+            openflags = FILE_OPEN_RW;
+    } else {
+        openflags = FILE_OPEN_RO;
+    }
+    mZipFp = fopen(zipFileName, openflags);
+    if (mZipFp == NULL) {
+		int err = errno;
+		LOGD("fopen failed: %d\n", err);
+        return errnoToStatus(err);
+	}
+
+    status_t result;
+    if (!newArchive) {
+        /*
+         * Load the central directory.  If that fails, then this probably
+         * isn't a Zip archive.
+         */
+        result = readCentralDir();
+    } else {
+        /*
+         * Newly-created.  The EndOfCentralDir constructor actually
+         * sets everything to be the way we want it (all zeroes).  We
+         * set mNeedCDRewrite so that we create *something* if the
+         * caller doesn't add any files.  (We could also just unlink
+         * the file if it's brand new and nothing was added, but that's
+         * probably doing more than we really should -- the user might
+         * have a need for empty zip files.)
+         */
+        mNeedCDRewrite = true;
+        result = NO_ERROR;
+    }
+
+    if (flags & kOpenReadOnly)
+        mReadOnly = true;
+    else
+        assert(!mReadOnly);
+
+    return result;
+}
+
+/*
+ * Return the Nth entry in the archive.
+ */
+ZipEntry* ZipFile::getEntryByIndex(int idx) const
+{
+    if (idx < 0 || idx >= (int) mEntries.size())
+        return NULL;
+
+    return mEntries[idx];
+}
+
+/*
+ * Find an entry by name.
+ */
+ZipEntry* ZipFile::getEntryByName(const char* fileName) const
+{
+    /*
+     * Do a stupid linear string-compare search.
+     *
+     * There are various ways to speed this up, especially since it's rare
+     * to intermingle changes to the archive with "get by name" calls.  We
+     * don't want to sort the mEntries vector itself, however, because
+     * it's used to recreate the Central Directory.
+     *
+     * (Hash table works, parallel list of pointers in sorted order is good.)
+     */
+    int idx;
+
+    for (idx = mEntries.size()-1; idx >= 0; idx--) {
+        ZipEntry* pEntry = mEntries[idx];
+        if (!pEntry->getDeleted() &&
+            strcmp(fileName, pEntry->getFileName()) == 0)
+        {
+            return pEntry;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Empty the mEntries vector.
+ */
+void ZipFile::discardEntries(void)
+{
+    int count = mEntries.size();
+
+    while (--count >= 0)
+        delete mEntries[count];
+
+    mEntries.clear();
+}
+
+
+/*
+ * Find the central directory and read the contents.
+ *
+ * The fun thing about ZIP archives is that they may or may not be
+ * readable from start to end.  In some cases, notably for archives
+ * that were written to stdout, the only length information is in the
+ * central directory at the end of the file.
+ *
+ * Of course, the central directory can be followed by a variable-length
+ * comment field, so we have to scan through it backwards.  The comment
+ * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff
+ * itself, plus apparently sometimes people throw random junk on the end
+ * just for the fun of it.
+ *
+ * This is all a little wobbly.  If the wrong value ends up in the EOCD
+ * area, we're hosed.  This appears to be the way that everbody handles
+ * it though, so we're in pretty good company if this fails.
+ */
+status_t ZipFile::readCentralDir(void)
+{
+    status_t result = NO_ERROR;
+    unsigned char* buf = NULL;
+    off_t fileLength, seekStart;
+    long readAmount;
+    int i;
+
+    fseek(mZipFp, 0, SEEK_END);
+    fileLength = ftell(mZipFp);
+    rewind(mZipFp);
+
+    /* too small to be a ZIP archive? */
+    if (fileLength < EndOfCentralDir::kEOCDLen) {
+        LOGD("Length is %ld -- too small\n", (long)fileLength);
+        result = INVALID_OPERATION;
+        goto bail;
+    }
+
+    buf = new unsigned char[EndOfCentralDir::kMaxEOCDSearch];
+    if (buf == NULL) {
+		LOGD("Failure allocating %d bytes for EOCD search",
+			 EndOfCentralDir::kMaxEOCDSearch);
+        result = NO_MEMORY;
+        goto bail;
+    }
+
+    if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
+        seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
+        readAmount = EndOfCentralDir::kMaxEOCDSearch;
+    } else {
+        seekStart = 0;
+        readAmount = (long) fileLength;
+    }
+    if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
+		LOGD("Failure seeking to end of zip at %ld", (long) seekStart);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /* read the last part of the file into the buffer */
+    if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
+        LOGD("short file? wanted %ld\n", readAmount);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /* find the end-of-central-dir magic */
+    for (i = readAmount - 4; i >= 0; i--) {
+        if (buf[i] == 0x50 &&
+            ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
+        {
+            LOGV("+++ Found EOCD at buf+%d\n", i);
+            break;
+        }
+    }
+    if (i < 0) {
+        LOGD("EOCD not found, not Zip\n");
+        result = INVALID_OPERATION;
+        goto bail;
+    }
+
+    /* extract eocd values */
+    result = mEOCD.readBuf(buf + i, readAmount - i);
+    if (result != NO_ERROR) {
+		LOGD("Failure reading %ld bytes of EOCD values", readAmount - i);
+        goto bail;
+	}
+    //mEOCD.dump();
+
+    if (mEOCD.mDiskNumber != 0 || mEOCD.mDiskWithCentralDir != 0 ||
+        mEOCD.mNumEntries != mEOCD.mTotalNumEntries)
+    {
+        LOGD("Archive spanning not supported\n");
+        result = INVALID_OPERATION;
+        goto bail;
+    }
+
+    /*
+     * So far so good.  "mCentralDirSize" is the size in bytes of the
+     * central directory, so we can just seek back that far to find it.
+     * We can also seek forward mCentralDirOffset bytes from the
+     * start of the file.
+     *
+     * We're not guaranteed to have the rest of the central dir in the
+     * buffer, nor are we guaranteed that the central dir will have any
+     * sort of convenient size.  We need to skip to the start of it and
+     * read the header, then the other goodies.
+     *
+     * The only thing we really need right now is the file comment, which
+     * we're hoping to preserve.
+     */
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+		LOGD("Failure seeking to central dir offset %ld\n",
+			 mEOCD.mCentralDirOffset);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /*
+     * Loop through and read the central dir entries.
+     */
+    LOGV("Scanning %d entries...\n", mEOCD.mTotalNumEntries);
+    int entry;
+    for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
+        ZipEntry* pEntry = new ZipEntry;
+
+        result = pEntry->initFromCDE(mZipFp);
+        if (result != NO_ERROR) {
+            LOGD("initFromCDE failed\n");
+            delete pEntry;
+            goto bail;
+        }
+
+        mEntries.add(pEntry);
+    }
+
+
+    /*
+     * If all went well, we should now be back at the EOCD.
+     */
+    {
+        unsigned char checkBuf[4];
+        if (fread(checkBuf, 1, 4, mZipFp) != 4) {
+            LOGD("EOCD check read failed\n");
+            result = INVALID_OPERATION;
+            goto bail;
+        }
+        if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
+            LOGD("EOCD read check failed\n");
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+        LOGV("+++ EOCD read check passed\n");
+    }
+
+bail:
+    delete[] buf;
+    return result;
+}
+
+
+/*
+ * Add a new file to the archive.
+ *
+ * This requires creating and populating a ZipEntry structure, and copying
+ * the data into the file at the appropriate position.  The "appropriate
+ * position" is the current location of the central directory, which we
+ * casually overwrite (we can put it back later).
+ *
+ * If we were concerned about safety, we would want to make all changes
+ * in a temp file and then overwrite the original after everything was
+ * safely written.  Not really a concern for us.
+ */
+status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,
+    const char* storageName, int sourceType, int compressionMethod,
+    ZipEntry** ppEntry)
+{
+    ZipEntry* pEntry = NULL;
+    status_t result = NO_ERROR;
+    long lfhPosn, startPosn, endPosn, uncompressedLen;
+    FILE* inputFp = NULL;
+    unsigned long crc;
+    time_t modWhen;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+
+    assert(compressionMethod == ZipEntry::kCompressDeflated ||
+           compressionMethod == ZipEntry::kCompressStored);
+
+    /* make sure we're in a reasonable state */
+    assert(mZipFp != NULL);
+    assert(mEntries.size() == mEOCD.mTotalNumEntries);
+
+    /* make sure it doesn't already exist */
+    if (getEntryByName(storageName) != NULL)
+        return ALREADY_EXISTS;
+
+    if (!data) {
+        inputFp = fopen(fileName, FILE_OPEN_RO);
+        if (inputFp == NULL)
+            return errnoToStatus(errno);
+    }
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    pEntry = new ZipEntry;
+    pEntry->initNew(storageName, NULL);
+
+    /*
+     * From here on out, failures are more interesting.
+     */
+    mNeedCDRewrite = true;
+
+    /*
+     * Write the LFH, even though it's still mostly blank.  We need it
+     * as a place-holder.  In theory the LFH isn't necessary, but in
+     * practice some utilities demand it.
+     */
+    lfhPosn = ftell(mZipFp);
+    pEntry->mLFH.write(mZipFp);
+    startPosn = ftell(mZipFp);
+
+    /*
+     * Copy the data in, possibly compressing it as we go.
+     */
+    if (sourceType == ZipEntry::kCompressStored) {
+        if (compressionMethod == ZipEntry::kCompressDeflated) {
+            bool failed = false;
+            result = compressFpToFp(mZipFp, inputFp, data, size, &crc);
+            if (result != NO_ERROR) {
+                LOGD("compression failed, storing\n");
+                failed = true;
+            } else {
+                /*
+                 * Make sure it has compressed "enough".  This probably ought
+                 * to be set through an API call, but I don't expect our
+                 * criteria to change over time.
+                 */
+                long src = inputFp ? ftell(inputFp) : size;
+                long dst = ftell(mZipFp) - startPosn;
+                if (dst + (dst / 10) > src) {
+                    LOGD("insufficient compression (src=%ld dst=%ld), storing\n",
+                        src, dst);
+                    failed = true;
+                }
+            }
+
+            if (failed) {
+                compressionMethod = ZipEntry::kCompressStored;
+                if (inputFp) rewind(inputFp);
+                fseek(mZipFp, startPosn, SEEK_SET);
+                /* fall through to kCompressStored case */
+            }
+        }
+        /* handle "no compression" request, or failed compression from above */
+        if (compressionMethod == ZipEntry::kCompressStored) {
+            if (inputFp) {
+                result = copyFpToFp(mZipFp, inputFp, &crc);
+            } else {
+                result = copyDataToFp(mZipFp, data, size, &crc);
+            }
+            if (result != NO_ERROR) {
+                // don't need to truncate; happens in CDE rewrite
+                LOGD("failed copying data in\n");
+                goto bail;
+            }
+        }
+
+        // currently seeked to end of file
+        uncompressedLen = inputFp ? ftell(inputFp) : size;
+    } else if (sourceType == ZipEntry::kCompressDeflated) {
+        /* we should support uncompressed-from-compressed, but it's not
+         * important right now */
+        assert(compressionMethod == ZipEntry::kCompressDeflated);
+
+        bool scanResult;
+        int method;
+        long compressedLen;
+
+        scanResult = ZipUtils::examineGzip(inputFp, &method, &uncompressedLen,
+                        &compressedLen, &crc);
+        if (!scanResult || method != ZipEntry::kCompressDeflated) {
+            LOGD("this isn't a deflated gzip file?");
+            result = UNKNOWN_ERROR;
+            goto bail;
+        }
+
+        result = copyPartialFpToFp(mZipFp, inputFp, compressedLen, NULL);
+        if (result != NO_ERROR) {
+            LOGD("failed copying gzip data in\n");
+            goto bail;
+        }
+    } else {
+        assert(false);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /*
+     * We could write the "Data Descriptor", but there doesn't seem to
+     * be any point since we're going to go back and write the LFH.
+     *
+     * Update file offsets.
+     */
+    endPosn = ftell(mZipFp);            // seeked to end of compressed data
+
+    /*
+     * Success!  Fill out new values.
+     */
+    pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc,
+        compressionMethod);
+    modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp));
+    pEntry->setModWhen(modWhen);
+    pEntry->setLFHOffset(lfhPosn);
+    mEOCD.mNumEntries++;
+    mEOCD.mTotalNumEntries++;
+    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
+    mEOCD.mCentralDirOffset = endPosn;
+
+    /*
+     * Go back and write the LFH.
+     */
+    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+    pEntry->mLFH.write(mZipFp);
+
+    /*
+     * Add pEntry to the list.
+     */
+    mEntries.add(pEntry);
+    if (ppEntry != NULL)
+        *ppEntry = pEntry;
+    pEntry = NULL;
+
+bail:
+    if (inputFp != NULL)
+        fclose(inputFp);
+    delete pEntry;
+    return result;
+}
+
+/*
+ * Add an entry by copying it from another zip file.  If "padding" is
+ * nonzero, the specified number of bytes will be added to the "extra"
+ * field in the header.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
+    int padding, ZipEntry** ppEntry)
+{
+    ZipEntry* pEntry = NULL;
+    status_t result;
+    long lfhPosn, endPosn;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+
+    /* make sure we're in a reasonable state */
+    assert(mZipFp != NULL);
+    assert(mEntries.size() == mEOCD.mTotalNumEntries);
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    pEntry = new ZipEntry;
+    if (pEntry == NULL) {
+        result = NO_MEMORY;
+        goto bail;
+    }
+
+    result = pEntry->initFromExternal(pSourceZip, pSourceEntry);
+    if (result != NO_ERROR)
+        goto bail;
+    if (padding != 0) {
+        result = pEntry->addPadding(padding);
+        if (result != NO_ERROR)
+            goto bail;
+    }
+
+    /*
+     * From here on out, failures are more interesting.
+     */
+    mNeedCDRewrite = true;
+
+    /*
+     * Write the LFH.  Since we're not recompressing the data, we already
+     * have all of the fields filled out.
+     */
+    lfhPosn = ftell(mZipFp);
+    pEntry->mLFH.write(mZipFp);
+
+    /*
+     * Copy the data over.
+     *
+     * If the "has data descriptor" flag is set, we want to copy the DD
+     * fields as well.  This is a fixed-size area immediately following
+     * the data.
+     */
+    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
+    {
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    off_t copyLen;
+    copyLen = pSourceEntry->getCompressedLen();
+    if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
+        copyLen += ZipEntry::kDataDescriptorLen;
+
+    if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)
+        != NO_ERROR)
+    {
+        LOGW("copy of '%s' failed\n", pEntry->mCDE.mFileName);
+        result = UNKNOWN_ERROR;
+        goto bail;
+    }
+
+    /*
+     * Update file offsets.
+     */
+    endPosn = ftell(mZipFp);
+
+    /*
+     * Success!  Fill out new values.
+     */
+    pEntry->setLFHOffset(lfhPosn);      // sets mCDE.mLocalHeaderRelOffset
+    mEOCD.mNumEntries++;
+    mEOCD.mTotalNumEntries++;
+    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
+    mEOCD.mCentralDirOffset = endPosn;
+
+    /*
+     * Add pEntry to the list.
+     */
+    mEntries.add(pEntry);
+    if (ppEntry != NULL)
+        *ppEntry = pEntry;
+    pEntry = NULL;
+
+    result = NO_ERROR;
+
+bail:
+    delete pEntry;
+    return result;
+}
+
+/*
+ * Copy all of the bytes in "src" to "dst".
+ *
+ * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
+ * will be seeked immediately past the data.
+ */
+status_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32)
+{
+    unsigned char tmpBuf[32768];
+    size_t count;
+
+    *pCRC32 = crc32(0L, Z_NULL, 0);
+
+    while (1) {
+        count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp);
+        if (ferror(srcFp) || ferror(dstFp))
+            return errnoToStatus(errno);
+        if (count == 0)
+            break;
+
+        *pCRC32 = crc32(*pCRC32, tmpBuf, count);
+
+        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
+            LOGD("fwrite %d bytes failed\n", (int) count);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Copy all of the bytes in "src" to "dst".
+ *
+ * On exit, "dstFp" will be seeked immediately past the data.
+ */
+status_t ZipFile::copyDataToFp(FILE* dstFp,
+    const void* data, size_t size, unsigned long* pCRC32)
+{
+    size_t count;
+
+    *pCRC32 = crc32(0L, Z_NULL, 0);
+    if (size > 0) {
+        *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);
+        if (fwrite(data, 1, size, dstFp) != size) {
+            LOGD("fwrite %d bytes failed\n", (int) size);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Copy some of the bytes in "src" to "dst".
+ *
+ * If "pCRC32" is NULL, the CRC will not be computed.
+ *
+ * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
+ * will be seeked immediately past the data just written.
+ */
+status_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
+    unsigned long* pCRC32)
+{
+    unsigned char tmpBuf[32768];
+    size_t count;
+
+    if (pCRC32 != NULL)
+        *pCRC32 = crc32(0L, Z_NULL, 0);
+
+    while (length) {
+        long readSize;
+        
+        readSize = sizeof(tmpBuf);
+        if (readSize > length)
+            readSize = length;
+
+        count = fread(tmpBuf, 1, readSize, srcFp);
+        if ((long) count != readSize) {     // error or unexpected EOF
+            LOGD("fread %d bytes failed\n", (int) readSize);
+            return UNKNOWN_ERROR;
+        }
+
+        if (pCRC32 != NULL)
+            *pCRC32 = crc32(*pCRC32, tmpBuf, count);
+
+        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
+            LOGD("fwrite %d bytes failed\n", (int) count);
+            return UNKNOWN_ERROR;
+        }
+
+        length -= readSize;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Compress all of the data in "srcFp" and write it to "dstFp".
+ *
+ * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
+ * will be seeked immediately past the compressed data.
+ */
+status_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp,
+    const void* data, size_t size, unsigned long* pCRC32)
+{
+    status_t result = NO_ERROR;
+	const size_t kBufSize = 32768;
+	unsigned char* inBuf = NULL;
+	unsigned char* outBuf = NULL;
+	z_stream zstream;
+    bool atEof = false;     // no feof() aviailable yet
+	unsigned long crc;
+	int zerr;
+
+	/*
+	 * Create an input buffer and an output buffer.
+	 */
+	inBuf = new unsigned char[kBufSize];
+	outBuf = new unsigned char[kBufSize];
+	if (inBuf == NULL || outBuf == NULL) {
+		result = NO_MEMORY;
+		goto bail;
+	}
+
+	/*
+	 * Initialize the zlib stream.
+	 */
+	memset(&zstream, 0, sizeof(zstream));
+	zstream.zalloc = Z_NULL;
+	zstream.zfree = Z_NULL;
+	zstream.opaque = Z_NULL;
+	zstream.next_in = NULL;
+	zstream.avail_in = 0;
+	zstream.next_out = outBuf;
+	zstream.avail_out = kBufSize;
+	zstream.data_type = Z_UNKNOWN;
+
+	zerr = deflateInit2(&zstream, Z_BEST_COMPRESSION,
+		Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+	if (zerr != Z_OK) {
+		result = UNKNOWN_ERROR;
+		if (zerr == Z_VERSION_ERROR) {
+			LOGE("Installed zlib is not compatible with linked version (%s)\n",
+				ZLIB_VERSION);
+		} else {
+			LOGD("Call to deflateInit2 failed (zerr=%d)\n", zerr);
+		}
+		goto bail;
+	}
+
+ 	crc = crc32(0L, Z_NULL, 0);
+
+	/*
+	 * Loop while we have data.
+	 */
+	do {
+		size_t getSize;
+		int flush;
+
+		/* only read if the input buffer is empty */
+		if (zstream.avail_in == 0 && !atEof) {
+            LOGV("+++ reading %d bytes\n", (int)kBufSize);
+            if (data) {
+                getSize = size > kBufSize ? kBufSize : size;
+                memcpy(inBuf, data, getSize);
+                data = ((const char*)data) + getSize;
+                size -= getSize;
+            } else {
+                getSize = fread(inBuf, 1, kBufSize, srcFp);
+                if (ferror(srcFp)) {
+                    LOGD("deflate read failed (errno=%d)\n", errno);
+                    goto z_bail;
+                }
+            }
+            if (getSize < kBufSize) {
+                LOGV("+++  got %d bytes, EOF reached\n",
+                    (int)getSize);
+                atEof = true;
+            }
+
+			crc = crc32(crc, inBuf, getSize);
+
+			zstream.next_in = inBuf;
+			zstream.avail_in = getSize;
+		}
+
+		if (atEof)
+			flush = Z_FINISH;       /* tell zlib that we're done */
+		else
+			flush = Z_NO_FLUSH;     /* more to come! */
+
+		zerr = deflate(&zstream, flush);
+		if (zerr != Z_OK && zerr != Z_STREAM_END) {
+			LOGD("zlib deflate call failed (zerr=%d)\n", zerr);
+			result = UNKNOWN_ERROR;
+			goto z_bail;
+		}
+
+		/* write when we're full or when we're done */
+		if (zstream.avail_out == 0 ||
+			(zerr == Z_STREAM_END && zstream.avail_out != (uInt) kBufSize))
+		{
+			LOGV("+++ writing %d bytes\n", (int) (zstream.next_out - outBuf));
+            if (fwrite(outBuf, 1, zstream.next_out - outBuf, dstFp) !=
+                (size_t)(zstream.next_out - outBuf))
+            {
+				LOGD("write %d failed in deflate\n",
+                    (int) (zstream.next_out - outBuf));
+				goto z_bail;
+			}
+
+			zstream.next_out = outBuf;
+			zstream.avail_out = kBufSize;
+		}
+	} while (zerr == Z_OK);
+
+	assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+	*pCRC32 = crc;
+
+z_bail:
+	deflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] inBuf;
+	delete[] outBuf;
+
+	return result;
+}
+
+/*
+ * Mark an entry as deleted.
+ *
+ * We will eventually need to crunch the file down, but if several files
+ * are being removed (perhaps as part of an "update" process) we can make
+ * things considerably faster by deferring the removal to "flush" time.
+ */
+status_t ZipFile::remove(ZipEntry* pEntry)
+{
+    /*
+     * Should verify that pEntry is actually part of this archive, and
+     * not some stray ZipEntry from a different file.
+     */
+
+    /* mark entry as deleted, and mark archive as dirty */
+    pEntry->setDeleted();
+    mNeedCDRewrite = true;
+    return NO_ERROR;
+}
+
+/*
+ * Flush any pending writes.
+ *
+ * In particular, this will crunch out deleted entries, and write the
+ * Central Directory and EOCD if we have stomped on them.
+ */
+status_t ZipFile::flush(void)
+{
+    status_t result = NO_ERROR;
+    long eocdPosn;
+    int i, count;
+
+    if (mReadOnly)
+        return INVALID_OPERATION;
+    if (!mNeedCDRewrite)
+        return NO_ERROR;
+
+    assert(mZipFp != NULL);
+
+    result = crunchArchive();
+    if (result != NO_ERROR)
+        return result;
+
+    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)
+        return UNKNOWN_ERROR;
+
+    count = mEntries.size();
+    for (i = 0; i < count; i++) {
+        ZipEntry* pEntry = mEntries[i];
+        pEntry->mCDE.write(mZipFp);
+    }
+
+    eocdPosn = ftell(mZipFp);
+    mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;
+
+    mEOCD.write(mZipFp);
+
+    /*
+     * If we had some stuff bloat up during compression and get replaced
+     * with plain files, or if we deleted some entries, there's a lot
+     * of wasted space at the end of the file.  Remove it now.
+     */
+    if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {
+        LOGW("ftruncate failed %ld: %s\n", ftell(mZipFp), strerror(errno));
+        // not fatal
+    }
+
+    /* should we clear the "newly added" flag in all entries now? */
+
+    mNeedCDRewrite = false;
+    return NO_ERROR;
+}
+
+/*
+ * Crunch deleted files out of an archive by shifting the later files down.
+ *
+ * Because we're not using a temp file, we do the operation inside the
+ * current file.
+ */
+status_t ZipFile::crunchArchive(void)
+{
+    status_t result = NO_ERROR;
+    int i, count;
+    long delCount, adjust;
+
+#if 0
+    printf("CONTENTS:\n");
+    for (i = 0; i < (int) mEntries.size(); i++) {
+        printf(" %d: lfhOff=%ld del=%d\n",
+            i, mEntries[i]->getLFHOffset(), mEntries[i]->getDeleted());
+    }
+    printf("  END is %ld\n", (long) mEOCD.mCentralDirOffset);
+#endif
+
+    /*
+     * Roll through the set of files, shifting them as appropriate.  We
+     * could probably get a slight performance improvement by sliding
+     * multiple files down at once (because we could use larger reads
+     * when operating on batches of small files), but it's not that useful.
+     */
+    count = mEntries.size();
+    delCount = adjust = 0;
+    for (i = 0; i < count; i++) {
+        ZipEntry* pEntry = mEntries[i];
+        long span;
+
+        if (pEntry->getLFHOffset() != 0) {
+            long nextOffset;
+
+            /* Get the length of this entry by finding the offset
+             * of the next entry.  Directory entries don't have
+             * file offsets, so we need to find the next non-directory
+             * entry.
+             */
+            nextOffset = 0;
+            for (int ii = i+1; nextOffset == 0 && ii < count; ii++)
+                nextOffset = mEntries[ii]->getLFHOffset();
+            if (nextOffset == 0)
+                nextOffset = mEOCD.mCentralDirOffset;
+            span = nextOffset - pEntry->getLFHOffset();
+
+            assert(span >= ZipEntry::LocalFileHeader::kLFHLen);
+        } else {
+            /* This is a directory entry.  It doesn't have
+             * any actual file contents, so there's no need to
+             * move anything.
+             */
+            span = 0;
+        }
+
+        //printf("+++ %d: off=%ld span=%ld del=%d [count=%d]\n",
+        //    i, pEntry->getLFHOffset(), span, pEntry->getDeleted(), count);
+
+        if (pEntry->getDeleted()) {
+            adjust += span;
+            delCount++;
+
+            delete pEntry;
+            mEntries.removeAt(i);
+
+            /* adjust loop control */
+            count--;
+            i--;
+        } else if (span != 0 && adjust > 0) {
+            /* shuffle this entry back */
+            //printf("+++ Shuffling '%s' back %ld\n",
+            //    pEntry->getFileName(), adjust);
+            result = filemove(mZipFp, pEntry->getLFHOffset() - adjust,
+                        pEntry->getLFHOffset(), span);
+            if (result != NO_ERROR) {
+                /* this is why you use a temp file */
+                LOGE("error during crunch - archive is toast\n");
+                return result;
+            }
+
+            pEntry->setLFHOffset(pEntry->getLFHOffset() - adjust);
+        }
+    }
+
+    /*
+     * Fix EOCD info.  We have to wait until the end to do some of this
+     * because we use mCentralDirOffset to determine "span" for the
+     * last entry.
+     */
+    mEOCD.mCentralDirOffset -= adjust;
+    mEOCD.mNumEntries -= delCount;
+    mEOCD.mTotalNumEntries -= delCount;
+    mEOCD.mCentralDirSize = 0;  // mark invalid; set by flush()
+
+    assert(mEOCD.mNumEntries == mEOCD.mTotalNumEntries);
+    assert(mEOCD.mNumEntries == count);
+
+    return result;
+}
+
+/*
+ * Works like memmove(), but on pieces of a file.
+ */
+status_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n)
+{
+    if (dst == src || n <= 0)
+        return NO_ERROR;
+
+    unsigned char readBuf[32768];
+
+    if (dst < src) {
+        /* shift stuff toward start of file; must read from start */
+        while (n != 0) {
+            size_t getSize = sizeof(readBuf);
+            if (getSize > n)
+                getSize = n;
+
+            if (fseek(fp, (long) src, SEEK_SET) != 0) {
+                LOGD("filemove src seek %ld failed\n", (long) src);
+                return UNKNOWN_ERROR;
+            }
+
+            if (fread(readBuf, 1, getSize, fp) != getSize) {
+                LOGD("filemove read %ld off=%ld failed\n",
+                    (long) getSize, (long) src);
+                return UNKNOWN_ERROR;
+            }
+
+            if (fseek(fp, (long) dst, SEEK_SET) != 0) {
+                LOGD("filemove dst seek %ld failed\n", (long) dst);
+                return UNKNOWN_ERROR;
+            }
+
+            if (fwrite(readBuf, 1, getSize, fp) != getSize) {
+                LOGD("filemove write %ld off=%ld failed\n",
+                    (long) getSize, (long) dst);
+                return UNKNOWN_ERROR;
+            }
+
+            src += getSize;
+            dst += getSize;
+            n -= getSize;
+        }
+    } else {
+        /* shift stuff toward end of file; must read from end */
+        assert(false);      // write this someday, maybe
+        return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+
+/*
+ * Get the modification time from a file descriptor.
+ */
+time_t ZipFile::getModTime(int fd)
+{
+    struct stat sb;
+
+    if (fstat(fd, &sb) < 0) {
+        LOGD("HEY: fstat on fd %d failed\n", fd);
+        return (time_t) -1;
+    }
+
+    return sb.st_mtime;
+}
+
+
+#if 0       /* this is a bad idea */
+/*
+ * Get a copy of the Zip file descriptor.
+ *
+ * We don't allow this if the file was opened read-write because we tend
+ * to leave the file contents in an uncertain state between calls to
+ * flush().  The duplicated file descriptor should only be valid for reads.
+ */
+int ZipFile::getZipFd(void) const
+{
+    if (!mReadOnly)
+        return INVALID_OPERATION;
+    assert(mZipFp != NULL);
+
+    int fd;
+    fd = dup(fileno(mZipFp));
+    if (fd < 0) {
+        LOGD("didn't work, errno=%d\n", errno);
+    }
+
+    return fd;
+}
+#endif
+
+
+#if 0
+/*
+ * Expand data.
+ */
+bool ZipFile::uncompress(const ZipEntry* pEntry, void* buf) const
+{
+    return false;
+}
+#endif
+
+// free the memory when you're done
+void* ZipFile::uncompress(const ZipEntry* entry)
+{
+    size_t unlen = entry->getUncompressedLen();
+    size_t clen = entry->getCompressedLen();
+
+    void* buf = malloc(unlen);
+    if (buf == NULL) {
+        return NULL;
+    }
+
+    fseek(mZipFp, 0, SEEK_SET);
+
+    off_t offset = entry->getFileOffset();
+    if (fseek(mZipFp, offset, SEEK_SET) != 0) {
+        goto bail;
+    }
+
+    switch (entry->getCompressionMethod())
+    {
+        case ZipEntry::kCompressStored: {
+            ssize_t amt = fread(buf, 1, unlen, mZipFp);
+            if (amt != (ssize_t)unlen) {
+                goto bail;
+            }
+#if 0
+            printf("data...\n");
+            const unsigned char* p = (unsigned char*)buf;
+            const unsigned char* end = p+unlen;
+            for (int i=0; i<32 && p < end; i++) {
+                printf("0x%08x ", (int)(offset+(i*0x10)));
+                for (int j=0; j<0x10 && p < end; j++) {
+                    printf(" %02x", *p);
+                    p++;
+                }
+                printf("\n");
+            }
+#endif
+
+            }
+            break;
+        case ZipEntry::kCompressDeflated: {
+            if (!ZipUtils::inflateToBuffer(mZipFp, buf, unlen, clen)) {
+                goto bail;
+            }
+            }
+            break;
+        default:
+            goto bail;
+    }
+    return buf;
+
+bail:
+    free(buf);
+    return NULL;
+}
+
+
+/*
+ * ===========================================================================
+ *		ZipFile::EndOfCentralDir
+ * ===========================================================================
+ */
+
+/*
+ * Read the end-of-central-dir fields.
+ *
+ * "buf" should be positioned at the EOCD signature, and should contain
+ * the entire EOCD area including the comment.
+ */
+status_t ZipFile::EndOfCentralDir::readBuf(const unsigned char* buf, int len)
+{
+    /* don't allow re-use */
+    assert(mComment == NULL);
+
+    if (len < kEOCDLen) {
+        /* looks like ZIP file got truncated */
+        LOGD(" Zip EOCD: expected >= %d bytes, found %d\n",
+            kEOCDLen, len);
+        return INVALID_OPERATION;
+    }
+
+    /* this should probably be an assert() */
+    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature)
+        return UNKNOWN_ERROR;
+
+    mDiskNumber = ZipEntry::getShortLE(&buf[0x04]);
+    mDiskWithCentralDir = ZipEntry::getShortLE(&buf[0x06]);
+    mNumEntries = ZipEntry::getShortLE(&buf[0x08]);
+    mTotalNumEntries = ZipEntry::getShortLE(&buf[0x0a]);
+    mCentralDirSize = ZipEntry::getLongLE(&buf[0x0c]);
+    mCentralDirOffset = ZipEntry::getLongLE(&buf[0x10]);
+    mCommentLen = ZipEntry::getShortLE(&buf[0x14]);
+
+    // TODO: validate mCentralDirOffset
+
+    if (mCommentLen > 0) {
+        if (kEOCDLen + mCommentLen > len) {
+            LOGD("EOCD(%d) + comment(%d) exceeds len (%d)\n",
+                kEOCDLen, mCommentLen, len);
+            return UNKNOWN_ERROR;
+        }
+        mComment = new unsigned char[mCommentLen];
+        memcpy(mComment, buf + kEOCDLen, mCommentLen);
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Write an end-of-central-directory section.
+ */
+status_t ZipFile::EndOfCentralDir::write(FILE* fp)
+{
+    unsigned char buf[kEOCDLen];
+
+    ZipEntry::putLongLE(&buf[0x00], kSignature);
+    ZipEntry::putShortLE(&buf[0x04], mDiskNumber);
+    ZipEntry::putShortLE(&buf[0x06], mDiskWithCentralDir);
+    ZipEntry::putShortLE(&buf[0x08], mNumEntries);
+    ZipEntry::putShortLE(&buf[0x0a], mTotalNumEntries);
+    ZipEntry::putLongLE(&buf[0x0c], mCentralDirSize);
+    ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset);
+    ZipEntry::putShortLE(&buf[0x14], mCommentLen);
+
+    if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen)
+        return UNKNOWN_ERROR;
+    if (mCommentLen > 0) {
+        assert(mComment != NULL);
+        if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen)
+            return UNKNOWN_ERROR;
+    }
+
+    return NO_ERROR;
+}
+
+/*
+ * Dump the contents of an EndOfCentralDir object.
+ */
+void ZipFile::EndOfCentralDir::dump(void) const
+{
+    LOGD(" EndOfCentralDir contents:\n");
+    LOGD("  diskNum=%u diskWCD=%u numEnt=%u totalNumEnt=%u\n",
+        mDiskNumber, mDiskWithCentralDir, mNumEntries, mTotalNumEntries);
+    LOGD("  centDirSize=%lu centDirOff=%lu commentLen=%u\n",
+        mCentralDirSize, mCentralDirOffset, mCommentLen);
+}
+
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/utils/ZipFileCRO.cpp
new file mode 100644
index 0000000..d312daf
--- /dev/null
+++ b/libs/utils/ZipFileCRO.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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 "utils/ZipFileCRO.h"
+#include "utils/ZipFileRO.h"
+
+using namespace android;
+
+ZipFileCRO ZipFileXRO_open(const char* path) {
+    ZipFileRO* zip = new ZipFileRO();
+    if (zip->open(path) == NO_ERROR) {
+        return (ZipFileCRO)zip;
+    }
+    return NULL;
+}
+
+void ZipFileCRO_destroy(ZipFileCRO zipToken) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    delete zip;
+}
+
+ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zipToken,
+        const char* fileName) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    return (ZipEntryCRO)zip->findEntryByName(fileName);
+}
+
+bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
+        int* pMethod, long* pUncompLen,
+        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    ZipEntryRO entry = (ZipEntryRO)entryToken;
+    return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
+            pModWhen, pCrc32);
+}
+
+bool ZipFileCRO_uncompressEntry(ZipFileCRO zipToken, ZipEntryRO entryToken, int fd) {
+    ZipFileRO* zip = (ZipFileRO*)zipToken;
+    ZipEntryRO entry = (ZipEntryRO)entryToken;
+    return zip->uncompressEntry(entry, fd);
+}
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
new file mode 100644
index 0000000..ae8c719
--- /dev/null
+++ b/libs/utils/ZipFileRO.cpp
@@ -0,0 +1,724 @@
+/*
+ * 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.
+ */
+
+//
+// Read-only access to Zip archives, with minimal heap allocation.
+//
+#define LOG_TAG "zipro"
+//#define LOG_NDEBUG 0
+#include "utils/ZipFileRO.h"
+#include "utils/Log.h"
+#include "utils/misc.h"
+
+#include <zlib.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+using namespace android;
+
+/*
+ * Zip file constants.
+ */
+#define kEOCDSignature      0x06054b50
+#define kEOCDLen            22
+#define kEOCDNumEntries     8               // offset to #of entries in file
+#define kEOCDFileOffset     16              // offset to central directory
+
+#define kMaxCommentLen      65535           // longest possible in ushort
+#define kMaxEOCDSearch      (kMaxCommentLen + kEOCDLen)
+
+#define kLFHSignature       0x04034b50
+#define kLFHLen             30              // excluding variable-len fields
+#define kLFHNameLen         26              // offset to filename length
+#define kLFHExtraLen        28              // offset to extra length
+
+#define kCDESignature       0x02014b50
+#define kCDELen             46              // excluding variable-len fields
+#define kCDEMethod          10              // offset to compression method
+#define kCDEModWhen         12              // offset to modification timestamp
+#define kCDECRC             16              // offset to entry CRC
+#define kCDECompLen         20              // offset to compressed length
+#define kCDEUncompLen       24              // offset to uncompressed length
+#define kCDENameLen         28              // offset to filename length
+#define kCDEExtraLen        30              // offset to extra length
+#define kCDECommentLen      32              // offset to comment length
+#define kCDELocalOffset     42              // offset to local hdr
+
+/*
+ * The values we return for ZipEntryRO use 0 as an invalid value, so we
+ * want to adjust the hash table index by a fixed amount.  Using a large
+ * value helps insure that people don't mix & match arguments, e.g. to
+ * findEntryByIndex().
+ */
+#define kZipEntryAdj        10000
+
+/*
+ * Convert a ZipEntryRO to a hash table index, verifying that it's in a
+ * valid range.
+ */
+int ZipFileRO::entryToIndex(const ZipEntryRO entry) const
+{
+    long ent = ((long) entry) - kZipEntryAdj;
+    if (ent < 0 || ent >= mHashTableSize || mHashTable[ent].name == NULL) {
+        LOGW("Invalid ZipEntryRO %p (%ld)\n", entry, ent);
+        return -1;
+    }
+    return ent;
+}
+
+
+/*
+ * Open the specified file read-only.  We memory-map the entire thing and
+ * close the file before returning.
+ */
+status_t ZipFileRO::open(const char* zipFileName)
+{
+    int fd = -1;
+    off_t length;
+
+    assert(mFileMap == NULL);
+
+    /*
+     * Open and map the specified file.
+     */
+    fd = ::open(zipFileName, O_RDONLY);
+    if (fd < 0) {
+        LOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
+        return NAME_NOT_FOUND;
+    }
+
+    length = lseek(fd, 0, SEEK_END);
+    if (length < 0) {
+        close(fd);
+        return UNKNOWN_ERROR;
+    }
+
+    mFileMap = new FileMap();
+    if (mFileMap == NULL) {
+        close(fd);
+        return NO_MEMORY;
+    }
+    if (!mFileMap->create(zipFileName, fd, 0, length, true)) {
+        LOGW("Unable to map '%s': %s\n", zipFileName, strerror(errno));
+        close(fd);
+        return UNKNOWN_ERROR;
+    }
+
+    mFd = fd;
+
+    /*
+     * Got it mapped, verify it and create data structures for fast access.
+     */
+    if (!parseZipArchive()) {
+        mFileMap->release();
+        mFileMap = NULL;
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+/*
+ * Parse the Zip archive, verifying its contents and initializing internal
+ * data structures.
+ */
+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;
+    }
+
+    /*
+     * 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);
+
+    /*
+     * 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;
+
+        if (get4LE(ptr) != kCDESignature) {
+            LOGW("Missed a central dir sig (at %d)\n", i);
+            goto bail;
+        }
+        if (ptr + kCDELen > basePtr + length) {
+            LOGW("Ran off the end (at %d)\n", i);
+            goto bail;
+        }
+
+        localHdrOffset = get4LE(ptr + kCDELocalOffset);
+        CHECK_OFFSET(localHdrOffset);
+        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);
+            goto bail;
+        }
+
+        ptr += kCDELen + fileNameLen + extraLen + commentLen;
+        CHECK_OFFSET(ptr - basePtr);
+    }
+
+    result = true;
+
+bail:
+    return result;
+#undef CHECK_OFFSET
+}
+
+
+/*
+ * Simple string hash function for non-null-terminated strings.
+ */
+/*static*/ unsigned int ZipFileRO::computeHash(const char* str, int len)
+{
+    unsigned int hash = 0;
+
+    while (len--)
+        hash = hash * 31 + *str++;
+
+    return hash;
+}
+
+/*
+ * Add a new entry to the hash table.
+ */
+void ZipFileRO::addToHash(const char* str, int strLen, unsigned int hash)
+{
+    int ent = hash & (mHashTableSize-1);
+
+    /*
+     * We over-allocate the table, so we're guaranteed to find an empty slot.
+     */
+    while (mHashTable[ent].name != NULL)
+        ent = (ent + 1) & (mHashTableSize-1);
+
+    mHashTable[ent].name = str;
+    mHashTable[ent].nameLen = strLen;
+}
+
+/*
+ * Find a matching entry.
+ *
+ * Returns 0 if not found.
+ */
+ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
+{
+    int nameLen = strlen(fileName);
+    unsigned int hash = computeHash(fileName, nameLen);
+    int ent = hash & (mHashTableSize-1);
+
+    while (mHashTable[ent].name != NULL) {
+        if (mHashTable[ent].nameLen == nameLen &&
+            memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
+        {
+            /* match */
+            return (ZipEntryRO) (ent + kZipEntryAdj);
+        }
+
+        ent = (ent + 1) & (mHashTableSize-1);
+    }
+
+    return NULL;
+}
+
+/*
+ * Find the Nth entry.
+ *
+ * This currently involves walking through the sparse hash table, counting
+ * non-empty entries.  If we need to speed this up we can either allocate
+ * a parallel lookup table or (perhaps better) provide an iterator interface.
+ */
+ZipEntryRO ZipFileRO::findEntryByIndex(int idx) const
+{
+    if (idx < 0 || idx >= mNumEntries) {
+        LOGW("Invalid index %d\n", idx);
+        return NULL;
+    }
+
+    for (int ent = 0; ent < mHashTableSize; ent++) {
+        if (mHashTable[ent].name != NULL) {
+            if (idx-- == 0)
+                return (ZipEntryRO) (ent + kZipEntryAdj);
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Get the useful fields from the zip entry.
+ *
+ * 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
+{
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return false;
+
+    /*
+     * Recover the start of the central directory entry from the filename
+     * pointer.
+     */
+    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
+    const unsigned char* ptr = (const unsigned char*) mHashTable[ent].name;
+    size_t zipLength = mFileMap->getDataLength();
+
+    ptr -= kCDELen;
+
+    int method = get2LE(ptr + kCDEMethod);
+    if (pMethod != NULL)
+        *pMethod = method;
+
+    if (pModWhen != NULL)
+        *pModWhen = get4LE(ptr + kCDEModWhen);
+    if (pCrc32 != NULL)
+        *pCrc32 = get4LE(ptr + kCDECRC);
+
+    /*
+     * 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.
+     */
+    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) {
+        *pOffset = dataOffset;
+    }
+    return true;
+}
+
+/*
+ * Copy the entry's filename to the buffer.
+ */
+int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)
+    const
+{
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return -1;
+
+    int nameLen = mHashTable[ent].nameLen;
+    if (bufLen < nameLen+1)
+        return nameLen+1;
+
+    memcpy(buffer, mHashTable[ent].name, nameLen);
+    buffer[nameLen] = '\0';
+    return 0;
+}
+
+/*
+ * Create a new FileMap object that spans the data in "entry".
+ */
+FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
+{
+    /*
+     * TODO: the efficient way to do this is to modify FileMap to allow
+     * sub-regions of a file to be mapped.  A reference-counting scheme
+     * can manage the base memory mapping.  For now, we just create a brand
+     * new mapping off of the Zip archive file descriptor.
+     */
+
+    FileMap* newMap;
+    long 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)) {
+        newMap->release();
+        return NULL;
+    }
+
+    return newMap;
+}
+
+/*
+ * Uncompress an entry, in its entirety, into the provided output buffer.
+ *
+ * This doesn't verify the data's CRC, which might be useful for
+ * uncompressed data.  The caller should be able to manage it.
+ */
+bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
+{
+    const int 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;
+    off_t offset;
+
+    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
+
+    /*
+     * 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
+     * bunch of compressed or uncompressed data sequentially.  The CDE
+     * visit will cause a limited amount of read-ahead because it's at
+     * the end of the file.  We could end up doing lots of extra disk
+     * access if the file we're prying open is small.  Bottom line is we
+     * probably don't want to turn MADV_SEQUENTIAL on and leave it on.
+     *
+     * So, if the compressed size of the file is above a certain minimum
+     * size, temporarily boost the read-ahead in the hope that the extra
+     * pair of system calls are negated by a reduction in page faults.
+     */
+    if (compLen > kSequentialMin)
+        mFileMap->advise(FileMap::SEQUENTIAL);
+
+    if (method == kCompressStored) {
+        memcpy(buffer, basePtr + offset, uncompLen);
+    } else {
+        if (!inflateBuffer(buffer, basePtr + offset, uncompLen, compLen))
+            goto bail;
+    }
+
+    if (compLen > kSequentialMin)
+        mFileMap->advise(FileMap::NORMAL);
+
+    result = true;
+
+bail:
+    return result;
+}
+
+/*
+ * Uncompress an entry, in its entirety, to an open file descriptor.
+ *
+ * This doesn't verify the data's CRC, but probably should.
+ */
+bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
+{
+    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;
+    off_t offset;
+
+    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
+
+    if (method == kCompressStored) {
+        ssize_t actual;
+
+        actual = write(fd, basePtr + offset, uncompLen);
+        if (actual < 0) {
+            LOGE("Write failed: %s\n", strerror(errno));
+            goto bail;
+        } else if (actual != uncompLen) {
+            LOGE("Partial write during uncompress (%d of %ld)\n",
+                (int)actual, uncompLen);
+            goto bail;
+        } else {
+            LOGI("+++ successful write\n");
+        }
+    } else {
+        if (!inflateBuffer(fd, basePtr+offset, uncompLen, compLen))
+            goto bail;
+    }
+
+    result = true;
+
+bail:
+    return result;
+}
+
+/*
+ * Uncompress "deflate" data from one buffer to another.
+ */
+/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
+    long uncompLen, long compLen)
+{
+    bool result = false;
+    z_stream zstream;
+    int zerr;
+
+    /*
+     * Initialize the zlib stream struct.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = (Bytef*)inBuf;
+    zstream.avail_in = compLen;
+    zstream.next_out = (Bytef*) outBuf;
+    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.
+	 */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Expand data.
+     */
+    zerr = inflate(&zstream, Z_FINISH);
+    if (zerr != Z_STREAM_END) {
+        LOGW("Zip inflate failed, zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
+            zerr, zstream.next_in, zstream.avail_in,
+            zstream.next_out, zstream.avail_out);
+        goto z_bail;
+    }
+
+    /* paranoia */
+    if ((long) zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompLen);
+        goto z_bail;
+    }
+
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+    return result;
+}
+
+/*
+ * Uncompress "deflate" data from one buffer to an open file descriptor.
+ */
+/*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
+    long uncompLen, long compLen)
+{
+    bool result = false;
+    const int kWriteBufSize = 32768;
+    unsigned char writeBuf[kWriteBufSize];
+    z_stream zstream;
+    int zerr;
+
+    /*
+     * Initialize the zlib stream struct.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = (Bytef*)inBuf;
+    zstream.avail_in = compLen;
+    zstream.next_out = (Bytef*) writeBuf;
+    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.
+	 */
+    zerr = inflateInit2(&zstream, -MAX_WBITS);
+    if (zerr != Z_OK) {
+        if (zerr == Z_VERSION_ERROR) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Loop while we have more to do.
+     */
+    do {
+        /*
+         * Expand data.
+         */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            LOGW("zlib inflate: zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
+                zerr, zstream.next_in, zstream.avail_in,
+                zstream.next_out, zstream.avail_out);
+            goto z_bail;
+        }
+
+        /* write when we're full or when we're done */
+        if (zstream.avail_out == 0 ||
+            (zerr == Z_STREAM_END && zstream.avail_out != sizeof(writeBuf)))
+        {
+            long writeSize = zstream.next_out - writeBuf;
+            int cc = write(fd, writeBuf, writeSize);
+            if (cc != (int) writeSize) {
+                LOGW("write failed in inflate (%d vs %ld)\n", cc, writeSize);
+                goto z_bail;
+            }
+
+            zstream.next_out = writeBuf;
+            zstream.avail_out = sizeof(writeBuf);
+        }
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    /* paranoia */
+    if ((long) zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompLen);
+        goto z_bail;
+    }
+
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+    return result;
+}
diff --git a/libs/utils/ZipUtils.cpp b/libs/utils/ZipUtils.cpp
new file mode 100644
index 0000000..bfbacfe
--- /dev/null
+++ b/libs/utils/ZipUtils.cpp
@@ -0,0 +1,344 @@
+/*
+ * 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.
+ */
+
+//
+// Misc zip/gzip utility functions.
+//
+
+#define LOG_TAG "ziputil"
+
+#include "utils/ZipUtils.h"
+#include "utils/ZipFileRO.h"
+#include "utils/Log.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <zlib.h>
+
+using namespace android;
+
+/*
+ * Utility function that expands zip/gzip "deflate" compressed data
+ * into a buffer.
+ *
+ * "fd" is an open file positioned at the start of the "deflate" data
+ * "buf" must hold at least "uncompressedLen" bytes.
+ */
+/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,
+    long uncompressedLen, long compressedLen)
+{
+    bool result = false;
+	const unsigned long kReadBufSize = 32768;
+	unsigned char* readBuf = NULL;
+    z_stream zstream;
+    int zerr;
+    unsigned long compRemaining;
+
+    assert(uncompressedLen >= 0);
+    assert(compressedLen >= 0);
+
+	readBuf = new unsigned char[kReadBufSize];
+	if (readBuf == NULL)
+        goto bail;
+    compRemaining = compressedLen;
+
+    /*
+     * Initialize the zlib stream.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = NULL;
+    zstream.avail_in = 0;
+    zstream.next_out = (Bytef*) buf;
+    zstream.avail_out = uncompressedLen;
+    zstream.data_type = Z_UNKNOWN;
+
+	/*
+	 * 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) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Loop while we have data.
+     */
+    do {
+        unsigned long getSize;
+
+        /* read as much as we can */
+        if (zstream.avail_in == 0) {
+            getSize = (compRemaining > kReadBufSize) ?
+                        kReadBufSize : compRemaining;
+            LOGV("+++ reading %ld bytes (%ld left)\n",
+                getSize, compRemaining);
+
+            int cc = read(fd, readBuf, getSize);
+            if (cc != (int) getSize) {
+                LOGD("inflate read failed (%d vs %ld)\n",
+                    cc, getSize);
+                goto z_bail;
+            }
+
+            compRemaining -= getSize;
+
+            zstream.next_in = readBuf;
+            zstream.avail_in = getSize;
+        }
+
+        /* uncompress the data */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            LOGD("zlib inflate call failed (zerr=%d)\n", zerr);
+            goto z_bail;
+        }
+
+		/* output buffer holds all, so no need to write the output */
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    if ((long) zstream.total_out != uncompressedLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompressedLen);
+        goto z_bail;
+    }
+
+    // success!
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] readBuf;
+    return result;
+}
+
+/*
+ * Utility function that expands zip/gzip "deflate" compressed data
+ * into a buffer.
+ *
+ * (This is a clone of the previous function, but it takes a FILE* instead
+ * of an fd.  We could pass fileno(fd) to the above, but we can run into
+ * trouble when "fp" has a different notion of what fd's file position is.)
+ *
+ * "fp" is an open file positioned at the start of the "deflate" data
+ * "buf" must hold at least "uncompressedLen" bytes.
+ */
+/*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,
+    long uncompressedLen, long compressedLen)
+{
+    bool result = false;
+	const unsigned long kReadBufSize = 32768;
+	unsigned char* readBuf = NULL;
+    z_stream zstream;
+    int zerr;
+    unsigned long compRemaining;
+
+    assert(uncompressedLen >= 0);
+    assert(compressedLen >= 0);
+
+	readBuf = new unsigned char[kReadBufSize];
+	if (readBuf == NULL)
+        goto bail;
+    compRemaining = compressedLen;
+
+    /*
+     * Initialize the zlib stream.
+     */
+	memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = NULL;
+    zstream.avail_in = 0;
+    zstream.next_out = (Bytef*) buf;
+    zstream.avail_out = uncompressedLen;
+    zstream.data_type = Z_UNKNOWN;
+
+	/*
+	 * 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) {
+            LOGE("Installed zlib is not compatible with linked version (%s)\n",
+                ZLIB_VERSION);
+        } else {
+            LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
+        }
+        goto bail;
+    }
+
+    /*
+     * Loop while we have data.
+     */
+    do {
+        unsigned long getSize;
+
+        /* read as much as we can */
+        if (zstream.avail_in == 0) {
+            getSize = (compRemaining > kReadBufSize) ?
+                        kReadBufSize : compRemaining;
+            LOGV("+++ reading %ld bytes (%ld left)\n",
+                getSize, compRemaining);
+
+            int cc = fread(readBuf, getSize, 1, fp);
+            if (cc != (int) getSize) {
+                LOGD("inflate read failed (%d vs %ld)\n",
+                    cc, getSize);
+                goto z_bail;
+            }
+
+            compRemaining -= getSize;
+
+            zstream.next_in = readBuf;
+            zstream.avail_in = getSize;
+        }
+
+        /* uncompress the data */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            LOGD("zlib inflate call failed (zerr=%d)\n", zerr);
+            goto z_bail;
+        }
+
+		/* output buffer holds all, so no need to write the output */
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    if ((long) zstream.total_out != uncompressedLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+            zstream.total_out, uncompressedLen);
+        goto z_bail;
+    }
+
+    // success!
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] readBuf;
+    return result;
+}
+
+/*
+ * Look at the contents of a gzip archive.  We want to know where the
+ * data starts, and how long it will be after it is uncompressed.
+ *
+ * We expect to find the CRC and length as the last 8 bytes on the file.
+ * This is a pretty reasonable thing to expect for locally-compressed
+ * files, but there's a small chance that some extra padding got thrown
+ * on (the man page talks about compressed data written to tape).  We
+ * don't currently deal with that here.  If "gzip -l" whines, we're going
+ * to fail too.
+ *
+ * On exit, "fp" is pointing at the start of the compressed data.
+ */
+/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,
+    long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)
+{
+    enum {  // flags
+        FTEXT       = 0x01,
+        FHCRC       = 0x02,
+        FEXTRA      = 0x04,
+        FNAME       = 0x08,
+        FCOMMENT    = 0x10,
+    };
+    int ic;
+    int method, flags;
+    int i;
+
+    ic = getc(fp);
+    if (ic != 0x1f || getc(fp) != 0x8b)
+        return false;       // not gzip
+    method = getc(fp);
+    flags = getc(fp);
+
+    /* quick sanity checks */
+    if (method == EOF || flags == EOF)
+        return false;
+    if (method != ZipFileRO::kCompressDeflated)
+        return false;
+
+    /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */
+    for (i = 0; i < 6; i++)
+        (void) getc(fp);
+    /* consume "extra" field, if present */
+    if ((flags & FEXTRA) != 0) {
+        int len;
+
+        len = getc(fp);
+        len |= getc(fp) << 8;
+        while (len-- && getc(fp) != EOF)
+            ;
+    }
+    /* consume filename, if present */
+    if ((flags & FNAME) != 0) {
+        do {
+            ic = getc(fp);
+        } while (ic != 0 && ic != EOF);
+    }
+    /* consume comment, if present */
+    if ((flags & FCOMMENT) != 0) {
+        do {
+            ic = getc(fp);
+        } while (ic != 0 && ic != EOF);
+    }
+    /* consume 16-bit header CRC, if present */
+    if ((flags & FHCRC) != 0) {
+        (void) getc(fp);
+        (void) getc(fp);
+    }
+
+    if (feof(fp) || ferror(fp))
+        return false;
+
+    /* seek to the end; CRC and length are in the last 8 bytes */
+    long curPosn = ftell(fp);
+    unsigned char buf[8];
+    fseek(fp, -8, SEEK_END);
+    *pCompressedLen = ftell(fp) - curPosn;
+
+    if (fread(buf, 1, 8, fp) != 8)
+        return false;
+    /* seek back to start of compressed data */
+    fseek(fp, curPosn, SEEK_SET);
+
+    *pCompressionMethod = method;
+    *pCRC32 = ZipFileRO::get4LE(&buf[0]);
+    *pUncompressedLen = ZipFileRO::get4LE(&buf[4]);
+
+    return true;
+}
+
diff --git a/libs/utils/characterData.h b/libs/utils/characterData.h
new file mode 100644
index 0000000..e931d99
--- /dev/null
+++ b/libs/utils/characterData.h
@@ -0,0 +1,730 @@
+/*
+ * 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.
+ */
+
+// Automatically generated on 07-11-2006 by make-CharacterDataC
+// DO NOT EDIT DIRECTLY
+namespace CharacterData {
+
+    // Structure containing an array of ranges
+    struct Range {
+        int length;
+        const uint32_t* array;
+    };
+
+    // For Latin1 characters just index into this array to get the index and decomposition
+    static const uint16_t LATIN1_DATA[] = {
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0002, 0x0003, 0x0002, 0x0004, 0x0003, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0003, 0x0003, 0x0002, 
+        0x0005, 0x0006, 0x0006, 0x0007, 0x0008, 0x0007, 0x0006, 0x0006, 
+        0x0009, 0x000A, 0x0006, 0x000B, 0x000C, 0x000D, 0x000C, 0x000C, 
+        0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 
+        0x0016, 0x0017, 0x000C, 0x0006, 0x0018, 0x0019, 0x001A, 0x0006, 
+        0x0006, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 
+        0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 
+        0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 
+        0x0032, 0x0033, 0x0034, 0x0035, 0x0006, 0x0036, 0x0037, 0x0038, 
+        0x0037, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 
+        0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 
+        0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 
+        0x0050, 0x0051, 0x0052, 0x0035, 0x0019, 0x0036, 0x0019, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
+        0x5853, 0x0006, 0x0008, 0x0008, 0x0008, 0x0008, 0x0054, 0x0054, 
+        0x1037, 0x0054, 0x7855, 0x0056, 0x0019, 0x0057, 0x0054, 0x1037, 
+        0x0058, 0x0059, 0x785A, 0x785B, 0x1037, 0x105C, 0x0054, 0x0006, 
+        0x1037, 0x785D, 0x7855, 0x005E, 0x305F, 0x305F, 0x305F, 0x0006, 
+        0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0860, 
+        0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 
+        0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0019, 
+        0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0055, 
+        0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0861, 
+        0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 
+        0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0019, 
+        0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0862
+    };
+
+    // Each of these arrays is stripped into ranges. In order to build the arrays, each
+    // codepoint was bit-shifted so that even and odd characters were separated into different
+    // arrays. The identifier of each array is the top byte after bit-shifting.
+    // The numbers stored in the array are the bit-shifted codepoint, the decomposition, and an
+    // index into another array of all possible packed data values. The top 16 bits are the
+    // codepoint and the bottom 16 are the decomposition and index. The top 5 bits for the decomposition
+    // and the rest for the index.
+    static const uint32_t a0[] = {
+        0x00800863, 0x00880063, 0x00890863, 0x00930063, 0x00940863, 0x00980864, 0x00991063, 0x009A0863, 
+        0x009C0055, 0x009D0865, 0x00A01065, 0x00A10065, 0x00A20865, 0x00A50063, 0x00A60863, 0x00A90063, 
+        0x00AA0863, 0x00B30063, 0x00B40863, 0x00BC0866, 0x00BD0865, 0x00C00055, 0x00C10063, 0x00C30067, 
+        0x00C40065, 0x00C50068, 0x00C60065, 0x00C70069, 0x00C8006A, 0x00C90065, 0x00CA006B, 0x00CB006C, 
+        0x00CC0063, 0x00CD006D, 0x00CE006C, 0x00CF006E, 0x00D00863, 0x00D10063, 0x00D3006F, 0x00D40065, 
+        0x00D50055, 0x00D60063, 0x00D7006F, 0x00D80865, 0x00D90070, 0x00DA0065, 0x00DC0063, 0x00DD0055, 
+        0x00DE0063, 0x00DF0055, 0x00E00071, 0x00E21072, 0x00E31073, 0x00E41074, 0x00E51072, 0x00E61073, 
+        0x00E70865, 0x00EF0863, 0x00F20063, 0x00F30863, 0x00F80855, 0x00F91074, 0x00FA0863, 0x00FB0075, 
+        0x00FC0863, 0x010E0063, 0x010F0863, 0x01100076, 0x01110063, 0x01130863, 0x011A0055, 0x011D0077, 
+        0x011E0065, 0x011F0077, 0x01200055, 0x01210078, 0x01280055, 0x012A0079, 0x012B007A, 0x012C0055, 
+        0x0130007A, 0x01310055, 0x0134007B, 0x01350055, 0x0139007C, 0x013A0055, 0x0140007D, 0x01410055, 
+        0x0144007D, 0x0145007E, 0x01460055, 0x0149007F, 0x014A0080, 0x014B0055, 0x01587881, 0x015D0082, 
+        0x015E0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 0x01707881, 
+        0x01730037, 0x01770081, 0x01780037, 0x01800083, 0x01A00883, 0x01A10083, 0x01A20883, 0x01A30083, 
+        0x01B80078, 0x01BA0837, 0x01BB0078, 0x01BD1081, 0x01BE0078, 0x01BF0806, 0x01C00078, 0x01C21037, 
+        0x01C30884, 0x01C40885, 0x01C60886, 0x01C70887, 0x01C80855, 0x01C90060, 0x01D10078, 0x01D20060, 
+        0x01D50860, 0x01D60888, 0x01D70889, 0x01D80855, 0x01D90061, 0x01E1008A, 0x01E20061, 0x01E50861, 
+        0x01E6088B, 0x01E7088C, 0x01E8108D, 0x01E91077, 0x01EA0877, 0x01EB108E, 0x01EC0063, 0x01F8108F, 
+        0x01F91090, 0x01FA1091, 0x01FB0019, 0x01FC0065, 0x01FD0063, 0x01FE0055, 0x01FF0077, 0x02000892, 
+        0x02010092, 0x02060892, 0x02080060, 0x02180061, 0x02280893, 0x02290093, 0x022E0893, 0x02300063, 
+        0x023B0863, 0x023C0063, 0x02410094, 0x02420083, 0x02440095, 0x02450063, 0x02600077, 0x02610865, 
+        0x02620065, 0x02680863, 0x026A0063, 0x026B0863, 0x026C0063, 0x026D0863, 0x02700063, 0x02710863, 
+        0x02740063, 0x02750863, 0x027B0063, 0x027C0863, 0x027D0078, 0x02800063, 0x02880078, 0x02990096, 
+        0x02AC0078, 0x02AD0097, 0x02B00078, 0x02B10098, 0x02C40078, 0x02C50099, 0x02C60078, 0x02C90083, 
+        0x02DD0078, 0x02DE0083, 0x02DF009A, 0x02E10083, 0x02E3009A, 0x02E40078, 0x02E8009B, 0x02F60078, 
+        0x02F8009B, 0x02FA009A, 0x02FB0078, 0x0300009C, 0x03020078, 0x0306000C, 0x03070054, 0x03080083, 
+        0x030B0078, 0x030F009D, 0x03100078, 0x0311089E, 0x0314009E, 0x031E0078, 0x0320009F, 0x0321009E, 
+        0x03260083, 0x033000A0, 0x033100A1, 0x033200A2, 0x033300A3, 0x033400A4, 0x03350007, 0x033600A5, 
+        0x0337009E, 0x03380083, 0x0339009E, 0x033B109E, 0x033D009E, 0x0360089E, 0x0362009E, 0x036A009D, 
+        0x036B0083, 0x036F0095, 0x03700083, 0x0373009F, 0x03740083, 0x0377009E, 0x0378000E, 0x03790010, 
+        0x037A0012, 0x037B0014, 0x037C0016, 0x037D009E, 0x037F00A6, 0x0380009D, 0x03870078, 0x0388009E, 
+        0x03980083, 0x03A60078, 0x03A7009E, 0x03B70078, 0x03C0009E, 0x03D30083, 0x03D90078, 0x04810083, 
+        0x04820071, 0x049A0871, 0x049B0071, 0x049D0078, 0x049E0083, 0x049F00A7, 0x04A10083, 0x04A500A7, 
+        0x04A70078, 0x04A80071, 0x04A90083, 0x04AB0078, 0x04AC0871, 0x04B00071, 0x04B10083, 0x04B20097, 
+        0x04B300A8, 0x04B400A9, 0x04B500AA, 0x04B600AB, 0x04B700AC, 0x04B80097, 0x04B90078, 0x04C100A7, 
+        0x04C20078, 0x04C30071, 0x04C70078, 0x04C80071, 0x04C90078, 0x04CA0071, 0x04DA0078, 0x04DB0071, 
+        0x04DD0078, 0x04DE0083, 0x04DF00A7, 0x04E10083, 0x04E30078, 0x04E400A7, 0x04E50078, 0x04E608A7, 
+        0x04E70071, 0x04E80078, 0x04EE0871, 0x04EF0078, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F300A8, 
+        0x04F400A9, 0x04F500AA, 0x04F600AB, 0x04F700AC, 0x04F80071, 0x04F90008, 0x04FA00AD, 0x04FB00AE, 
+        0x04FC00AF, 0x04FD0094, 0x04FE0078, 0x05010083, 0x05020078, 0x05030071, 0x05060078, 0x05080071, 
+        0x05090078, 0x050A0071, 0x051A0078, 0x051B0871, 0x051C0071, 0x051D0078, 0x051E0083, 0x051F00A7, 
+        0x05210083, 0x05220078, 0x05240083, 0x05250078, 0x05260083, 0x05270078, 0x052D0871, 0x052E0071, 
+        0x052F0871, 0x05300078, 0x053300A8, 0x053400A9, 0x053500AA, 0x053600AB, 0x053700AC, 0x05380083, 
+        0x05390071, 0x053B0078, 0x05410083, 0x05420078, 0x05430071, 0x05470078, 0x05480071, 0x05490078, 
+        0x054A0071, 0x055A0078, 0x055B0071, 0x055D0078, 0x055E0083, 0x055F00A7, 0x05610083, 0x05630078, 
+        0x05640083, 0x05650078, 0x056600A7, 0x05670078, 0x05680071, 0x05690078, 0x05700071, 0x05710083, 
+        0x05720078, 0x057300A8, 0x057400A9, 0x057500AA, 0x057600AB, 0x057700AC, 0x05780078, 0x058100A7, 
+        0x05820078, 0x05830071, 0x05870078, 0x05880071, 0x05890078, 0x058A0071, 0x059A0078, 0x059B0071, 
+        0x059D0078, 0x059E0083, 0x059F00A7, 0x05A10083, 0x05A20078, 0x05A408A7, 0x05A50078, 0x05A608A7, 
+        0x05A70078, 0x05AB0083, 0x05AC0078, 0x05AE0871, 0x05AF0078, 0x05B00071, 0x05B10078, 0x05B300A8, 
+        0x05B400A9, 0x05B500AA, 0x05B600AB, 0x05B700AC, 0x05B80094, 0x05B90078, 0x05C10083, 0x05C20078, 
+        0x05C30071, 0x05C60078, 0x05C70071, 0x05CA0871, 0x05CB0078, 0x05CD0071, 0x05D00078, 0x05D20071, 
+        0x05D30078, 0x05D40071, 0x05D60078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 0x05E00083, 0x05E100A7, 
+        0x05E20078, 0x05E300A7, 0x05E508A7, 0x05E70078, 0x05F300A8, 0x05F400A9, 0x05F500AA, 0x05F600AB, 
+        0x05F700AC, 0x05F800B0, 0x05F900B1, 0x05FA0054, 0x05FE0078, 0x060100A7, 0x06020078, 0x06030071, 
+        0x061A0078, 0x061B0071, 0x061D0078, 0x061F0083, 0x062100A7, 0x06230083, 0x06240883, 0x06250083, 
+        0x06270078, 0x062B0083, 0x062C0078, 0x06300071, 0x06310078, 0x063300A8, 0x063400A9, 0x063500AA, 
+        0x063600AB, 0x063700AC, 0x06380078, 0x064100A7, 0x06420078, 0x06430071, 0x065A0078, 0x065B0071, 
+        0x065D0078, 0x065E0083, 0x065F00A7, 0x066008A7, 0x066100A7, 0x066300B2, 0x066408A7, 0x06660083, 
+        0x06670078, 0x066B00A7, 0x066C0078, 0x066F0071, 0x06710078, 0x067300A8, 0x067400A9, 0x067500AA, 
+        0x067600AB, 0x067700AC, 0x06780078, 0x068100A7, 0x06820078, 0x06830071, 0x069D0078, 0x069F00A7, 
+        0x06A10083, 0x06A20078, 0x06A300A7, 0x06A508A7, 0x06A70078, 0x06B00071, 0x06B10078, 0x06B300A8, 
+        0x06B400A9, 0x06B500AA, 0x06B600AB, 0x06B700AC, 0x06B80078, 0x06C100A7, 0x06C20078, 0x06C30071, 
+        0x06CC0078, 0x06CD0071, 0x06D90078, 0x06DA0071, 0x06DE0078, 0x06E00071, 0x06E40078, 0x06E50083, 
+        0x06E60078, 0x06E800A7, 0x06E90083, 0x06EC00A7, 0x06ED08A7, 0x06F00078, 0x06F900A7, 0x06FA0097, 
+        0x06FB0078, 0x07010071, 0x071A0083, 0x071E0078, 0x07200071, 0x07230081, 0x07240083, 0x072800A8, 
+        0x072900A9, 0x072A00AA, 0x072B00AB, 0x072C00AC, 0x072D0097, 0x072E0078, 0x07410071, 0x07430078, 
+        0x07440071, 0x07460078, 0x074A0071, 0x074C0078, 0x074D0071, 0x07500078, 0x07510071, 0x07520078, 
+        0x07550071, 0x07560078, 0x07570071, 0x075A0083, 0x075D0078, 0x075E0083, 0x075F0078, 0x07600071, 
+        0x07630081, 0x07640083, 0x07670078, 0x076800A8, 0x076900A9, 0x076A00AA, 0x076B00AB, 0x076C00AC, 
+        0x076D0078, 0x076E1071, 0x076F0078, 0x07800071, 0x07810094, 0x07820097, 0x07865897, 0x07870097, 
+        0x078A0094, 0x078C0083, 0x078D0094, 0x079000A8, 0x079100A9, 0x079200AA, 0x079300AB, 0x079400AC, 
+        0x079500B3, 0x079A0094, 0x079D00B4, 0x079F00A7, 0x07A00071, 0x07A40078, 0x07A50071, 0x07A90871, 
+        0x07AA0071, 0x07AE0871, 0x07AF0071, 0x07B60078, 0x07B90083, 0x07BB0883, 0x07BD0083, 0x07C40071, 
+        0x07C60078, 0x07C80083, 0x07CC0078, 0x07CD0083, 0x07D10883, 0x07D20083, 0x07D60883, 0x07D70083, 
+        0x07DF0094, 0x07E30083, 0x07E40094, 0x07E70078, 0x07E80097, 0x07E90078, 0x08000071, 0x08110078, 
+        0x08120071, 0x08130871, 0x08140078, 0x08150071, 0x081600A7, 0x08170083, 0x081A0078, 0x081B0083, 
+        0x081C00A7, 0x081D0078, 0x082000A8, 0x082100A9, 0x082200AA, 0x082300AB, 0x082400AC, 0x08250097, 
+        0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 0x08680071, 0x087E7881, 
+        0x087F0078, 0x08800071, 0x08AD0078, 0x08B00071, 0x08D20078, 0x08D40071, 0x08FD0078, 0x09000071, 
+        0x09270078, 0x09280071, 0x092F0078, 0x09300071, 0x09470078, 0x09480071, 0x095B0078, 0x095C0071, 
+        0x09630078, 0x09640071, 0x098B0078, 0x098C0071, 0x09AE0078, 0x09B00094, 0x09B10097, 0x09B500B6, 
+        0x09B600B7, 0x09B700B8, 0x09B800B9, 0x09B900B0, 0x09BA00BA, 0x09BB00BB, 0x09BC00BC, 0x09BD00BD, 
+        0x09BE00BE, 0x09BF0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FB0078, 0x0A010071, 
+        0x0B370097, 0x0B380071, 0x0B3C0078, 0x0B400005, 0x0B410071, 0x0B4E00BF, 0x0B4F0078, 0x0B500071, 
+        0x0B760097, 0x0B7700C0, 0x0B7800C1, 0x0B790078, 0x0B800071, 0x0B890083, 0x0B8B0078, 0x0B900071, 
+        0x0B990083, 0x0B9B0097, 0x0B9C0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB90083, 
+        0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB00A7, 0x0BDC0083, 0x0BDF00A7, 0x0BE30083, 0x0BE400A7, 
+        0x0BE50083, 0x0BEA0097, 0x0BEE0071, 0x0BEF0078, 0x0BF000A8, 0x0BF100A9, 0x0BF200AA, 0x0BF300AB, 
+        0x0BF400AC, 0x0BF50078, 0x0BF800C3, 0x0BF900C4, 0x0BFA00C5, 0x0BFB00C6, 0x0BFC00C7, 0x0BFD0078, 
+        0x0C000006, 0x0C030099, 0x0C040006, 0x0C060083, 0x0C070005, 0x0C0800A8, 0x0C0900A9, 0x0C0A00AA, 
+        0x0C0B00AB, 0x0C0C00AC, 0x0C0D0078, 0x0C100071, 0x0C3C0078, 0x0C400071, 0x0C550078, 0x0C800071, 
+        0x0C8F0078, 0x0C900083, 0x0C9200A7, 0x0C940083, 0x0C9500C8, 0x0C960078, 0x0C9800A7, 0x0C990083, 
+        0x0C9A00A7, 0x0C9D0083, 0x0C9E0078, 0x0CA00054, 0x0CA10078, 0x0CA20006, 0x0CA300A8, 0x0CA400A9, 
+        0x0CA500AA, 0x0CA600AB, 0x0CA700AC, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBB0078, 0x0CC00071, 
+        0x0CD50078, 0x0CD800A7, 0x0CE10071, 0x0CE400A7, 0x0CE50078, 0x0CE800A8, 0x0CE900A9, 0x0CEA00AA, 
+        0x0CEB00AB, 0x0CEC00AC, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0C0083, 0x0D0D00A7, 
+        0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0EA70081, 0x0EA87881, 0x0EB17055, 
+        0x0EB60055, 0x0EBC7881, 0x0EBD0055, 0x0ECE7881, 0x0EE00083, 0x0EE20078, 0x0F000863, 0x0F4B0855, 
+        0x0F4D1055, 0x0F4E0078, 0x0F500863, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078, 
+        0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078, 
+        0x0FA408CA, 0x0FA70078, 0x0FA80855, 0x0FAC0078, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC, 
+        0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9, 
+        0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD90855, 0x0FDC08CA, 0x0FDD08D2, 0x0FDE08D3, 
+        0x0FDF08D4, 0x0FE01037, 0x0FE10855, 0x0FE408D5, 0x0FE608D3, 0x0FE70837, 0x0FE808C9, 0x0FE90855, 
+        0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0078, 0x0FEF0837, 0x0FF008C9, 0x0FF10855, 
+        0x0FF408CA, 0x0FF508D7, 0x0FF608D8, 0x0FF70837, 0x0FF80078, 0x0FF90855, 0x0FFC08D9, 0x0FFD08DA, 
+        0x0FFE08D3, 0x0FFF1037, 0x10000805, 0x10011005, 0x10060057, 0x100700C2, 0x10080099, 0x100B0006, 
+        0x100C00DB, 0x100D00B4, 0x100E00DB, 0x100F00B4, 0x10100006, 0x10121006, 0x101400DC, 0x101500DD, 
+        0x101600DE, 0x101700DF, 0x10180007, 0x101A1007, 0x101B1006, 0x101C0006, 0x101D00E0, 0x101E1006, 
+        0x10200038, 0x10210006, 0x102200E1, 0x1023000A, 0x10241006, 0x10250006, 0x10290019, 0x102A0038, 
+        0x102B0006, 0x10300057, 0x10320078, 0x10350057, 0x103878E2, 0x10390078, 0x103A78E3, 0x103B78E4, 
+        0x103C78E5, 0x103D780B, 0x103E7819, 0x103F780A, 0x104070E2, 0x1041705A, 0x104270E3, 0x104370E4, 
+        0x104470E5, 0x1045700B, 0x10467019, 0x1047700A, 0x10487081, 0x104B0078, 0x10500008, 0x10541008, 
+        0x10550008, 0x105B0078, 0x10680083, 0x106F0095, 0x10730083, 0x10760078, 0x10801054, 0x10812877, 
+        0x10820054, 0x10831054, 0x10840054, 0x10852855, 0x10862877, 0x10872855, 0x10882877, 0x108A0054, 
+        0x108B1054, 0x108C0054, 0x108D2877, 0x108F0054, 0x10907854, 0x10922877, 0x109308E6, 0x10942877, 
+        0x109508E7, 0x10962877, 0x10970058, 0x10982877, 0x10990054, 0x109A2855, 0x109B1071, 0x109D0054, 
+        0x109E2855, 0x109F2877, 0x10A028E8, 0x10A10019, 0x10A32855, 0x10A50054, 0x10A70078, 0x10AA305F, 
+        0x10B010E9, 0x10B110EA, 0x10B210EB, 0x10B310EC, 0x10B410ED, 0x10B510EE, 0x10B610EF, 0x10B710F0, 
+        0x10B810F1, 0x10B910F2, 0x10BA10F3, 0x10BB10F4, 0x10BC10F5, 0x10BD10F6, 0x10BE10F7, 0x10BF10F8, 
+        0x10C000F9, 0x10C100FA, 0x10C20078, 0x10C80019, 0x10CB0054, 0x10CD0819, 0x10CE0054, 0x10D00019, 
+        0x10D10054, 0x10D30019, 0x10D40054, 0x10D70819, 0x10D80054, 0x10E70819, 0x10E80054, 0x10E90019, 
+        0x10EB0054, 0x10FA0019, 0x110100E8, 0x110208E8, 0x11030019, 0x110400FB, 0x110608FC, 0x11070019, 
+        0x1109000B, 0x110A0019, 0x110B00E8, 0x110C0019, 0x110D00E8, 0x110F0019, 0x111000E8, 0x111208E8, 
+        0x11140019, 0x111610E8, 0x111700E8, 0x111810E8, 0x111900E8, 0x111A0019, 0x111E00FD, 0x111F00E8, 
+        0x112208E8, 0x112300E8, 0x11270019, 0x112900FD, 0x112B0019, 0x113008E8, 0x113200FD, 0x11360019, 
+        0x113708FD, 0x113900FD, 0x113A08FD, 0x113B00FD, 0x113C08FD, 0x113D00FD, 0x114008FD, 0x114100FD, 
+        0x114208FD, 0x114300FD, 0x114408FD, 0x114500FD, 0x114600E8, 0x11470019, 0x114800FE, 0x114A0019, 
+        0x114C00FF, 0x114D0019, 0x115100FD, 0x11520019, 0x11530100, 0x11540101, 0x115500E8, 0x115608E8, 
+        0x115800FD, 0x115C00E8, 0x115D0019, 0x115F00E8, 0x11600019, 0x116500FE, 0x11670019, 0x116800FD, 
+        0x11690019, 0x116B00FD, 0x117008FD, 0x117200FD, 0x117508FD, 0x11770019, 0x117800FD, 0x11790102, 
+        0x117B0103, 0x117C00E8, 0x117D0104, 0x117F0105, 0x11800054, 0x118400FD, 0x11860054, 0x119000E8, 
+        0x11910054, 0x1195080A, 0x11960054, 0x119B0094, 0x11BE0019, 0x11BF0054, 0x11CE0019, 0x11DA00B4, 
+        0x11DB0006, 0x11DC0054, 0x11EE0078, 0x12000054, 0x12140078, 0x12200054, 0x12260078, 0x12301906, 
+        0x12311907, 0x12321908, 0x12331909, 0x1234190A, 0x1235190B, 0x1236190C, 0x1237190D, 0x1238190E, 
+        0x1239190F, 0x123A1106, 0x123B1107, 0x123C1108, 0x123D1109, 0x123E110A, 0x123F110B, 0x1240110C, 
+        0x1241110D, 0x1242110E, 0x1243110F, 0x1244105D, 0x1245105B, 0x12461110, 0x12471111, 0x12481112, 
+        0x12491113, 0x124A1114, 0x124B1115, 0x124C1116, 0x124D1117, 0x124E1094, 0x125B1918, 0x12681919, 
+        0x127518C3, 0x1276011A, 0x1277011B, 0x1278011C, 0x1279011D, 0x127A011E, 0x127B00C4, 0x127C00C5, 
+        0x127D00C6, 0x127E00C7, 0x127F011F, 0x12800054, 0x12FC0019, 0x13000054, 0x134F0078, 0x13500054, 
+        0x13560094, 0x13570054, 0x13590078, 0x13810054, 0x13850078, 0x13860054, 0x13940078, 0x13950054, 
+        0x13A60078, 0x13A80054, 0x13AA0078, 0x13AB0054, 0x13B00078, 0x13B10054, 0x13B40009, 0x13BB0106, 
+        0x13BC0107, 0x13BD0108, 0x13BE0109, 0x13BF010A, 0x13C00106, 0x13C10107, 0x13C20108, 0x13C30109, 
+        0x13C4010A, 0x13C50106, 0x13C60107, 0x13C70108, 0x13C80109, 0x13C9010A, 0x13CA0054, 0x13CB0078, 
+        0x13CC0054, 0x13D80078, 0x13D90054, 0x13E000E8, 0x13E10019, 0x13E200FE, 0x13E3000A, 0x13E40078, 
+        0x13E80019, 0x13EA00E8, 0x13EB00FE, 0x13EC0019, 0x13EE00E8, 0x13EF00FE, 0x13F00019, 0x13F100FD, 
+        0x13F30009, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C2000A, 0x14C70120, 0x14C80121, 
+        0x14C9000A, 0x14CD0019, 0x14CE00E8, 0x14D80019, 0x14DC0122, 0x14DD0019, 0x14E000FD, 0x14E100E8, 
+        0x14E200FD, 0x14E30019, 0x14E700E8, 0x14E800FE, 0x14EA00FD, 0x14EB0019, 0x14EC0009, 0x14EE00E8, 
+        0x14EF0019, 0x14F200E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA00E8, 0x14FC00FD, 0x14FD0019, 
+        0x14FE0009, 0x14FF0019, 0x150500E8, 0x150610E8, 0x150700E8, 0x15110019, 0x151200E8, 0x15140019, 
+        0x151600FE, 0x15180019, 0x151A00FD, 0x151B0019, 0x151E00FD, 0x151F00E8, 0x15200019, 0x152C00E8, 
+        0x152D0019, 0x153200FD, 0x15330019, 0x153500E8, 0x15370019, 0x153800E8, 0x15390019, 0x153A10E8, 
+        0x153B1019, 0x153C0019, 0x153D00FE, 0x153E00E8, 0x153F00FE, 0x154300E8, 0x154600FE, 0x154700E8, 
+        0x154900FE, 0x154F00E8, 0x155100FE, 0x15520019, 0x155300FD, 0x15570019, 0x155800FE, 0x155900E8, 
+        0x155A00FE, 0x155B00E8, 0x155E00FE, 0x156400E8, 0x156700FE, 0x156C0019, 0x156E08E8, 0x156F0123, 
+        0x15700019, 0x157100E8, 0x15720124, 0x157300E8, 0x15740019, 0x157600FD, 0x157700E8, 0x15780019, 
+        0x157C00FE, 0x157E0019, 0x15800054, 0x158A0078, 0x16000096, 0x16180098, 0x16300078, 0x16400063, 
+        0x16720055, 0x16730054, 0x16760078, 0x167D0006, 0x16800125, 0x16930078, 0x16980071, 0x16B30078, 
+        0x16C00071, 0x16CC0078, 0x16D00071, 0x16F00078, 0x17000006, 0x17010126, 0x17030006, 0x170500E0, 
+        0x17060126, 0x17070006, 0x170C0078, 0x170E0126, 0x170F0078, 0x17400054, 0x174D0078, 0x174E0054, 
+        0x177A0078, 0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18008805, 0x18010006, 0x18020054, 
+        0x18030071, 0x18040009, 0x18090054, 0x180A0009, 0x180E0099, 0x180F00BF, 0x18100054, 0x18110127, 
+        0x18120128, 0x18130129, 0x1814012A, 0x18150083, 0x18180099, 0x18190081, 0x181B1054, 0x181C112B, 
+        0x181D112C, 0x181E0071, 0x181F0054, 0x18200078, 0x18210071, 0x18260871, 0x18320071, 0x18380871, 
+        0x18390071, 0x183A0871, 0x183C0071, 0x183D0871, 0x183F0071, 0x184A0871, 0x184B0071, 0x184C0078, 
+        0x184D0083, 0x184E1037, 0x184F0881, 0x18500099, 0x18510071, 0x18560871, 0x18620071, 0x18680871, 
+        0x18690071, 0x186A0871, 0x186C0071, 0x186D0871, 0x186F0071, 0x187A0871, 0x187B0071, 0x187C0871, 
+        0x187E0081, 0x187F0881, 0x18800078, 0x18830071, 0x18970078, 0x18991071, 0x18C80094, 0x18C978AD, 
+        0x18CA78AE, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 0x18F80071, 0x19001094, 
+        0x190F1054, 0x191010AD, 0x191110AE, 0x1912112D, 0x1913112E, 0x1914112F, 0x19151094, 0x19220078, 
+        0x19286854, 0x19291930, 0x192A1931, 0x192B1932, 0x192C1933, 0x192D1934, 0x192E1935, 0x192F1936, 
+        0x19301894, 0x193E1854, 0x194018AD, 0x194118AE, 0x1942192D, 0x1943192E, 0x1944192F, 0x19451894, 
+        0x19591937, 0x195A1938, 0x195B1939, 0x195C193A, 0x195D193B, 0x195E193C, 0x195F193D, 0x19601094, 
+        0x19666854, 0x19681894, 0x19806894, 0x19AC1094, 0x19B96894, 0x19BC6854, 0x19BE6894, 0x19EF6854, 
+        0x19F01094, 0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x52470078, 
+        0x52480054, 0x52640078, 0x53800037, 0x538C0078, 0x54000071, 0x540100C8, 0x54020071, 0x54030083, 
+        0x54040071, 0x541200A7, 0x54130083, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E, 
+        0x7000013F, 0x7C800871, 0x7D070071, 0x7D080871, 0x7D0A0071, 0x7D0B0871, 0x7D120071, 0x7D130871, 
+        0x7D140071, 0x7D150871, 0x7D170078, 0x7D180871, 0x7D360078, 0x7D380871, 0x7D6D0078, 0x7D801055, 
+        0x7D840078, 0x7D8A1055, 0x7D8C0078, 0x7D8F0083, 0x7D90289B, 0x7D95089B, 0x7DA10078, 0x7DA2089B, 
+        0x7DA8409E, 0x7DAA389E, 0x7DAB409E, 0x7DAC389E, 0x7DAD409E, 0x7DAE389E, 0x7DAF409E, 0x7DB0389E, 
+        0x7DB1409E, 0x7DB2389E, 0x7DB3409E, 0x7DB4389E, 0x7DB5409E, 0x7DB6389E, 0x7DB7409E, 0x7DB8389E, 
+        0x7DB9409E, 0x7DBA389E, 0x7DBB409E, 0x7DBC389E, 0x7DBD409E, 0x7DBE389E, 0x7DBF409E, 0x7DC0389E, 
+        0x7DC1409E, 0x7DC8389E, 0x7DC9409E, 0x7DCA389E, 0x7DCB409E, 0x7DCC389E, 0x7DCD409E, 0x7DCE389E, 
+        0x7DCF409E, 0x7DD1389E, 0x7DD2409E, 0x7DD4389E, 0x7DD5409E, 0x7DD6389E, 0x7DD7409E, 0x7DD90078, 
+        0x7DEA209E, 0x7DEB489E, 0x7DEC209E, 0x7DEF409E, 0x7DF3389E, 0x7DF5409E, 0x7DFC389E, 0x7DFD209E, 
+        0x7DFE409E, 0x7DFF389E, 0x7E00409E, 0x7E32209E, 0x7E4C389E, 0x7E70489E, 0x7E7B409E, 0x7E89209E, 
+        0x7E97389E, 0x7E9A489E, 0x7E9E209E, 0x7E9F00B4, 0x7EA00078, 0x7EA8389E, 0x7EAC209E, 0x7EAE389E, 
+        0x7EAF209E, 0x7EB0389E, 0x7EB1209E, 0x7EB4389E, 0x7EB5209E, 0x7EB8389E, 0x7EBA209E, 0x7EC3389E, 
+        0x7EC80078, 0x7EC9389E, 0x7ECB209E, 0x7ECC389E, 0x7ECD209E, 0x7EDA389E, 0x7EDB209E, 0x7EDC389E, 
+        0x7EDE209E, 0x7EE2389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 0x7EFE4140, 0x7EFF0078, 0x7F000083, 
+        0x7F088006, 0x7F0C80BF, 0x7F0D0078, 0x7F100083, 0x7F120078, 0x7F188006, 0x7F198099, 0x7F1A8038, 
+        0x7F1B80BF, 0x7F230006, 0x7F2480BF, 0x7F251006, 0x7F271038, 0x7F28600C, 0x7F2A6006, 0x7F2C6099, 
+        0x7F2D60BF, 0x7F306006, 0x7F31600B, 0x7F326019, 0x7F346006, 0x7F356007, 0x7F360078, 0x7F38409E, 
+        0x7F41209E, 0x7F46489E, 0x7F47209E, 0x7F49489E, 0x7F4A209E, 0x7F4C489E, 0x7F4D209E, 0x7F4E489E, 
+        0x7F4F209E, 0x7F50489E, 0x7F51209E, 0x7F52489E, 0x7F53209E, 0x7F54489E, 0x7F55209E, 0x7F5A489E, 
+        0x7F5B209E, 0x7F5C489E, 0x7F5D209E, 0x7F5E489E, 0x7F5F209E, 0x7F60489E, 0x7F61209E, 0x7F62489E, 
+        0x7F63209E, 0x7F64489E, 0x7F65209E, 0x7F66489E, 0x7F67209E, 0x7F68489E, 0x7F69209E, 0x7F6A489E, 
+        0x7F6B209E, 0x7F6C489E, 0x7F6D209E, 0x7F6E489E, 0x7F6F209E, 0x7F70489E, 0x7F71209E, 0x7F72489E, 
+        0x7F73209E, 0x7F74489E, 0x7F75209E, 0x7F76489E, 0x7F77209E, 0x7F7A489E, 0x7F7B209E, 0x7F7F0078, 
+        0x7F818806, 0x7F828808, 0x7F838806, 0x7F848809, 0x7F858806, 0x7F86880C, 0x7F88880E, 0x7F898810, 
+        0x7F8A8812, 0x7F8B8814, 0x7F8C8816, 0x7F8D880C, 0x7F8E8818, 0x7F8F881A, 0x7F908806, 0x7F918860, 
+        0x7F9E8806, 0x7F9F8837, 0x7FA18861, 0x7FAE8819, 0x7FB0880A, 0x7FB15009, 0x7FB25006, 0x7FB35071, 
+        0x7FB85081, 0x7FB95071, 0x7FCF5081, 0x7FD05071, 0x7FE00078, 0x7FE15071, 0x7FE40078, 0x7FE55071, 
+        0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEF0078, 0x7FF08808, 0x7FF18819, 0x7FF28854, 
+        0x7FF38808, 0x7FF45054, 0x7FF55019, 0x7FF75054, 0x7FF80078, 0x7FFD0141, 0x7FFE0054, 0x7FFF0078, 
+        0x80000071, 0x80060078, 0x80070071, 0x801F0078, 0x80200071, 0x80270078, 0x80280071, 0x802F0078, 
+        0x80400071, 0x807E0078, 0x80800097, 0x80810094, 0x80820078, 0x808400B6, 0x808500B7, 0x808600B8, 
+        0x808700B9, 0x808800B0, 0x808900BA, 0x808A00BB, 0x808B00BC, 0x808C00BD, 0x808D0142, 0x808E0143, 
+        0x808F0144, 0x80900145, 0x809100B1, 0x80920146, 0x80930147, 0x80940148, 0x80950149, 0x8096014A, 
+        0x8097014B, 0x8098014C, 0x8099014D, 0x809A0078, 0x809C0094, 0x80A0014E, 0x80A1014F, 0x80A20150, 
+        0x80A30151, 0x80A40152, 0x80A50150, 0x80A60153, 0x80A70151, 0x80A80154, 0x80A90155, 0x80AA0156, 
+        0x80AB0157, 0x80AC014F, 0x80AE0158, 0x80B00154, 0x80B30150, 0x80B50155, 0x80B60153, 0x80B90151, 
+        0x80BA0150, 0x80BB005F, 0x80BD0054, 0x80C500C3, 0x80C60078, 0x81800071, 0x819000AD, 0x819100B0, 
+        0x81920078, 0x81980071, 0x81A50159, 0x81A60078, 0x81C00071, 0x81CF0078, 0x81D00071, 0x81E20078, 
+        0x81E40071, 0x81E80094, 0x81E90158, 0x81EA015A, 0x81EB0078, 0x8200015B, 0x8214015C, 0x82280071, 
+        0x824F0078, 0x825000A8, 0x825100A9, 0x825200AA, 0x825300AB, 0x825400AC, 0x82550078, 0x8400009B, 
+        0x84030078, 0x8404009B, 0x841B0078, 0x841C009B, 0x841D0078, 0x841E009B, 0x841F0078, 0x8500009B, 
+        0x85010083, 0x85020078, 0x85030083, 0x85040078, 0x85060083, 0x8508009B, 0x850A0078, 0x850B009B, 
+        0x850C0078, 0x850D009B, 0x851A0078, 0x851C0083, 0x851E0078, 0x8520015D, 0x8521015E, 0x8522015F, 
+        0x85230160, 0x85240078, 0x8528009A, 0x852D0078, 0xE8000094, 0xE87B0078, 0xE8800094, 0xE8940078, 
+        0xE8950094, 0xE8AF0894, 0xE8B300A7, 0xE8B40083, 0xE8B50094, 0xE8B700A7, 0xE8BA0057, 0xE8BE0083, 
+        0xE8C20094, 0xE8C30083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 0xE8DE0894, 0xE8E10094, 0xE8EF0078, 
+        0xE9000054, 0xE9210083, 0xE9230078, 0xE9800054, 0xE9AC0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 
+        0xEA272855, 0xEA342877, 0xEA412855, 0xEA4E2877, 0xEA500078, 0xEA512877, 0xEA520078, 0xEA532877, 
+        0xEA540078, 0xEA552877, 0xEA5B2855, 0xEA5D0078, 0xEA5F2855, 0xEA620078, 0xEA632855, 0xEA682877, 
+        0xEA752855, 0xEA822877, 0xEA830078, 0xEA842877, 0xEA860078, 0xEA872877, 0xEA8F2855, 0xEA9C2877, 
+        0xEA9D0078, 0xEA9E2877, 0xEAA40078, 0xEAA52877, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 
+        0xEADD2855, 0xEAEA2877, 0xEAF72855, 0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 
+        0xEB452855, 0xEB530078, 0xEB542877, 0xEB612855, 0xEB712877, 0xEB7E2855, 0xEB8E2877, 0xEB9B2855, 
+        0xEBAB2877, 0xEBB82855, 0xEBC82877, 0xEBD52855, 0xEBE50078, 0xEBE7280E, 0xEBE82810, 0xEBE92812, 
+        0xEBEA2814, 0xEBEB2816, 0xEBEC280E, 0xEBED2810, 0xEBEE2812, 0xEBEF2814, 0xEBF02816, 0xEBF1280E, 
+        0xEBF22810, 0xEBF32812, 0xEBF42814, 0xEBF52816, 0xEBF6280E, 0xEBF72810, 0xEBF82812, 0xEBF92814, 
+        0xEBFA2816, 0xEBFB280E, 0xEBFC2810, 0xEBFD2812, 0xEBFE2814, 0xEBFF2816, 0xEC000078
+    };
+
+    static const uint32_t a1[] = {
+        0x00000071, 0x536C0078, 0x7C000871, 0x7D0F0078
+    };
+
+    static const uint32_t a7[] = {
+        0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
+    };
+
+    static const uint32_t a8[] = {
+        0x0000013F, 0x7FFF0078
+    };
+
+    static const uint32_t a16[] = {
+        0x00800865, 0x00880065, 0x00890865, 0x00930065, 0x00940865, 0x00980161, 0x00991065, 0x009A0865, 
+        0x009C0863, 0x009F1063, 0x00A00063, 0x00A10863, 0x00A41055, 0x00A50065, 0x00A60865, 0x00A90065, 
+        0x00AA0865, 0x00B30065, 0x00B40865, 0x00BC0863, 0x00BF1162, 0x00C00163, 0x00C10065, 0x00C30063, 
+        0x00C40068, 0x00C50063, 0x00C60055, 0x00C70164, 0x00C80063, 0x00C90068, 0x00CA0165, 0x00CB0166, 
+        0x00CC0065, 0x00CD0055, 0x00CE0167, 0x00CF0168, 0x00D00865, 0x00D10065, 0x00D30063, 0x00D4006F, 
+        0x00D50055, 0x00D60065, 0x00D70863, 0x00D80070, 0x00D90063, 0x00DB0169, 0x00DC0065, 0x00DD0071, 
+        0x00DE0065, 0x00DF016A, 0x00E00071, 0x00E21074, 0x00E31072, 0x00E41073, 0x00E51074, 0x00E60863, 
+        0x00EE016B, 0x00EF0865, 0x00F20065, 0x00F30865, 0x00F81072, 0x00F91073, 0x00FA0865, 0x00FB016C, 
+        0x00FC0865, 0x010E0065, 0x010F0865, 0x01100055, 0x01110065, 0x01130865, 0x011A0055, 0x011D0063, 
+        0x011E016D, 0x011F0055, 0x0120016E, 0x01210078, 0x01280055, 0x0129016F, 0x012A0055, 0x012B007A, 
+        0x012C0170, 0x012D0171, 0x012E0055, 0x01310172, 0x01320055, 0x01340173, 0x01350055, 0x01370173, 
+        0x01380055, 0x013A0174, 0x013B0055, 0x0141007D, 0x01420055, 0x0145007E, 0x01460055, 0x01587881, 
+        0x015C0082, 0x015D0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 
+        0x01707881, 0x01720037, 0x01800083, 0x01A00883, 0x01A20175, 0x01A30083, 0x01B80078, 0x01BA0037, 
+        0x01BB0078, 0x01C20837, 0x01C30806, 0x01C40885, 0x01C50078, 0x01C70887, 0x01C80060, 0x01D50860, 
+        0x01D60889, 0x01D80061, 0x01E50861, 0x01E6088C, 0x01E70078, 0x01E81176, 0x01E90877, 0x01EA1177, 
+        0x01EB0055, 0x01EC0065, 0x01F81093, 0x01F90055, 0x01FA1178, 0x01FB0063, 0x01FC10D8, 0x01FD0065, 
+        0x01FE0077, 0x02000892, 0x02020092, 0x02030892, 0x02040092, 0x02060892, 0x02070092, 0x02080060, 
+        0x020C0860, 0x020D0060, 0x02180061, 0x021C0861, 0x021D0061, 0x02280893, 0x022A0093, 0x022B0893, 
+        0x022C0093, 0x022E0893, 0x022F0093, 0x02300065, 0x023B0865, 0x023C0065, 0x02410083, 0x02430078, 
+        0x02440095, 0x02450065, 0x02600863, 0x02610063, 0x02670078, 0x02680865, 0x026A0065, 0x026B0865, 
+        0x026C0065, 0x026D0865, 0x02700065, 0x02710865, 0x02740065, 0x02750865, 0x027B0065, 0x027C0865, 
+        0x027D0078, 0x02800065, 0x02880078, 0x02980096, 0x02AB0078, 0x02AC0081, 0x02AD0097, 0x02B00098, 
+        0x02C31055, 0x02C40097, 0x02C50078, 0x02C80083, 0x02E1009A, 0x02E20083, 0x02E40078, 0x02E8009B, 
+        0x02F50078, 0x02F8009B, 0x02F9009A, 0x02FA0078, 0x0300009C, 0x03020078, 0x03050140, 0x0306009D, 
+        0x03070054, 0x03080083, 0x030B0078, 0x030D009D, 0x030E0078, 0x030F009D, 0x0310009E, 0x0311089E, 
+        0x0313009E, 0x031D0078, 0x0320009E, 0x03250083, 0x032F0078, 0x03300179, 0x0331017A, 0x0332017B, 
+        0x0333017C, 0x0334017D, 0x033500A5, 0x0336009D, 0x0337009E, 0x033A109E, 0x033C009E, 0x0369089E, 
+        0x036A009E, 0x036B0083, 0x036E009C, 0x036F0083, 0x0372009F, 0x03730083, 0x03740054, 0x03750083, 
+        0x0377009E, 0x0378000F, 0x03790011, 0x037A0013, 0x037B0015, 0x037C0017, 0x037D009E, 0x037E00A6, 
+        0x037F009E, 0x0380009D, 0x03870057, 0x03880083, 0x0389009E, 0x03980083, 0x03A50078, 0x03A6009E, 
+        0x03B70078, 0x03C0009E, 0x03D30083, 0x03D8009E, 0x03D90078, 0x04800083, 0x048100A7, 0x04820071, 
+        0x04940871, 0x04950071, 0x04980871, 0x04990071, 0x049D0078, 0x049E0071, 0x049F00A7, 0x04A00083, 
+        0x04A400A7, 0x04A60083, 0x04A70078, 0x04A80083, 0x04AA0078, 0x04AC0871, 0x04B00071, 0x04B10083, 
+        0x04B20097, 0x04B3017E, 0x04B4017F, 0x04B50180, 0x04B60181, 0x04B70182, 0x04B80078, 0x04BE0071, 
+        0x04BF0078, 0x04C00083, 0x04C100A7, 0x04C20071, 0x04C60078, 0x04C70071, 0x04C80078, 0x04C90071, 
+        0x04D40078, 0x04D50071, 0x04D80078, 0x04DB0071, 0x04DD0078, 0x04DE0071, 0x04DF00A7, 0x04E00083, 
+        0x04E20078, 0x04E300A7, 0x04E40078, 0x04E508A7, 0x04E60083, 0x04E70078, 0x04EB00A7, 0x04EC0078, 
+        0x04EE0871, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F3017E, 0x04F4017F, 0x04F50180, 0x04F60181, 
+        0x04F70182, 0x04F80071, 0x04F90008, 0x04FA00B6, 0x04FB00B7, 0x04FC0183, 0x04FD0078, 0x05000083, 
+        0x050100A7, 0x05020071, 0x05050078, 0x05070071, 0x05080078, 0x05090071, 0x05140078, 0x05150071, 
+        0x05180078, 0x05190871, 0x051A0071, 0x051B0078, 0x051C0071, 0x051D0078, 0x051F00A7, 0x05200083, 
+        0x05210078, 0x05230083, 0x05240078, 0x05250083, 0x05270078, 0x052C0871, 0x052E0078, 0x0533017E, 
+        0x0534017F, 0x05350180, 0x05360181, 0x05370182, 0x05380083, 0x05390071, 0x053A0078, 0x05400083, 
+        0x054100A7, 0x05420071, 0x05540078, 0x05550071, 0x05580078, 0x05590071, 0x055D0078, 0x055E0071, 
+        0x055F00A7, 0x05600083, 0x056400A7, 0x05660083, 0x05670078, 0x05700071, 0x05710083, 0x05720078, 
+        0x0573017E, 0x0574017F, 0x05750180, 0x05760181, 0x05770182, 0x05780008, 0x05790078, 0x05800083, 
+        0x058100A7, 0x05820071, 0x05860078, 0x05870071, 0x05880078, 0x05890071, 0x05940078, 0x05950071, 
+        0x05980078, 0x05990071, 0x059D0078, 0x059E0071, 0x059F0083, 0x05A20078, 0x05A300A7, 0x05A40078, 
+        0x05A508A7, 0x05A60083, 0x05A70078, 0x05AB00A7, 0x05AC0078, 0x05AE0871, 0x05AF0071, 0x05B10078, 
+        0x05B3017E, 0x05B4017F, 0x05B50180, 0x05B60181, 0x05B70182, 0x05B80071, 0x05B90078, 0x05C10071, 
+        0x05C50078, 0x05C70071, 0x05C80078, 0x05C90071, 0x05CB0078, 0x05CC0071, 0x05CD0078, 0x05CF0071, 
+        0x05D00078, 0x05D10071, 0x05D20078, 0x05D40071, 0x05D50078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 
+        0x05E10078, 0x05E300A7, 0x05E40078, 0x05E508A7, 0x05E60083, 0x05E70078, 0x05EB00A7, 0x05EC0078, 
+        0x05F3017E, 0x05F4017F, 0x05F50180, 0x05F60181, 0x05F70182, 0x05F80184, 0x05F90054, 0x05FC0008, 
+        0x05FD0078, 0x060000A7, 0x06020071, 0x06060078, 0x06070071, 0x06080078, 0x06090071, 0x06140078, 
+        0x06150071, 0x061D0078, 0x061F0083, 0x062000A7, 0x06220078, 0x06230083, 0x06240078, 0x06250083, 
+        0x06270078, 0x062A0083, 0x062B0078, 0x06300071, 0x06310078, 0x0633017E, 0x0634017F, 0x06350180, 
+        0x06360181, 0x06370182, 0x06380078, 0x064100A7, 0x06420071, 0x06460078, 0x06470071, 0x06480078, 
+        0x06490071, 0x06540078, 0x06550071, 0x065D0078, 0x065E0071, 0x065F00B2, 0x066000A7, 0x06620078, 
+        0x066308A7, 0x06640078, 0x066508A7, 0x06660083, 0x06670078, 0x066A00A7, 0x066B0078, 0x06700071, 
+        0x06710078, 0x0673017E, 0x0674017F, 0x06750180, 0x06760181, 0x06770182, 0x06780078, 0x068100A7, 
+        0x06820071, 0x06860078, 0x06870071, 0x06880078, 0x06890071, 0x06940078, 0x06950071, 0x069D0078, 
+        0x069F00A7, 0x06A00083, 0x06A20078, 0x06A300A7, 0x06A40078, 0x06A508A7, 0x06A60083, 0x06A70078, 
+        0x06AB00A7, 0x06AC0078, 0x06B00071, 0x06B10078, 0x06B3017E, 0x06B4017F, 0x06B50180, 0x06B60181, 
+        0x06B70182, 0x06B80078, 0x06C100A7, 0x06C20071, 0x06CB0078, 0x06CD0071, 0x06DF0078, 0x06E00071, 
+        0x06E30078, 0x06E700A7, 0x06E90083, 0x06EA0078, 0x06EC00A7, 0x06EE08A7, 0x06EF00A7, 0x06F00078, 
+        0x06F900A7, 0x06FA0078, 0x07000071, 0x07180083, 0x07191071, 0x071A0083, 0x071D0078, 0x071F0008, 
+        0x07200071, 0x07230083, 0x07270097, 0x0728017E, 0x0729017F, 0x072A0180, 0x072B0181, 0x072C0182, 
+        0x072D0097, 0x072E0078, 0x07400071, 0x07410078, 0x07430071, 0x07440078, 0x07460071, 0x07470078, 
+        0x074A0071, 0x07540078, 0x07550071, 0x07580083, 0x07591071, 0x075A0083, 0x075E0071, 0x075F0078, 
+        0x07600071, 0x07620078, 0x07640083, 0x07670078, 0x0768017E, 0x0769017F, 0x076A0180, 0x076B0181, 
+        0x076C0182, 0x076D0078, 0x076E1071, 0x076F0078, 0x07800094, 0x07820097, 0x07890094, 0x078C0083, 
+        0x078D0094, 0x0790017E, 0x0791017F, 0x07920180, 0x07930181, 0x07940182, 0x079500B3, 0x079A0083, 
+        0x079D00BF, 0x079F00A7, 0x07A00071, 0x07A10871, 0x07A20071, 0x07A60871, 0x07A70071, 0x07AB0871, 
+        0x07AC0071, 0x07B40871, 0x07B50078, 0x07B80083, 0x07B90883, 0x07BB1083, 0x07BD0083, 0x07BF00A7, 
+        0x07C00883, 0x07C10083, 0x07C20097, 0x07C30083, 0x07C40071, 0x07C60078, 0x07C80083, 0x07C90883, 
+        0x07CA0083, 0x07CE0883, 0x07CF0083, 0x07D30883, 0x07D40083, 0x07DC0883, 0x07DD0083, 0x07DE0078, 
+        0x07DF0094, 0x07E60078, 0x07E70094, 0x07E80097, 0x07E90078, 0x08000071, 0x08150078, 0x08160083, 
+        0x081800A7, 0x08190078, 0x081B0083, 0x081D0078, 0x0820017E, 0x0821017F, 0x08220180, 0x08230181, 
+        0x08240182, 0x08250097, 0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 
+        0x08680071, 0x087D0097, 0x087E0078, 0x08800071, 0x08AD0078, 0x08AF0071, 0x08D10078, 0x08D40071, 
+        0x08FD0078, 0x09000071, 0x09240078, 0x09250071, 0x09270078, 0x09280071, 0x092B0078, 0x092D0071, 
+        0x092F0078, 0x09300071, 0x09440078, 0x09450071, 0x09470078, 0x09480071, 0x09580078, 0x09590071, 
+        0x095B0078, 0x095C0071, 0x095F0078, 0x09610071, 0x09630078, 0x09640071, 0x096B0078, 0x096C0071, 
+        0x09880078, 0x09890071, 0x098B0078, 0x098C0071, 0x09AD0078, 0x09AF0083, 0x09B00097, 0x09B400AD, 
+        0x09B500AE, 0x09B6012D, 0x09B7012E, 0x09B8012F, 0x09B90185, 0x09BA0186, 0x09BB0187, 0x09BC0188, 
+        0x09BD0184, 0x09BE0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FA0078, 0x0A000071, 
+        0x0B360097, 0x0B370071, 0x0B3B0078, 0x0B400071, 0x0B4D00B4, 0x0B4E0078, 0x0B500071, 0x0B750097, 
+        0x0B770189, 0x0B780078, 0x0B800071, 0x0B860078, 0x0B870071, 0x0B890083, 0x0B8A0078, 0x0B900071, 
+        0x0B990083, 0x0B9A0097, 0x0B9B0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB60078, 
+        0x0BB70071, 0x0BB80078, 0x0BB90083, 0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB0083, 0x0BDF00A7, 
+        0x0BE40083, 0x0BEA0097, 0x0BEB0081, 0x0BEC0097, 0x0BED0008, 0x0BEE0083, 0x0BEF0078, 0x0BF0017E, 
+        0x0BF1017F, 0x0BF20180, 0x0BF30181, 0x0BF40182, 0x0BF50078, 0x0BF80106, 0x0BF90107, 0x0BFA0108, 
+        0x0BFB0109, 0x0BFC010A, 0x0BFD0078, 0x0C000006, 0x0C050083, 0x0C070078, 0x0C08017E, 0x0C09017F, 
+        0x0C0A0180, 0x0C0B0181, 0x0C0C0182, 0x0C0D0078, 0x0C100071, 0x0C210081, 0x0C220071, 0x0C3C0078, 
+        0x0C400071, 0x0C540083, 0x0C550078, 0x0C800071, 0x0C8E0078, 0x0C900083, 0x0C9100A7, 0x0C930083, 
+        0x0C9400C8, 0x0C960078, 0x0C9800A7, 0x0C9C0083, 0x0C9E0078, 0x0CA20006, 0x0CA3017E, 0x0CA4017F, 
+        0x0CA50180, 0x0CA60181, 0x0CA70182, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBA0078, 0x0CC00071, 
+        0x0CD50078, 0x0CD800A7, 0x0CE00071, 0x0CE400A7, 0x0CE50078, 0x0CE8017E, 0x0CE9017F, 0x0CEA0180, 
+        0x0CEB0181, 0x0CEC0182, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0B0083, 0x0D0C00A7, 
+        0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0E970081, 0x0E987881, 0x0E9D0081, 
+        0x0E9E7881, 0x0EB17055, 0x0EB50055, 0x0ECD7881, 0x0EE00083, 0x0EE20078, 0x0F000865, 0x0F4B0855, 
+        0x0F4D098A, 0x0F4E0078, 0x0F500865, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078, 
+        0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078, 
+        0x0FA408CA, 0x0FA70078, 0x0FA808C9, 0x0FAC08CA, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC, 
+        0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9, 
+        0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD9098B, 0x0FDA0078, 0x0FDB0855, 0x0FDC08CA, 
+        0x0FDD08D2, 0x0FDE1037, 0x0FE00837, 0x0FE1098B, 0x0FE20078, 0x0FE30855, 0x0FE408D5, 0x0FE60837, 
+        0x0FE808C9, 0x0FE90855, 0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0837, 0x0FF008C9, 
+        0x0FF10855, 0x0FF20890, 0x0FF30855, 0x0FF408CA, 0x0FF508D7, 0x0FF60837, 0x0FF80078, 0x0FF9098B, 
+        0x0FFA0078, 0x0FFB0855, 0x0FFC08D9, 0x0FFD08DA, 0x0FFE0837, 0x0FFF0078, 0x10000805, 0x10011005, 
+        0x10035805, 0x10041005, 0x10050057, 0x1007018C, 0x10085899, 0x10090099, 0x100B1006, 0x100C018D, 
+        0x100D00DB, 0x100E018D, 0x100F00DB, 0x10100006, 0x10121006, 0x10130006, 0x1014018E, 0x1015018F, 
+        0x10160190, 0x10175853, 0x10180007, 0x10191007, 0x101A0006, 0x101B1006, 0x101C0126, 0x101D0006, 
+        0x101F0038, 0x10200006, 0x10220009, 0x10231006, 0x10250006, 0x102B1006, 0x102C0006, 0x102F1005, 
+        0x10300057, 0x10320078, 0x10350057, 0x10387855, 0x10390078, 0x103A7910, 0x103B7911, 0x103C7912, 
+        0x103D780B, 0x103E7809, 0x103F7855, 0x1040705D, 0x1041705B, 0x10427110, 0x10437111, 0x10447112, 
+        0x1045700B, 0x10467009, 0x10470078, 0x10487081, 0x104A0078, 0x10500008, 0x105B0078, 0x10680083, 
+        0x106E0095, 0x10700083, 0x10710095, 0x10720083, 0x10760078, 0x10801054, 0x10831077, 0x10841054, 
+        0x10852877, 0x10872855, 0x10882877, 0x10892855, 0x108A2877, 0x108B0054, 0x108C2877, 0x108F0054, 
+        0x10901054, 0x10910054, 0x10950991, 0x10962877, 0x10972855, 0x10982877, 0x109A1071, 0x109C2855, 
+        0x109D1054, 0x109E2855, 0x109F2877, 0x10A00019, 0x10A22877, 0x10A32855, 0x10A50019, 0x10A60078, 
+        0x10A9305F, 0x10AF3106, 0x10B01192, 0x10B11193, 0x10B21194, 0x10B31195, 0x10B41196, 0x10B51197, 
+        0x10B61198, 0x10B71199, 0x10B8119A, 0x10B9119B, 0x10BA119C, 0x10BB119D, 0x10BC119E, 0x10BD119F, 
+        0x10BE11A0, 0x10BF11A1, 0x10C001A2, 0x10C101A3, 0x10C20078, 0x10C80019, 0x10CA0054, 0x10CD0819, 
+        0x10CE0054, 0x10D10019, 0x10D20054, 0x10E60854, 0x10E70819, 0x10E80054, 0x10FA0019, 0x110000E8, 
+        0x11020019, 0x110408FB, 0x110500FC, 0x11070019, 0x110800E8, 0x11090059, 0x110A01A4, 0x110B0019, 
+        0x110D00E8, 0x11110019, 0x111500E8, 0x111610E8, 0x111800E8, 0x111A0019, 0x111C00E8, 0x111E00FE, 
+        0x111F00E8, 0x112008E8, 0x112101A5, 0x112200E8, 0x112308E8, 0x112500E8, 0x11260019, 0x112900FE, 
+        0x112B0019, 0x112F00E8, 0x11300019, 0x113200FE, 0x11360819, 0x113708FE, 0x113900FE, 0x113A08FE, 
+        0x113B00FE, 0x113C08FE, 0x113D00FE, 0x114008FE, 0x114100FE, 0x114208FE, 0x114300FE, 0x114408FE, 
+        0x114500FE, 0x11460019, 0x114700FD, 0x11490019, 0x115100FE, 0x11520019, 0x115300E8, 0x115401A6, 
+        0x115608E8, 0x115800FE, 0x115C0019, 0x115F00E8, 0x11600019, 0x116400FD, 0x116601A7, 0x11670019, 
+        0x116800FE, 0x11690019, 0x116B00FE, 0x117008FE, 0x117200FE, 0x117508FE, 0x11770019, 0x117800FE, 
+        0x11790102, 0x117A00E8, 0x117B0103, 0x117C00E8, 0x117D0104, 0x117E0105, 0x117F00E8, 0x11800054, 
+        0x118400FE, 0x11860054, 0x119000E8, 0x11910054, 0x11940809, 0x11950054, 0x119B0094, 0x11BD0054, 
+        0x11CA0094, 0x11CB0054, 0x11CD0019, 0x11DA00BF, 0x11DB0054, 0x11EE0078, 0x12000054, 0x12130078, 
+        0x12200054, 0x12250078, 0x123018C4, 0x123118C5, 0x123218C6, 0x123318C7, 0x1234191F, 0x1235191A, 
+        0x1236191B, 0x1237191C, 0x1238191D, 0x1239191E, 0x123A10C4, 0x123B10C5, 0x123C10C6, 0x123D10C7, 
+        0x123E111F, 0x123F111A, 0x1240111B, 0x1241111C, 0x1242111D, 0x1243111E, 0x1244105A, 0x124510E3, 
+        0x124610E4, 0x124710E5, 0x124811A8, 0x124911A9, 0x124A11AA, 0x124B11AB, 0x124C11AC, 0x124D11AD, 
+        0x124E1094, 0x125B1918, 0x12681919, 0x1275010B, 0x1276010C, 0x1277010D, 0x1278010E, 0x1279010F, 
+        0x127A0106, 0x127B0107, 0x127C0108, 0x127D0109, 0x127E010A, 0x127F00C3, 0x12800054, 0x12DB0019, 
+        0x12DC0054, 0x12E00019, 0x12E10054, 0x12FC0019, 0x13000054, 0x13370019, 0x13380054, 0x134E0078, 
+        0x13500054, 0x13590078, 0x13800054, 0x13820078, 0x13830054, 0x13850078, 0x13860054, 0x13A90078, 
+        0x13AC0054, 0x13AF0078, 0x13B00054, 0x13B4000A, 0x13BB00C4, 0x13BC00C5, 0x13BD00C6, 0x13BE00C7, 
+        0x13BF011F, 0x13C000C4, 0x13C100C5, 0x13C200C6, 0x13C300C7, 0x13C4011F, 0x13C500C4, 0x13C600C5, 
+        0x13C700C6, 0x13C800C7, 0x13C9011F, 0x13CA0078, 0x13CC0054, 0x13DF0078, 0x13E00019, 0x13E100FD, 
+        0x13E20009, 0x13E30078, 0x13E80019, 0x13E900E8, 0x13EA00FD, 0x13EB0019, 0x13EE00FD, 0x13EF0019, 
+        0x13F100FE, 0x13F3000A, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C10009, 0x14C601AE, 
+        0x14C701AF, 0x14C80009, 0x14CC0019, 0x14CD00E8, 0x14D80019, 0x14E000FE, 0x14E100E8, 0x14E200FE, 
+        0x14E30019, 0x14E400E8, 0x14E50019, 0x14E700FD, 0x14E90019, 0x14EA00FE, 0x14EB0019, 0x14EC000A, 
+        0x14EE0019, 0x14F000E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA01B0, 0x14FB00E8, 0x14FC00FE, 
+        0x14FD0019, 0x14FE000A, 0x14FF0019, 0x150500E8, 0x150E0019, 0x150F00E8, 0x15110019, 0x151400E8, 
+        0x151500FD, 0x15170019, 0x151A00FE, 0x151B0019, 0x151E00FE, 0x151F0019, 0x152B00E8, 0x152C0019, 
+        0x153200FE, 0x15330019, 0x153500E8, 0x15380019, 0x153900E8, 0x153A1019, 0x153B0019, 0x153C00FD, 
+        0x153D00E8, 0x153E00FD, 0x154200E8, 0x154500FD, 0x154600E8, 0x154800FD, 0x154E00E8, 0x155000FD, 
+        0x155100E8, 0x15520019, 0x155300FE, 0x155700FD, 0x155800E8, 0x155900FD, 0x155A00E8, 0x155D00FD, 
+        0x156300E8, 0x156600FD, 0x156B0019, 0x157101B1, 0x15730019, 0x157600FE, 0x15770019, 0x157900E8, 
+        0x157A0019, 0x157B00FD, 0x157D00E8, 0x157F0019, 0x15800054, 0x158A0078, 0x16000096, 0x16170078, 
+        0x16180098, 0x162F0078, 0x16400065, 0x16720054, 0x16750078, 0x167C0006, 0x167E005F, 0x167F0006, 
+        0x16800125, 0x16930078, 0x16980071, 0x16B30078, 0x16B77881, 0x16B80078, 0x16C00071, 0x16CB0078, 
+        0x16D00071, 0x16D30078, 0x16D40071, 0x16D70078, 0x16D80071, 0x16DB0078, 0x16DC0071, 0x16DF0078, 
+        0x16E00071, 0x16E30078, 0x16E40071, 0x16E70078, 0x16E80071, 0x16EB0078, 0x16EC0071, 0x16EF0078, 
+        0x17000006, 0x170100E0, 0x17030006, 0x17040126, 0x17050006, 0x170600E0, 0x17070006, 0x170B0099, 
+        0x170C0078, 0x170E00E0, 0x170F0078, 0x17400054, 0x174F1054, 0x17500054, 0x17791054, 0x177A0078, 
+        0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18000006, 0x18020081, 0x180301B2, 0x1804000A, 
+        0x18090054, 0x180A000A, 0x180E00B4, 0x180F00BF, 0x181001B3, 0x181101B4, 0x181201B5, 0x181301B6, 
+        0x181401B7, 0x18150083, 0x18180081, 0x181B0054, 0x181C11B8, 0x181D0081, 0x181E0006, 0x181F0054, 
+        0x18200071, 0x18320871, 0x18350071, 0x18380871, 0x183A0071, 0x183B0871, 0x183D0071, 0x183E0871, 
+        0x183F0071, 0x184B0078, 0x184C0083, 0x184D1037, 0x184E0081, 0x184F8071, 0x18500071, 0x18620871, 
+        0x18650071, 0x18680871, 0x186A0071, 0x186B0871, 0x186D0071, 0x186E0871, 0x186F0071, 0x187B0871, 
+        0x187D0006, 0x187E0081, 0x187F8071, 0x18800078, 0x18820071, 0x18960078, 0x18981071, 0x18C70078, 
+        0x18C80094, 0x18C978B6, 0x18CA78B7, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 
+        0x18F80071, 0x19001094, 0x190E1054, 0x190F0078, 0x191010B6, 0x191110B7, 0x191210B8, 0x191310B9, 
+        0x191410B0, 0x19151094, 0x19220078, 0x192819B9, 0x192919BA, 0x192A19BB, 0x192B19BC, 0x192C19BD, 
+        0x192D19BE, 0x192E19BF, 0x192F19C0, 0x19301894, 0x193E1854, 0x193F0094, 0x194018B6, 0x194118B7, 
+        0x194218B8, 0x194318B9, 0x194418B0, 0x19451894, 0x195819C1, 0x195919C2, 0x195A19C3, 0x195B19C4, 
+        0x195C19C5, 0x195D19C6, 0x195E19C7, 0x195F19C8, 0x19601094, 0x19666854, 0x19681894, 0x197F0078, 
+        0x19806894, 0x19AC1094, 0x19B86894, 0x19BB6854, 0x19BD6894, 0x19EF6854, 0x19F01094, 0x19FF6854, 
+        0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x500A0081, 0x500B0071, 
+        0x52460078, 0x52480054, 0x52630078, 0x53800037, 0x538B0078, 0x54000071, 0x54050083, 0x54060071, 
+        0x541100A7, 0x54120083, 0x541300A7, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E, 
+        0x7000013F, 0x7C800871, 0x7D070071, 0x7D0A0871, 0x7D0F0071, 0x7D120871, 0x7D130071, 0x7D150871, 
+        0x7D170078, 0x7D180871, 0x7D350078, 0x7D380871, 0x7D6D0078, 0x7D801055, 0x7D830078, 0x7D891055, 
+        0x7D8C0078, 0x7D8E089B, 0x7D90289B, 0x7D94280B, 0x7D95089B, 0x7D9B0078, 0x7D9C089B, 0x7D9E0078, 
+        0x7DA0089B, 0x7DA20078, 0x7DA3089B, 0x7DA7109B, 0x7DA8209E, 0x7DAA489E, 0x7DAB209E, 0x7DAC489E, 
+        0x7DAD209E, 0x7DAE489E, 0x7DAF209E, 0x7DB0489E, 0x7DB1209E, 0x7DB2489E, 0x7DB3209E, 0x7DB4489E, 
+        0x7DB5209E, 0x7DB6489E, 0x7DB7209E, 0x7DB8489E, 0x7DB9209E, 0x7DBA489E, 0x7DBB209E, 0x7DBC489E, 
+        0x7DBD209E, 0x7DBE489E, 0x7DBF209E, 0x7DC0489E, 0x7DC1209E, 0x7DC8489E, 0x7DC9209E, 0x7DCA489E, 
+        0x7DCB209E, 0x7DCC489E, 0x7DCD209E, 0x7DCE489E, 0x7DCF209E, 0x7DD1489E, 0x7DD2209E, 0x7DD4489E, 
+        0x7DD5209E, 0x7DD6489E, 0x7DD7209E, 0x7DD90078, 0x7DE9409E, 0x7DEA389E, 0x7DEB409E, 0x7DEF209E, 
+        0x7DF3489E, 0x7DF5209E, 0x7DFC409E, 0x7DFD389E, 0x7DFE209E, 0x7DFF489E, 0x7E00409E, 0x7E32209E, 
+        0x7E4B389E, 0x7E6F489E, 0x7E7A409E, 0x7E88209E, 0x7E96389E, 0x7E9A489E, 0x7E9E409E, 0x7E9F00BF, 
+        0x7EA00078, 0x7EA8209E, 0x7EA9389E, 0x7EAD209E, 0x7EAE389E, 0x7EAF209E, 0x7EB0389E, 0x7EB3209E, 
+        0x7EB5389E, 0x7EB7209E, 0x7EB9389E, 0x7EBA209E, 0x7EBB389E, 0x7EBC209E, 0x7EBE389E, 0x7EBF209E, 
+        0x7EC1389E, 0x7EC2209E, 0x7EC4389E, 0x7EC5209E, 0x7EC6389E, 0x7EC80078, 0x7EC9389E, 0x7ECB209E, 
+        0x7ECE389E, 0x7ECF209E, 0x7EDA389E, 0x7EDB209E, 0x7EE1389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 
+        0x7EFE0054, 0x7EFF0078, 0x7F000083, 0x7F088006, 0x7F0B80B4, 0x7F0C8006, 0x7F0D0078, 0x7F100083, 
+        0x7F120078, 0x7F188099, 0x7F198038, 0x7F1A80B4, 0x7F220006, 0x7F2380B4, 0x7F241006, 0x7F261038, 
+        0x7F286006, 0x7F290078, 0x7F2A600C, 0x7F2B6006, 0x7F2C60B4, 0x7F2F6007, 0x7F306006, 0x7F31600D, 
+        0x7F326019, 0x7F330078, 0x7F346008, 0x7F356006, 0x7F360078, 0x7F38489E, 0x7F39009E, 0x7F3A0078, 
+        0x7F3B489E, 0x7F40409E, 0x7F45389E, 0x7F46409E, 0x7F48389E, 0x7F49409E, 0x7F4B389E, 0x7F4C409E, 
+        0x7F4D389E, 0x7F4E409E, 0x7F4F389E, 0x7F50409E, 0x7F51389E, 0x7F52409E, 0x7F53389E, 0x7F54409E, 
+        0x7F59389E, 0x7F5A409E, 0x7F5B389E, 0x7F5C409E, 0x7F5D389E, 0x7F5E409E, 0x7F5F389E, 0x7F60409E, 
+        0x7F61389E, 0x7F62409E, 0x7F63389E, 0x7F64409E, 0x7F65389E, 0x7F66409E, 0x7F67389E, 0x7F68409E, 
+        0x7F69389E, 0x7F6A409E, 0x7F6B389E, 0x7F6C409E, 0x7F6D389E, 0x7F6E409E, 0x7F6F389E, 0x7F70409E, 
+        0x7F71389E, 0x7F72409E, 0x7F73389E, 0x7F74409E, 0x7F75389E, 0x7F76409E, 0x7F79389E, 0x7F7A409E, 
+        0x7F7E0078, 0x7F7F0057, 0x7F808806, 0x7F818807, 0x7F838806, 0x7F84880A, 0x7F85880B, 0x7F86880D, 
+        0x7F87880C, 0x7F88880F, 0x7F898811, 0x7F8A8813, 0x7F8B8815, 0x7F8C8817, 0x7F8D8806, 0x7F8E8819, 
+        0x7F8F8806, 0x7F908860, 0x7F9D8835, 0x7F9E8836, 0x7F9F8838, 0x7FA08861, 0x7FAD8835, 0x7FAE8836, 
+        0x7FAF8809, 0x7FB05006, 0x7FB1500A, 0x7FB25006, 0x7FB35071, 0x7FCF5081, 0x7FD05071, 0x7FDF0078, 
+        0x7FE15071, 0x7FE40078, 0x7FE55071, 0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEE0078, 
+        0x7FF08808, 0x7FF18837, 0x7FF28808, 0x7FF30078, 0x7FF45019, 0x7FF65054, 0x7FF70078, 0x7FFC0141, 
+        0x7FFE0054, 0x7FFF0078, 0x80000071, 0x80130078, 0x80140071, 0x801D0078, 0x801E0071, 0x80270078, 
+        0x80280071, 0x802F0078, 0x80400071, 0x807D0078, 0x80800006, 0x80810078, 0x808300AD, 0x808400AE, 
+        0x8085012D, 0x8086012E, 0x8087012F, 0x80880185, 0x80890186, 0x808A0187, 0x808B0188, 0x808C0184, 
+        0x808D01C9, 0x808E01CA, 0x808F01CB, 0x809001CC, 0x809101CD, 0x809201CE, 0x809301CF, 0x809401D0, 
+        0x809500BE, 0x809601D1, 0x809701D2, 0x809801D3, 0x809901D4, 0x809A0078, 0x809B0094, 0x80A0014E, 
+        0x80A10152, 0x80A20153, 0x80A30157, 0x80A40154, 0x80A50155, 0x80A60156, 0x80A70152, 0x80A80150, 
+        0x80A90153, 0x80AA01D5, 0x80AB0154, 0x80AC014F, 0x80AD0158, 0x80AF0152, 0x80B00154, 0x80B201D6, 
+        0x80B30150, 0x80B501D7, 0x80B60153, 0x80B80156, 0x80B90152, 0x80BA005F, 0x80BC0054, 0x80C50078, 
+        0x81800071, 0x818F0078, 0x8190012D, 0x819100BB, 0x81920078, 0x81980071, 0x81A50078, 0x81C00071, 
+        0x81CF0097, 0x81D00071, 0x81E20078, 0x81E40071, 0x81E8014F, 0x81E90154, 0x81EA0155, 0x81EB0078, 
+        0x8200015B, 0x8214015C, 0x82280071, 0x824F0078, 0x8250017E, 0x8251017F, 0x82520180, 0x82530181, 
+        0x82540182, 0x82550078, 0x8400009B, 0x84030078, 0x8405009B, 0x841C0078, 0x841F009B, 0x84200078, 
+        0x85000083, 0x85030078, 0x85060083, 0x8508009B, 0x851A0078, 0x851C0083, 0x851D0078, 0x851F0083, 
+        0x852001D8, 0x852101D9, 0x852201DA, 0x852301DB, 0x85240078, 0x8528009A, 0x852C0078, 0xE8000094, 
+        0xE87B0078, 0xE8800094, 0xE8930078, 0xE8950094, 0xE8AF0894, 0xE8B200A7, 0xE8B30083, 0xE8B50094, 
+        0xE8B600A7, 0xE8B90057, 0xE8BD0083, 0xE8C10094, 0xE8C20083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 
+        0xE8DD0894, 0xE8E00094, 0xE8EF0078, 0xE9000054, 0xE9210083, 0xE9220054, 0xE9230078, 0xE9800054, 
+        0xE9AB0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 0xEA272855, 0xEA2A0078, 0xEA2B2855, 0xEA342877, 
+        0xEA412855, 0xEA4E0078, 0xEA4F2877, 0xEA500078, 0xEA522877, 0xEA530078, 0xEA542877, 0xEA560078, 
+        0xEA572877, 0xEA5B2855, 0xEA682877, 0xEA752855, 0xEA822877, 0xEA850078, 0xEA862877, 0xEA8A0078, 
+        0xEA8B2877, 0xEA8E0078, 0xEA8F2855, 0xEA9C2877, 0xEA9F0078, 0xEAA02877, 0xEAA20078, 0xEAA52877, 
+        0xEAA80078, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 0xEADD2855, 0xEAEA2877, 0xEAF72855, 
+        0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 0xEB452855, 0xEB530078, 0xEB542877, 
+        0xEB6029DC, 0xEB612855, 0xEB6D29DC, 0xEB6E2855, 0xEB712877, 0xEB7D29DC, 0xEB7E2855, 0xEB8A29DC, 
+        0xEB8B2855, 0xEB8E2877, 0xEB9A29DC, 0xEB9B2855, 0xEBA729DC, 0xEBA82855, 0xEBAB2877, 0xEBB729DC, 
+        0xEBB82855, 0xEBC429DC, 0xEBC52855, 0xEBC82877, 0xEBD429DC, 0xEBD52855, 0xEBE129DC, 0xEBE22855, 
+        0xEBE50078, 0xEBE7280F, 0xEBE82811, 0xEBE92813, 0xEBEA2815, 0xEBEB2817, 0xEBEC280F, 0xEBED2811, 
+        0xEBEE2813, 0xEBEF2815, 0xEBF02817, 0xEBF1280F, 0xEBF22811, 0xEBF32813, 0xEBF42815, 0xEBF52817, 
+        0xEBF6280F, 0xEBF72811, 0xEBF82813, 0xEBF92815, 0xEBFA2817, 0xEBFB280F, 0xEBFC2811, 0xEBFD2813, 
+        0xEBFE2815, 0xEBFF2817, 0xEC000078
+    };
+
+    static const uint32_t a17[] = {
+        0x00000071, 0x536B0078, 0x7C000871, 0x7D0F0078
+    };
+
+    static const uint32_t a23[] = {
+        0x00000057, 0x00010078, 0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
+    };
+
+    static const uint32_t a24[] = {
+        0x0000013F, 0x7FFF0078
+    };
+
+
+    // The full set of all arrays to be searched.
+    static const Range FULL_DATA[] = {
+        {sizeof(a0)/sizeof(uint32_t), a0},
+        {sizeof(a1)/sizeof(uint32_t), a1},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {sizeof(a7)/sizeof(uint32_t), a7},
+        {sizeof(a8)/sizeof(uint32_t), a8},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {sizeof(a16)/sizeof(uint32_t), a16},
+        {sizeof(a17)/sizeof(uint32_t), a17},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {sizeof(a23)/sizeof(uint32_t), a23},
+        {sizeof(a24)/sizeof(uint32_t), a24},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0},
+        {0, 0}
+    };
+
+    // Array of uppercase differences
+    static const short UCDIFF[] = {
+            0,   -32,   743,   121,    -1,  -232,  -300,    97, 
+          163,   130,    56,    -2,   -79,  -210,  -206,  -205, 
+         -202,  -203,  -207,  -209,  -211,  -213,  -214,  -218, 
+         -217,  -219,   -83,    84,   -38,   -37,   -31,   -64, 
+          -63,   -62,   -57,   -47,   -54,   -86,   -80,     7, 
+          -96,   -48,   -59,     8,    74,    86,   100,   128, 
+          112,   126,     9, -7205,   -16,   -26, -7264,   -40
+    };
+
+    // Array of lowercase differences
+    static const short LCDIFF[] = {
+            0,    32,     1,  -199,  -121,   210,   206,   205, 
+           79,   202,   203,   207,   211,   209,   213,   214, 
+          218,   217,   219,     2,   -97,   -56,  -130,  -163, 
+           83,    38,    37,    64,    63,   -60,    -7,    80, 
+           48,  7264,    -8,   -74,    -9,   -86,  -100,  -112, 
+         -128,  -126, -7517, -8383, -8262,    16,    26,    40
+    };
+
+    // Array of titlecase differences
+    static const short TCDIFF[] = {
+            3,     1,     0,    -1
+    };
+
+    // Array of mirrored character differences
+    static const short MIRROR_DIFF[] = {
+            0,     1,    -1,     2,    -2,    16,   -16,     3, 
+           -3,  2016,   138,  1824,  2104,  2108,  2106,  -138, 
+            8,     7,    -8,    -7, -1824, -2016, -2104, -2106, 
+        -2108
+    };
+
+   // Array of all possible numeric values
+   static const int NUMERICS[] = {
+            -1,      0,      1,      2,      3,      4,      5,      6, 
+             7,      8,      9,     10,     11,     12,     13,     14, 
+            15,     16,     17,     18,     19,     20,     21,     22, 
+            23,     24,     25,     26,     27,     28,     29,     30, 
+            31,     32,     33,     34,     35,     -2,    100,   1000, 
+            40,     50,     60,     70,     80,     90,  10000,    500, 
+          5000,     36,     37,     38,     39,     41,     42,     43, 
+            44,     45,     46,     47,     48,     49,    200,    300, 
+           400,    600,    700,    800,    900,   2000,   3000,   4000, 
+          6000,   7000,   8000,   9000,  20000,  30000,  40000,  50000, 
+         60000,  70000,  80000,  90000
+    };
+
+    // All possible packed data values, no duplicates
+    static const uint32_t PACKED_DATA[] = {
+        0x00000000, 0x0000012F, 0x0000016F, 0x0000014F, 0x0000018F, 0x0000018C, 0x000001B8, 0x000000B8, 
+        0x000000BA, 0x020005B5, 0x040005B6, 0x00000099, 0x000000F8, 0x00000094, 0x02000069, 0x04000069, 
+        0x06000069, 0x08000069, 0x0A000069, 0x0C000069, 0x0E000069, 0x10000069, 0x12000069, 0x14000069, 
+        0x060005B9, 0x000001B9, 0x080005B9, 0x16020001, 0x18020001, 0x1A020001, 0x1C020001, 0x1E020001, 
+        0x20020001, 0x22020001, 0x24020001, 0x26020001, 0x28020001, 0x2A020001, 0x2C020001, 0x2E020001, 
+        0x30020001, 0x32020001, 0x34020001, 0x36020001, 0x38020001, 0x3A020001, 0x3C020001, 0x3E020001, 
+        0x40020001, 0x42020001, 0x44020001, 0x46020001, 0x48020001, 0x060005B5, 0x080005B6, 0x000001BB, 
+        0x000001B7, 0x16000802, 0x18000802, 0x1A000802, 0x1C000802, 0x1E000802, 0x20000802, 0x22000802, 
+        0x24000802, 0x26000802, 0x28000802, 0x2A000802, 0x2C000802, 0x2E000802, 0x30000802, 0x32000802, 
+        0x34000802, 0x36000802, 0x38000802, 0x3A000802, 0x3C000802, 0x3E000802, 0x40000802, 0x42000802, 
+        0x44000802, 0x46000802, 0x48000802, 0x000000EC, 0x000001BC, 0x00000002, 0x0A0005BD, 0x00000130, 
+        0x000000BC, 0x000000B9, 0x0600006B, 0x0800006B, 0x00001002, 0x0400006B, 0x0C0005BE, 0x4A0001AB, 
+        0x00020001, 0x00000802, 0x00001802, 0x00040001, 0x00060001, 0x00002002, 0x00080001, 0x000C0001, 
+        0x000E0001, 0x00100001, 0x00140001, 0x00160001, 0x00180001, 0x00004002, 0x00004802, 0x00200001, 
+        0x00220001, 0x00000005, 0x00A60001, 0x01805802, 0x01042003, 0x00280001, 0x002C0001, 0x00000001, 
+        0x00000000, 0x00007002, 0x00007802, 0x00009802, 0x0000A802, 0x0000B802, 0x0000C002, 0x0000C802, 
+        0x0000D002, 0x00000004, 0x000001A4, 0x00000106, 0x00320001, 0x00340001, 0x00360001, 0x00380001, 
+        0x0000E002, 0x0000E802, 0x0000F002, 0x0000F802, 0x00010002, 0x00010802, 0x00012002, 0x00012802, 
+        0x00013802, 0x003A0001, 0x003E0001, 0x00013002, 0x0000001C, 0x00000107, 0x00400001, 0x00000018, 
+        0x00014802, 0x000001B4, 0x00000038, 0x00000025, 0x00000050, 0x00000058, 0x00000045, 0x00000044, 
+        0x020000C9, 0x060000C9, 0x0A0000C9, 0x0E0000C9, 0x120000C9, 0x000000D8, 0x0000005C, 0x00000008, 
+        0x02000009, 0x06000009, 0x0A000009, 0x0E000009, 0x12000009, 0x0400000B, 0x0800000B, 0x0000000B, 
+        0x1600000B, 0x4E00000B, 0x00000006, 0x4A00000B, 0x000001B5, 0x00420001, 0x0600000B, 0x0A00000B, 
+        0x0E00000B, 0x1200000B, 0x3E00000B, 0x5200000B, 0x5600000B, 0x5A00000B, 0x5C00000B, 0x000001B6, 
+        0x2400000A, 0x2800000A, 0x00000010, 0x020001AB, 0x060001AB, 0x0A0001AB, 0x0E0001AB, 0x120001AB, 
+        0x00000108, 0x00015802, 0x00440001, 0x00016002, 0x00016802, 0x00017002, 0x00017802, 0x00018002, 
+        0x00018802, 0x00440003, 0x00460001, 0x00480003, 0x00019802, 0x004A0001, 0x004C0001, 0x004E0001, 
+        0x003C0001, 0x00500001, 0x00520001, 0x000001BD, 0x0000018D, 0x000001D0, 0x00000250, 0x00000230, 
+        0x040005BE, 0x000000F9, 0x0200006B, 0x0A00006B, 0x0E00006B, 0x1200006B, 0x00540001, 0x00560001, 
+        0x000005B9, 0x045A000A, 0x085A000A, 0x0C5A000A, 0x105A000A, 0x145A000A, 0x185A000A, 0x525A000A, 
+        0x5E5A000A, 0x0401A00A, 0x0801A00A, 0x0C01A00A, 0x1001A00A, 0x1401A00A, 0x1801A00A, 0x5201A00A, 
+        0x5E01A00A, 0x4E00000A, 0x5C00000A, 0x0E0005B9, 0x100005B9, 0x020005B9, 0x040005B9, 0x160005B9, 
+        0x180005B9, 0x1A0005B9, 0x200005B9, 0x220005B9, 0x240005B9, 0x260005B9, 0x040001AB, 0x080001AB, 
+        0x0C0001AB, 0x100001AB, 0x140001AB, 0x180001AB, 0x1C0001AB, 0x200001AB, 0x240001AB, 0x280001AB, 
+        0x0C00006B, 0x1000006B, 0x1400006B, 0x1800006B, 0x1C00006B, 0x2000006B, 0x2400006B, 0x2800006B, 
+        0x005C001C, 0x0001A81C, 0x1A0001AB, 0x1E0001AB, 0x220001AB, 0x260001AB, 0x2A0001AB, 0x160001AB, 
+        0x020005B6, 0x100005B6, 0x280005B9, 0x2C0005B9, 0x300005B9, 0x0001B002, 0x020005BD, 0x0600000A, 
+        0x0A00000A, 0x0E00000A, 0x1200000A, 0x1600000A, 0x3E00000A, 0x0C00000B, 0x1000000B, 0x1400000B, 
+        0x2E0001AB, 0x320001AB, 0x360001AB, 0x3A0001AB, 0x3E0001AB, 0x420001AB, 0x460001AB, 0x640001AB, 
+        0x680001AB, 0x6A0001AB, 0x6E0001AB, 0x720001AB, 0x760001AB, 0x7A0001AB, 0x00000013, 0x00000012, 
+        0x0000005A, 0x000001B0, 0x7C00000B, 0x8000000B, 0x8200000B, 0x8600000B, 0x8C00000B, 0x6000000B, 
+        0x9200000B, 0x9600000B, 0x9800000B, 0x9C00000B, 0xA000000B, 0xA400000B, 0x4A0001AA, 0x040001AA, 
+        0x520001AA, 0x600001AA, 0x0C0001AA, 0x5E0001AA, 0x160001AA, 0x4C0001AA, 0x4E0001AA, 0x9E0001AA, 
+        0x060001AA, 0x8800000A, 0x2A0001AA, 0x005E0001, 0x0001B802, 0x0400002B, 0x0800002B, 0x1600002B, 
+        0x4C00002B, 0x00002802, 0x00003002, 0x000A0001, 0x00120001, 0x00003802, 0x001A0001, 0x001C0001, 
+        0x001E0001, 0x00240001, 0x00005002, 0x00006002, 0x002A0001, 0x002E0001, 0x00300001, 0x00006802, 
+        0x00008002, 0x00008802, 0x00009002, 0x0000A002, 0x0000B002, 0x0000D906, 0x00011002, 0x00011802, 
+        0x00014002, 0x040000C9, 0x080000C9, 0x0C0000C9, 0x100000C9, 0x140000C9, 0x04000009, 0x08000009, 
+        0x0C000009, 0x10000009, 0x14000009, 0x2200000B, 0x4C00000B, 0x2A00000B, 0x5000000B, 0x5400000B, 
+        0x5800000B, 0x2600000A, 0x00015002, 0x00019002, 0x00000030, 0x000001BE, 0x0000014E, 0x00000210, 
+        0x000001F0, 0x00580001, 0x065A000A, 0x0A5A000A, 0x0E5A000A, 0x125A000A, 0x165A000A, 0x1A5A000A, 
+        0x4C5A000A, 0x4E5A000A, 0x0601A00A, 0x0A01A00A, 0x0E01A00A, 0x1201A00A, 0x1601A00A, 0x1A01A00A, 
+        0x4C01A00A, 0x4E01A00A, 0x6000000A, 0x0000000A, 0x120005B9, 0x140005B9, 0x1C0005B9, 0x1E0005B9, 
+        0x1600006B, 0x1A00006B, 0x1E00006B, 0x2200006B, 0x2600006B, 0x2A00006B, 0x0E0005B5, 0x040005B5, 
+        0x2A0005B9, 0x2E0005B9, 0x0200000A, 0x0400000A, 0x0800000A, 0x0C00000A, 0x1000000A, 0x1400000A, 
+        0x2A00000A, 0x2C0001AB, 0x300001AB, 0x340001AB, 0x380001AB, 0x3C0001AB, 0x400001AB, 0x440001AB, 
+        0x480001AB, 0x620001AB, 0x660001AB, 0x500001AB, 0x6C0001AB, 0x700001AB, 0x740001AB, 0x780001AB, 
+        0x520001AB, 0x7E00000B, 0x5E00000B, 0x8400000B, 0x8800000B, 0x8A00000B, 0x8E00000B, 0x9000000B, 
+        0x9400000B, 0x9A00000B, 0x9E00000B, 0xA200000B, 0xA600000B, 0x5C0001AA, 0x3E0001AA, 0x7E0001AA, 
+        0x0600002B, 0x0A00002B, 0x2A00002B, 0x4E00002B, 0x00000019
+    };
+}
diff --git a/libs/utils/executablepath_darwin.cpp b/libs/utils/executablepath_darwin.cpp
new file mode 100644
index 0000000..2e3c3a0
--- /dev/null
+++ b/libs/utils/executablepath_darwin.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/executablepath.h>
+#import <Carbon/Carbon.h>
+#include <unistd.h>
+
+void executablepath(char s[PATH_MAX])
+{
+    ProcessSerialNumber psn;
+    GetCurrentProcess(&psn);
+    CFDictionaryRef dict;
+    dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
+    CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict,
+                CFSTR("CFBundleExecutable"));
+    CFStringGetCString(value, s, PATH_MAX+1, kCFStringEncodingUTF8);
+}
+
diff --git a/libs/utils/executablepath_linux.cpp b/libs/utils/executablepath_linux.cpp
new file mode 100644
index 0000000..b8d2a3d
--- /dev/null
+++ b/libs/utils/executablepath_linux.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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 <utils/executablepath.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdio.h>
+
+void executablepath(char exe[PATH_MAX])
+{
+    char proc[100];
+    sprintf(proc, "/proc/%d/exe", getpid());
+    
+    int err = readlink(proc, exe, PATH_MAX);
+}
+
diff --git a/libs/utils/futex_synchro.c b/libs/utils/futex_synchro.c
new file mode 100644
index 0000000..c13760d
--- /dev/null
+++ b/libs/utils/futex_synchro.c
@@ -0,0 +1,175 @@
+/*
+ * 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 <stdio.h>
+#include <limits.h>
+
+#include <sys/time.h>
+#include <sched.h>
+
+#include <errno.h>
+
+#include <private/utils/futex_synchro.h>
+
+
+// This futex glue code is need on desktop linux, but is part of klibc on ARM
+#if !defined(__arm__)
+
+#include <sys/syscall.h>
+typedef unsigned int u32;
+#define asmlinkage
+#define __user
+#include <linux/futex.h>
+#include <utils/Atomic.h>
+
+
+int futex (int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3)
+{
+    int err = syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3);
+    return err == 0 ? 0 : -errno;
+}
+
+int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout)
+{
+    return futex((int*)ftx, FUTEX_WAIT, val, timeout, NULL, 0);
+}
+
+int __futex_wake(volatile void *ftx, int count)
+{
+    return futex((int*)ftx, FUTEX_WAKE, count, NULL, NULL, 0);
+}
+
+int __atomic_cmpxchg(int old, int _new, volatile int *ptr)
+{
+    return android_atomic_cmpxchg(old, _new, ptr);
+}
+
+int __atomic_swap(int _new, volatile int *ptr)
+{
+    return android_atomic_swap(_new, ptr);
+}
+
+int __atomic_dec(volatile int *ptr)
+{
+    return android_atomic_dec(ptr);
+}
+
+#else // !defined(__arm__)
+
+int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
+int __futex_wake(volatile void *ftx, int count);
+
+int __atomic_cmpxchg(int old, int _new, volatile int *ptr);
+int __atomic_swap(int _new, volatile int *ptr);
+int __atomic_dec(volatile int *ptr);
+
+#endif // !defined(__arm__)
+
+
+// lock states
+//
+// 0: unlocked
+// 1: locked, no waiters
+// 2: locked, maybe waiters
+
+void futex_mutex_init(futex_mutex_t *m)
+{
+    m->value = 0;
+}
+
+int futex_mutex_lock(futex_mutex_t *m, unsigned msec)
+{
+    if(__atomic_cmpxchg(0, 1, &m->value) == 0) {
+        return 0;
+    }
+    if(msec == FUTEX_WAIT_INFINITE) {
+        while(__atomic_swap(2, &m->value) != 0) {
+            __futex_wait(&m->value, 2, 0);
+        }
+    } else {
+        struct timespec ts;
+        ts.tv_sec = msec / 1000;
+        ts.tv_nsec = (msec % 1000) * 1000000;
+        while(__atomic_swap(2, &m->value) != 0) {
+            if(__futex_wait(&m->value, 2, &ts) == -ETIMEDOUT) {
+                return -1;
+            }
+        }
+    }
+    return 0;
+}
+
+int futex_mutex_trylock(futex_mutex_t *m)
+{
+    if(__atomic_cmpxchg(0, 1, &m->value) == 0) {
+        return 0;
+    }
+    return -1;
+}
+
+void futex_mutex_unlock(futex_mutex_t *m)
+{
+    if(__atomic_dec(&m->value) != 1) {
+        m->value = 0;
+        __futex_wake(&m->value, 1);
+    }
+}
+
+/* XXX *technically* there is a race condition that could allow
+ * XXX a signal to be missed.  If thread A is preempted in _wait()
+ * XXX after unlocking the mutex and before waiting, and if other
+ * XXX threads call signal or broadcast UINT_MAX times (exactly),
+ * XXX before thread A is scheduled again and calls futex_wait(),
+ * XXX then the signal will be lost.
+ */
+
+void futex_cond_init(futex_cond_t *c)
+{
+    c->value = 0;
+}
+
+int futex_cond_wait(futex_cond_t *c, futex_mutex_t *m, unsigned msec)
+{
+    if(msec == FUTEX_WAIT_INFINITE){
+        int oldvalue = c->value;
+        futex_mutex_unlock(m);
+        __futex_wait(&c->value, oldvalue, 0);
+        futex_mutex_lock(m, FUTEX_WAIT_INFINITE);
+        return 0;
+    } else {
+        int oldvalue = c->value;
+        struct timespec ts;        
+        ts.tv_sec = msec / 1000;
+        ts.tv_nsec = (msec % 1000) * 1000000;
+        futex_mutex_unlock(m);
+        const int err = __futex_wait(&c->value, oldvalue, &ts);
+        futex_mutex_lock(m, FUTEX_WAIT_INFINITE);
+        return err;
+    }
+}
+
+void futex_cond_signal(futex_cond_t *c)
+{
+    __atomic_dec(&c->value);
+    __futex_wake(&c->value, 1);
+}
+
+void futex_cond_broadcast(futex_cond_t *c)
+{
+    __atomic_dec(&c->value);
+    __futex_wake(&c->value, INT_MAX);
+}
+
diff --git a/libs/utils/misc.cpp b/libs/utils/misc.cpp
new file mode 100644
index 0000000..dc89d15
--- /dev/null
+++ b/libs/utils/misc.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Miscellaneous utility functions.
+//
+#include <utils/misc.h>
+
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdio.h>
+
+using namespace android;
+
+namespace android {
+
+/*
+ * Like strdup(), but uses C++ "new" operator instead of malloc.
+ */
+char* strdupNew(const char* str)
+{
+    char* newStr;
+    int len;
+
+    if (str == NULL)
+        return NULL;
+
+    len = strlen(str);
+    newStr = new char[len+1];
+    memcpy(newStr, str, len+1);
+
+    return newStr;
+}
+
+/*
+ * Concatenate an argument vector.
+ */
+char* concatArgv(int argc, const char* const argv[])
+{
+    char* newStr = NULL;
+    int len, totalLen, posn, idx;
+
+    /*
+     * First, figure out the total length.
+     */
+    totalLen = idx = 0;
+    while (1) {
+        if (idx == argc || argv[idx] == NULL)
+            break;
+        if (idx)
+            totalLen++;  // leave a space between args
+        totalLen += strlen(argv[idx]);
+        idx++;
+    }
+
+    /*
+     * Alloc the string.
+     */
+    newStr = new char[totalLen +1];
+    if (newStr == NULL)
+        return NULL;
+
+    /*
+     * Finally, allocate the string and copy data over.
+     */
+    idx = posn = 0;
+    while (1) {
+        if (idx == argc || argv[idx] == NULL)
+            break;
+        if (idx)
+            newStr[posn++] = ' ';
+
+        len = strlen(argv[idx]);
+        memcpy(&newStr[posn], argv[idx], len);
+        posn += len;
+
+        idx++;
+    }
+
+    assert(posn == totalLen);
+    newStr[posn] = '\0';
+
+    return newStr;
+}
+
+/*
+ * Count the #of args in an argument vector.  Don't count the final NULL.
+ */
+int countArgv(const char* const argv[])
+{
+    int count = 0;
+
+    while (argv[count] != NULL)
+        count++;
+
+    return count;
+}
+
+
+#include <stdio.h>
+/*
+ * Get a file's type.
+ */
+FileType getFileType(const char* fileName)
+{
+    struct stat sb;
+
+    if (stat(fileName, &sb) < 0) {
+        if (errno == ENOENT || errno == ENOTDIR)
+            return kFileTypeNonexistent;
+        else {
+            fprintf(stderr, "getFileType got errno=%d on '%s'\n",
+                errno, fileName);
+            return kFileTypeUnknown;
+        }
+    } else {
+        if (S_ISREG(sb.st_mode))
+            return kFileTypeRegular;
+        else if (S_ISDIR(sb.st_mode))
+            return kFileTypeDirectory;
+        else if (S_ISCHR(sb.st_mode))
+            return kFileTypeCharDev;
+        else if (S_ISBLK(sb.st_mode))
+            return kFileTypeBlockDev;
+        else if (S_ISFIFO(sb.st_mode))
+            return kFileTypeFifo;
+#ifdef HAVE_SYMLINKS            
+        else if (S_ISLNK(sb.st_mode))
+            return kFileTypeSymlink;
+        else if (S_ISSOCK(sb.st_mode))
+            return kFileTypeSocket;
+#endif            
+        else
+            return kFileTypeUnknown;
+    }
+}
+
+/*
+ * Get a file's modification date.
+ */
+time_t getFileModDate(const char* fileName)
+{
+    struct stat sb;
+
+    if (stat(fileName, &sb) < 0)
+        return (time_t) -1;
+
+    return sb.st_mtime;
+}
+
+/*
+ * Round up to the next highest power of 2.
+ *
+ * Found on http://graphics.stanford.edu/~seander/bithacks.html.
+ */
+unsigned int roundUpPower2(unsigned int val)
+{
+    val--;
+    val |= val >> 1;
+    val |= val >> 2;
+    val |= val >> 4;
+    val |= val >> 8;
+    val |= val >> 16;
+    val++;
+
+    return val;
+}
+
+}; // namespace android
+
diff --git a/libs/utils/ported.cpp b/libs/utils/ported.cpp
new file mode 100644
index 0000000..656e46f
--- /dev/null
+++ b/libs/utils/ported.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Ports of standard functions that don't exist on a specific platform.
+//
+// Note these are NOT in the "android" namespace.
+//
+#include <utils/ported.h>
+
+#if defined(NEED_GETTIMEOFDAY) || defined(NEED_USLEEP)
+# include <sys/time.h>
+# include <windows.h>
+#endif
+
+
+#if defined(NEED_GETTIMEOFDAY)
+/*
+ * Replacement gettimeofday() for Windows environments (primarily MinGW).
+ *
+ * Ignores "tz".
+ */
+int gettimeofday(struct timeval* ptv, struct timezone* tz)
+{
+    long long nsTime;   // time in 100ns units since Jan 1 1601
+    FILETIME ft;
+
+    if (tz != NULL) {
+        // oh well
+    }
+
+    ::GetSystemTimeAsFileTime(&ft);
+    nsTime = (long long) ft.dwHighDateTime << 32 |
+             (long long) ft.dwLowDateTime;
+    // convert to time in usec since Jan 1 1970
+    ptv->tv_usec = (long) ((nsTime / 10LL) % 1000000LL);
+    ptv->tv_sec = (long) ((nsTime - 116444736000000000LL) / 10000000LL);
+
+    return 0;
+}
+#endif
+
+#if defined(NEED_USLEEP)
+//
+// Replacement usleep for Windows environments (primarily MinGW).
+//
+void usleep(unsigned long usec)
+{
+    // Win32 API function Sleep() takes milliseconds
+    ::Sleep((usec + 500) / 1000);
+}
+#endif
+
+#if 0 //defined(NEED_PIPE)
+//
+// Replacement pipe() command for MinGW
+//
+// The _O_NOINHERIT flag sets bInheritHandle to FALSE in the
+// SecurityAttributes argument to CreatePipe().  This means the handles
+// aren't inherited when a new process is created.  The examples I've seen
+// use it, possibly because there's a lot of junk going on behind the
+// scenes.  (I'm assuming "process" and "thread" are different here, so
+// we should be okay spinning up a thread.)  The recommended practice is
+// to dup() the descriptor you want the child to have.
+//
+// It appears that unnamed pipes can't do non-blocking ("overlapped") I/O.
+// You can't use select() either, since that only works on sockets.  The
+// Windows API calls that are useful here all operate on a HANDLE, not
+// an integer file descriptor, and I don't think you can get there from
+// here.  The "named pipe" stuff is insane.
+//
+int pipe(int filedes[2])
+{
+    return _pipe(filedes, 0, _O_BINARY | _O_NOINHERIT);
+}
+#endif
+
+#if defined(NEED_SETENV)
+/*
+ * MinGW lacks these.  For now, just stub them out so the code compiles.
+ */
+int setenv(const char* name, const char* value, int overwrite)
+{
+    return 0;
+}
+void unsetenv(const char* name)
+{
+}
+char* getenv(const char* name)
+{
+    return NULL;
+}
+#endif
diff --git a/opengl/libGLES_CM/Android.mk b/opengl/libGLES_CM/Android.mk
new file mode 100644
index 0000000..a0081ef
--- /dev/null
+++ b/opengl/libGLES_CM/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# Build the wrapper OpenGL ES library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= gl_wrapper.cpp.arm gl_logger.cpp
+
+LOCAL_SHARED_LIBRARIES += libcutils libutils libui
+LOCAL_LDLIBS := -lpthread -ldl
+LOCAL_MODULE:= libGLES_CM
+
+# needed on sim build because of weird logging issues
+ifeq ($(TARGET_SIMULATOR),true)
+else
+	LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/opengl/libGLES_CM/egl_entries.cpp b/opengl/libGLES_CM/egl_entries.cpp
new file mode 100644
index 0000000..ba46f40
--- /dev/null
+++ b/opengl/libGLES_CM/egl_entries.cpp
@@ -0,0 +1,46 @@
+EGL_ENTRY(EGLDisplay, eglGetDisplay, NativeDisplayType)
+EGL_ENTRY(EGLBoolean, eglInitialize, EGLDisplay, EGLint*, EGLint*)
+EGL_ENTRY(EGLBoolean, eglTerminate, EGLDisplay)
+EGL_ENTRY(EGLBoolean, eglGetConfigs, EGLDisplay, EGLConfig*, EGLint, EGLint*)
+EGL_ENTRY(EGLBoolean, eglChooseConfig, EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)
+
+EGL_ENTRY(EGLBoolean, eglGetConfigAttrib, EGLDisplay, EGLConfig, EGLint, EGLint *)
+EGL_ENTRY(EGLSurface, eglCreateWindowSurface, EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)
+EGL_ENTRY(EGLSurface, eglCreatePixmapSurface, EGLDisplay, EGLConfig, NativePixmapType, const EGLint *)
+EGL_ENTRY(EGLSurface, eglCreatePbufferSurface,  EGLDisplay, EGLConfig, const EGLint *)
+EGL_ENTRY(EGLBoolean, eglDestroySurface, EGLDisplay, EGLSurface)
+EGL_ENTRY(EGLBoolean, eglQuerySurface,  EGLDisplay, EGLSurface, EGLint, EGLint *)
+EGL_ENTRY(EGLContext, eglCreateContext, EGLDisplay, EGLConfig, EGLContext, const EGLint *)
+EGL_ENTRY(EGLBoolean, eglDestroyContext, EGLDisplay, EGLContext)
+EGL_ENTRY(EGLBoolean, eglMakeCurrent, EGLDisplay, EGLSurface, EGLSurface, EGLContext)
+EGL_ENTRY(EGLContext, eglGetCurrentContext, void)
+EGL_ENTRY(EGLSurface, eglGetCurrentSurface, EGLint)
+EGL_ENTRY(EGLDisplay, eglGetCurrentDisplay, void)
+EGL_ENTRY(EGLBoolean, eglQueryContext,  EGLDisplay, EGLContext, EGLint, EGLint *)
+EGL_ENTRY(EGLBoolean, eglWaitGL, void)
+EGL_ENTRY(EGLBoolean, eglWaitNative, EGLint)
+EGL_ENTRY(EGLBoolean, eglSwapBuffers, EGLDisplay, EGLSurface)
+EGL_ENTRY(EGLBoolean, eglCopyBuffers, EGLDisplay, EGLSurface, NativePixmapType)
+EGL_ENTRY(EGLint, eglGetError, void)
+EGL_ENTRY(const char*, eglQueryString, EGLDisplay, EGLint)
+EGL_ENTRY(proc_t, eglGetProcAddress, const char *)
+
+/* EGL 1.1 */
+
+EGL_ENTRY(EGLBoolean, eglSurfaceAttrib, EGLDisplay, EGLSurface, EGLint, EGLint)
+EGL_ENTRY(EGLBoolean, eglBindTexImage, EGLDisplay, EGLSurface, EGLint)
+EGL_ENTRY(EGLBoolean, eglReleaseTexImage, EGLDisplay, EGLSurface, EGLint)
+EGL_ENTRY(EGLBoolean, eglSwapInterval, EGLDisplay, EGLint)
+
+/* EGL 1.2 */
+
+EGL_ENTRY(EGLBoolean, eglBindAPI, EGLenum)
+EGL_ENTRY(EGLenum, eglQueryAPI, void)
+EGL_ENTRY(EGLBoolean, eglWaitClient, void)
+EGL_ENTRY(EGLBoolean, eglReleaseThread, void)
+EGL_ENTRY(EGLSurface, eglCreatePbufferFromClientBuffer, EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const EGLint *)
+
+/* Android extentions */
+
+EGL_ENTRY(EGLBoolean, eglSwapRectangleANDROID, EGLDisplay, EGLSurface , EGLint, EGLint, EGLint, EGLint)
+EGL_ENTRY(const char*, eglQueryStringConfigANDROID, EGLDisplay, EGLConfig, EGLint)
diff --git a/opengl/libGLES_CM/enumextract.sh b/opengl/libGLES_CM/enumextract.sh
new file mode 100644
index 0000000..5707302
--- /dev/null
+++ b/opengl/libGLES_CM/enumextract.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+awk '
+/^#define GL_/ {
+    names[count] = $2;
+    values[count] = $3;
+    sort[count] = $3 + 0;
+    count++;
+}
+END {
+    for (i = 1; i < count; i++) {
+        for (j = 0; j < i; j++) {
+            if (sort[i] < sort[j]) {
+                tn = names[i];
+                tv = values[i];
+                ts = sort[i];
+                names[i] = names[j];
+                values[i] = values[j];
+                sort[i] = sort[j];
+                names[j] = tn;
+                values[j] = tv;
+                sort[j] = ts;
+            }
+        }
+    }
+ 
+    for (i = 0; i < count; i++) {
+        printf("GLENUM(%s, %s)\n", names[i], values[i]);
+    }
+}
+' < $1
+
diff --git a/opengl/libGLES_CM/gl_api.cpp b/opengl/libGLES_CM/gl_api.cpp
new file mode 100644
index 0000000..ed3bdaa
--- /dev/null
+++ b/opengl/libGLES_CM/gl_api.cpp
@@ -0,0 +1,606 @@
+void API_ENTRY(glActiveTexture)(GLenum texture) {
+    CALL_GL_API(glActiveTexture, texture);
+}
+
+void API_ENTRY(glAlphaFunc)(GLenum func, GLclampf ref) {
+    CALL_GL_API(glAlphaFunc, func, ref);
+}
+
+void API_ENTRY(glAlphaFuncx)(GLenum func, GLclampx ref) {
+    CALL_GL_API(glAlphaFuncx, func, ref);
+}
+
+void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
+    CALL_GL_API(glBindTexture, target, texture);
+}
+
+void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
+    CALL_GL_API(glBlendFunc, sfactor, dfactor);
+}
+
+void API_ENTRY(glClear)(GLbitfield mask) {
+    CALL_GL_API(glClear, mask);
+}
+
+void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+    CALL_GL_API(glClearColor, red, green, blue, alpha);
+}
+
+void API_ENTRY(glClearColorx)(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
+    CALL_GL_API(glClearColorx, red, green, blue, alpha);
+}
+
+void API_ENTRY(glClearDepthf)(GLclampf depth) {
+    CALL_GL_API(glClearDepthf, depth);
+}
+
+void API_ENTRY(glClearDepthx)(GLclampx depth) {
+    CALL_GL_API(glClearDepthx, depth);
+}
+
+void API_ENTRY(glClearStencil)(GLint s) {
+    CALL_GL_API(glClearStencil, s);
+}
+
+void API_ENTRY(glClientActiveTexture)(GLenum texture) {
+    CALL_GL_API(glClientActiveTexture, texture);
+}
+
+void API_ENTRY(glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
+    CALL_GL_API(glColor4f, red, green, blue, alpha);
+}
+
+void API_ENTRY(glColor4x)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
+    CALL_GL_API(glColor4x, red, green, blue, alpha);
+}
+
+void API_ENTRY(glColorMask)(GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
+    CALL_GL_API(glColorMask, r, g, b, a);
+}
+
+void API_ENTRY(glColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+    CALL_GL_API(glColorPointer, size, type, stride, ptr);
+}
+
+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 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) {
+    CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y,
+            width, height, border);
+}
+
+void API_ENTRY(glCopyTexSubImage2D)(   GLenum target, GLint level, GLint xoffset,
+                            GLint yoffset, GLint x, GLint y, GLsizei width,
+                            GLsizei height) {
+    CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y,
+            width, height);
+}
+
+void API_ENTRY(glCullFace)(GLenum mode) {
+    CALL_GL_API(glCullFace, mode);
+}
+
+void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint *textures) {
+    CALL_GL_API(glDeleteTextures, n, textures);
+}
+
+void API_ENTRY(glDepthFunc)(GLenum func) {
+    CALL_GL_API(glDepthFunc, func);
+}
+
+void API_ENTRY(glDepthMask)(GLboolean flag) {
+    CALL_GL_API(glDepthMask, flag);
+}
+
+void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) {
+    CALL_GL_API(glDepthRangef, zNear, zFar);
+}
+
+void API_ENTRY(glDepthRangex)(GLclampx zNear, GLclampx zFar) {
+    CALL_GL_API(glDepthRangex, zNear, zFar);
+}
+
+void API_ENTRY(glDisable)(GLenum cap) {
+    CALL_GL_API(glDisable, cap);
+}
+
+void API_ENTRY(glDisableClientState)(GLenum array) {
+    CALL_GL_API(glDisableClientState, array);
+}
+
+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 GLvoid *indices) {
+    CALL_GL_API(glDrawElements, mode, count, type, indices);
+}
+
+void API_ENTRY(glEnable)(GLenum cap) {
+    CALL_GL_API(glEnable, cap);
+}
+
+void API_ENTRY(glEnableClientState)(GLenum array) {
+    CALL_GL_API(glEnableClientState, array);
+}
+
+void API_ENTRY(glFinish)(void) {
+    CALL_GL_API(glFinish);
+}
+
+void API_ENTRY(glFlush)(void) {
+    CALL_GL_API(glFlush);
+}
+
+void API_ENTRY(glFogf)(GLenum pname, GLfloat param) {
+    CALL_GL_API(glFogf, pname, param);
+}
+
+void API_ENTRY(glFogfv)(GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glFogfv, pname, params);
+}
+
+void API_ENTRY(glFogx)(GLenum pname, GLfixed param) {
+    CALL_GL_API(glFogx, pname, param);
+}
+
+void API_ENTRY(glFogxv)(GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glFogxv, pname, params);
+}
+
+void API_ENTRY(glFrontFace)(GLenum mode) {
+    CALL_GL_API(glFrontFace, mode);
+}
+
+void API_ENTRY(glFrustumf)(GLfloat left, GLfloat right,
+                GLfloat bottom, GLfloat top,
+                GLfloat zNear, GLfloat zFar) {
+    CALL_GL_API(glFrustumf, left, right, bottom, top, zNear, zFar);
+}
+
+void API_ENTRY(glFrustumx)(GLfixed left, GLfixed right,
+                GLfixed bottom, GLfixed top,
+                GLfixed zNear, GLfixed zFar) {
+    CALL_GL_API(glFrustumx, left, right, bottom, top, zNear, zFar);
+}
+
+void API_ENTRY(glGenTextures)(GLsizei n, GLuint *textures) {
+    CALL_GL_API(glGenTextures, n, textures);
+}
+
+GLenum API_ENTRY(glGetError)(void) {
+    CALL_GL_API_RETURN(glGetError);
+}
+
+void API_ENTRY(glGetIntegerv)(GLenum pname, GLint *params) {
+    CALL_GL_API(glGetIntegerv, pname, params);
+}
+
+const GLubyte * API_ENTRY(glGetString)(GLenum name) {
+    CALL_GL_API_RETURN(glGetString, name);
+}
+
+void API_ENTRY(glHint)(GLenum target, GLenum mode) {
+    CALL_GL_API(glHint, target, mode);
+}
+
+void API_ENTRY(glLightModelf)(GLenum pname, GLfloat param) {
+    CALL_GL_API(glLightModelf, pname, param);
+}
+
+void API_ENTRY(glLightModelfv)(GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glLightModelfv, pname, params);
+}
+
+void API_ENTRY(glLightModelx)(GLenum pname, GLfixed param) {
+    CALL_GL_API(glLightModelx, pname, param);
+}
+
+void API_ENTRY(glLightModelxv)(GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glLightModelxv, pname, params);
+}
+
+void API_ENTRY(glLightf)(GLenum light, GLenum pname, GLfloat param) {
+    CALL_GL_API(glLightf, light, pname, param);
+}
+
+void API_ENTRY(glLightfv)(GLenum light, GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glLightfv, light, pname, params);
+}
+
+void API_ENTRY(glLightx)(GLenum light, GLenum pname, GLfixed param) {
+    CALL_GL_API(glLightx, light, pname, param);
+}
+
+void API_ENTRY(glLightxv)(GLenum light, GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glLightxv, light, pname, params);
+}
+
+void API_ENTRY(glLineWidth)(GLfloat width) {
+    CALL_GL_API(glLineWidth, width);
+}
+
+void API_ENTRY(glLineWidthx)(GLfixed width) {
+    CALL_GL_API(glLineWidthx, width);
+}
+
+void API_ENTRY(glLoadIdentity)(void) {
+    CALL_GL_API(glLoadIdentity);
+}
+
+void API_ENTRY(glLoadMatrixf)(const GLfloat *m) {
+    CALL_GL_API(glLoadMatrixf, m);
+}
+
+void API_ENTRY(glLoadMatrixx)(const GLfixed *m) {
+    CALL_GL_API(glLoadMatrixx, m);
+}
+
+void API_ENTRY(glLogicOp)(GLenum opcode) {
+    CALL_GL_API(glLogicOp, opcode);
+}
+
+void API_ENTRY(glMaterialf)(GLenum face, GLenum pname, GLfloat param) {
+    CALL_GL_API(glMaterialf, face, pname, param);
+}
+
+void API_ENTRY(glMaterialfv)(GLenum face, GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glMaterialfv, face, pname, params);
+}
+
+void API_ENTRY(glMaterialx)(GLenum face, GLenum pname, GLfixed param) {
+    CALL_GL_API(glMaterialx, face, pname, param);
+}
+
+void API_ENTRY(glMaterialxv)(GLenum face, GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glMaterialxv, face, pname, params);
+}
+
+void API_ENTRY(glMatrixMode)(GLenum mode) {
+    CALL_GL_API(glMatrixMode, mode);
+}
+
+void API_ENTRY(glMultMatrixf)(const GLfloat *m) {
+    CALL_GL_API(glMultMatrixf, m);
+}
+
+void API_ENTRY(glMultMatrixx)(const GLfixed *m) {
+    CALL_GL_API(glMultMatrixx, m);
+}
+
+void API_ENTRY(glMultiTexCoord4f)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
+    CALL_GL_API(glMultiTexCoord4f, target, s, t, r, q);
+}
+
+void API_ENTRY(glMultiTexCoord4x)(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
+    CALL_GL_API(glMultiTexCoord4x, target, s, t, r, q);
+}
+
+void API_ENTRY(glNormal3f)(GLfloat nx, GLfloat ny, GLfloat nz) {
+    CALL_GL_API(glNormal3f, nx, ny, nz);
+}
+
+void API_ENTRY(glNormal3x)(GLfixed nx, GLfixed ny, GLfixed nz) {
+    CALL_GL_API(glNormal3x, nx, ny, nz);
+}
+
+void API_ENTRY(glNormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) {
+    CALL_GL_API(glNormalPointer, type, stride, pointer);
+}
+
+void API_ENTRY(glOrthof)(  GLfloat left, GLfloat right,
+                GLfloat bottom, GLfloat top,
+                GLfloat zNear, GLfloat zFar) {
+    CALL_GL_API(glOrthof, left, right, bottom, top, zNear, zFar);
+}
+
+void API_ENTRY(glOrthox)(  GLfixed left, GLfixed right,
+                GLfixed bottom, GLfixed top,
+                GLfixed zNear, GLfixed zFar) {
+    CALL_GL_API(glOrthox, left, right, bottom, top, zNear, zFar);
+}
+
+void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
+    CALL_GL_API(glPixelStorei, pname, param);
+}
+
+void API_ENTRY(glPointSize)(GLfloat size) {
+    CALL_GL_API(glPointSize, size);
+}
+
+void API_ENTRY(glPointSizex)(GLfixed size) {
+    CALL_GL_API(glPointSizex, size);
+}
+
+void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
+    CALL_GL_API(glPolygonOffset, factor, units);
+}
+
+void API_ENTRY(glPolygonOffsetx)(GLfixed factor, GLfixed units) {
+    CALL_GL_API(glPolygonOffsetx, factor, units);
+}
+
+void API_ENTRY(glPopMatrix)(void) {
+    CALL_GL_API(glPopMatrix);
+}
+
+void API_ENTRY(glPushMatrix)(void) {
+    CALL_GL_API(glPushMatrix);
+}
+
+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(glRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
+    CALL_GL_API(glRotatef, angle, x, y, z);
+}
+
+void API_ENTRY(glRotatex)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
+    CALL_GL_API(glRotatex, angle, x, y, z);
+}
+
+void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) {
+    CALL_GL_API(glSampleCoverage, value, invert);
+}
+
+void API_ENTRY(glSampleCoveragex)(GLclampx value, GLboolean invert) {
+    CALL_GL_API(glSampleCoveragex, value, invert);
+}
+
+void API_ENTRY(glScalef)(GLfloat x, GLfloat y, GLfloat z) {
+    CALL_GL_API(glScalef, x, y, z);
+}
+
+void API_ENTRY(glScalex)(GLfixed x, GLfixed y, GLfixed z) {
+    CALL_GL_API(glScalex, x, y, z);
+}
+
+void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
+    CALL_GL_API(glScissor, x, y, width, height);
+}
+
+void API_ENTRY(glShadeModel)(GLenum mode) {
+    CALL_GL_API(glShadeModel, mode);
+}
+
+void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
+    CALL_GL_API(glStencilFunc, func, ref, mask);
+}
+
+void API_ENTRY(glStencilMask)(GLuint mask) {
+    CALL_GL_API(glStencilMask, mask);
+}
+
+void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
+    CALL_GL_API(glStencilOp, fail, zfail, zpass);
+}
+
+void API_ENTRY(glTexCoordPointer)( GLint size, GLenum type,
+                        GLsizei stride, const GLvoid *pointer) {
+    CALL_GL_API(glTexCoordPointer, size, type, stride, pointer);
+}
+
+void API_ENTRY(glTexEnvf)(GLenum target, GLenum pname, GLfloat param) {
+    CALL_GL_API(glTexEnvf, target, pname, param);
+}
+
+void API_ENTRY(glTexEnvfv)(GLenum target, GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glTexEnvfv, target, pname, params);
+}
+
+void API_ENTRY(glTexEnvx)(GLenum target, GLenum pname, GLfixed param) {
+    CALL_GL_API(glTexEnvx, target, pname, param);
+}
+
+void API_ENTRY(glTexEnvxv)(GLenum target, GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glTexEnvxv, target, pname, params);
+}
+
+void API_ENTRY(glTexImage2D)(  GLenum target, GLint level, GLenum 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) {
+    CALL_GL_API(glTexParameterf, target, pname, param);
+}
+
+void API_ENTRY(glTexParameterx)(GLenum target, GLenum pname, GLfixed param) {
+    CALL_GL_API(glTexParameterx, target, pname, param);
+}
+
+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(glTranslatef)(GLfloat x, GLfloat y, GLfloat z) {
+    CALL_GL_API(glTranslatef, x, y, z);
+}
+
+void API_ENTRY(glTranslatex)(GLfixed x, GLfixed y, GLfixed z) {
+    CALL_GL_API(glTranslatex, x, y, z);
+}
+
+void API_ENTRY(glVertexPointer)(   GLint size, GLenum type,
+                        GLsizei stride, const GLvoid *pointer) {
+    CALL_GL_API(glVertexPointer, size, type, stride, pointer);
+}
+
+void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
+    CALL_GL_API(glViewport, x, y, width, height);
+}
+
+// ES 1.1
+void API_ENTRY(glClipPlanef)(GLenum plane, const GLfloat *equation) {
+    CALL_GL_API(glClipPlanef, plane, equation);
+}
+void API_ENTRY(glClipPlanex)(GLenum plane, const GLfixed *equation) {
+    CALL_GL_API(glClipPlanex, plane, equation);
+}
+void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
+    CALL_GL_API(glBindBuffer, target, buffer);
+}
+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 GLvoid* data) {
+    CALL_GL_API(glBufferSubData, target, offset, size, data);
+}
+void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint* buffers) {
+    CALL_GL_API(glDeleteBuffers, n, buffers);
+}
+void API_ENTRY(glGenBuffers)(GLsizei n, GLuint* buffers) {
+    CALL_GL_API(glGenBuffers, n, buffers);
+}
+void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean *params) {
+    CALL_GL_API(glGetBooleanv, pname, params);
+}
+void API_ENTRY(glGetFixedv)(GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetFixedv, pname, params);
+}
+void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetFloatv, pname, params);
+}
+void API_ENTRY(glGetPointerv)(GLenum pname, void **params) {
+    CALL_GL_API(glGetPointerv, pname, params);
+}
+void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint *params) {
+    CALL_GL_API(glGetBufferParameteriv, target, pname, params);
+}
+void API_ENTRY(glGetClipPlanef)(GLenum pname, GLfloat eqn[4]) {
+    CALL_GL_API(glGetClipPlanef, pname, eqn);
+}
+void API_ENTRY(glGetClipPlanex)(GLenum pname, GLfixed eqn[4]) {
+    CALL_GL_API(glGetClipPlanex, pname, eqn);
+}
+void API_ENTRY(glGetLightxv)(GLenum light, GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetLightxv, light, pname, params);
+}
+void API_ENTRY(glGetLightfv)(GLenum light, GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetLightfv, light, pname, params);
+}
+void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetMaterialxv, face, pname, params);
+}
+void API_ENTRY(glGetMaterialfv)(GLenum face, GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetMaterialfv, face, pname, params);
+}
+void API_ENTRY(glGetTexEnvfv)(GLenum env, GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetTexEnvfv, env, pname, params);
+}
+void API_ENTRY(glGetTexEnviv)(GLenum env, GLenum pname, GLint *params) {
+    CALL_GL_API(glGetTexEnviv, env, pname, params);
+}
+void API_ENTRY(glGetTexEnvxv)(GLenum env, GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetTexEnvxv, env, pname, params);
+}
+void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetTexParameterfv, target, pname, params);
+}
+void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint *params) {
+    CALL_GL_API(glGetTexParameteriv, target, pname, params);
+}
+void API_ENTRY(glGetTexParameterxv)(GLenum target, GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetTexParameterxv, target, pname, params);
+}
+GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) {
+    CALL_GL_API_RETURN(glIsBuffer, buffer);
+}
+GLboolean API_ENTRY(glIsEnabled)(GLenum cap) {
+    CALL_GL_API_RETURN(glIsEnabled, cap);
+}
+GLboolean API_ENTRY(glIsTexture)(GLuint texture) {
+    CALL_GL_API_RETURN(glIsTexture, texture);
+}
+void API_ENTRY(glPointParameterf)(GLenum pname, GLfloat param) {
+    CALL_GL_API(glPointParameterf, pname, param);
+}
+void API_ENTRY(glPointParameterfv)(GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glPointParameterfv, pname, params);
+}
+void API_ENTRY(glPointParameterx)(GLenum pname, GLfixed param) {
+    CALL_GL_API(glPointParameterx, pname, param);
+}
+void API_ENTRY(glPointParameterxv)(GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glPointParameterxv, pname, params);
+}
+void API_ENTRY(glColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
+    CALL_GL_API(glColor4ub, red, green, blue, alpha);
+}
+void API_ENTRY(glTexEnvi)(GLenum target, GLenum pname, GLint param) {
+    CALL_GL_API(glTexEnvi, target, pname, param);
+}
+void API_ENTRY(glTexEnviv)(GLenum target, GLenum pname, const GLint *params) {
+    CALL_GL_API(glTexEnviv, target, pname, params);
+}
+
+void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glTexParameterfv, target, pname, params);
+}
+
+void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) {
+    CALL_GL_API(glTexParameteriv, target, pname, params);
+}
+
+void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) {
+    CALL_GL_API(glTexParameteri, target, pname, param);
+}
+void API_ENTRY(glTexParameterxv)(GLenum target, GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glTexParameterxv, target, pname, params);
+}
+void API_ENTRY(glPointSizePointerOES)(GLenum type, GLsizei stride, const GLvoid *pointer) {
+    CALL_GL_API(glPointSizePointerOES, type, stride, pointer);
+}
+
+// Extensions
+void API_ENTRY(glDrawTexsOES)(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) {
+    CALL_GL_API(glDrawTexsOES, x, y, z, w, h);
+}
+void API_ENTRY(glDrawTexiOES)(GLint x, GLint y, GLint z, GLint w, GLint h) {
+    CALL_GL_API(glDrawTexiOES, x, y, z, w, h);
+}
+void API_ENTRY(glDrawTexfOES)(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h) {
+    CALL_GL_API(glDrawTexfOES, x, y, z, w, h);
+}
+void API_ENTRY(glDrawTexxOES)(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) {
+    CALL_GL_API(glDrawTexxOES, x, y, z, w, h);
+}
+void API_ENTRY(glDrawTexsvOES)(const GLshort* coords) {
+    CALL_GL_API(glDrawTexsvOES, coords);
+}
+void API_ENTRY(glDrawTexivOES)(const GLint* coords) {
+    CALL_GL_API(glDrawTexivOES, coords);
+}
+void API_ENTRY(glDrawTexfvOES)(const GLfloat* coords) {
+    CALL_GL_API(glDrawTexfvOES, coords);
+}
+void API_ENTRY(glDrawTexxvOES)(const GLfixed* coords) {
+    CALL_GL_API(glDrawTexxvOES, coords);
+}
+GLbitfield API_ENTRY(glQueryMatrixxOES)(GLfixed* mantissa, GLint* exponent) {
+    CALL_GL_API_RETURN(glQueryMatrixxOES, mantissa, exponent);
+}
diff --git a/opengl/libGLES_CM/gl_entries.cpp b/opengl/libGLES_CM/gl_entries.cpp
new file mode 100644
index 0000000..3279322
--- /dev/null
+++ b/opengl/libGLES_CM/gl_entries.cpp
@@ -0,0 +1,159 @@
+GL_ENTRY(void, glColor4f, GLfloat, GLfloat, GLfloat, GLfloat)
+GL_ENTRY(void, glColor4x, GLfixed, GLfixed, GLfixed, GLfixed)
+GL_ENTRY(void, glNormal3f, GLfloat, GLfloat, GLfloat)
+GL_ENTRY(void, glNormal3x, GLfixed, GLfixed, GLfixed)
+GL_ENTRY(void, glCullFace, GLenum)
+GL_ENTRY(void, glFrontFace, GLenum)
+GL_ENTRY(void, glDisable, GLenum)
+GL_ENTRY(void, glEnable, GLenum)
+GL_ENTRY(void, glFinish, void)
+GL_ENTRY(void, glFlush, void)
+GL_ENTRY(GLenum, glGetError, void)
+GL_ENTRY(const GLubyte*, glGetString, GLenum)
+GL_ENTRY(void, glGetIntegerv, GLenum, GLint *)
+GL_ENTRY(void, glColorMask, GLboolean, GLboolean, GLboolean, GLboolean)
+GL_ENTRY(void, glDepthMask, GLboolean)
+GL_ENTRY(void, glStencilMask, GLuint)
+GL_ENTRY(void, glDepthFunc, GLenum)
+GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar)
+GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar)
+GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units)
+GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units)
+GL_ENTRY(void, glLogicOp, GLenum opcode)
+GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref)
+GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref)
+GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
+GL_ENTRY(void, glClear, GLbitfield mask)
+GL_ENTRY(void, glClearColor, GLclampf r, GLclampf g, GLclampf b, GLclampf a)
+GL_ENTRY(void, glClearColorx, GLclampx r, GLclampx g, GLclampx b, GLclampx a)
+GL_ENTRY(void, glClearDepthf, GLclampf depth)
+GL_ENTRY(void, glClearDepthx, GLclampx depth)
+GL_ENTRY(void, glClearStencil, GLint s)
+GL_ENTRY(void, glPointSize, GLfloat)
+GL_ENTRY(void, glPointSizex, GLfixed)
+GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert)
+GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert)
+GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
+GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass)
+GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glHint, GLenum, GLenum mode)
+GL_ENTRY(void, glLineWidth, GLfloat width)
+GL_ENTRY(void, glLineWidthx, GLfixed width)
+GL_ENTRY(void, glShadeModel, GLenum)
+GL_ENTRY(void, glLightModelf, GLenum, GLfloat)
+GL_ENTRY(void, glLightModelfv, GLenum, const GLfloat *)
+GL_ENTRY(void, glLightModelx, GLenum, GLfixed)
+GL_ENTRY(void, glLightModelxv, GLenum, const GLfixed *)
+GL_ENTRY(void, glLightf, GLenum, GLenum, GLfloat)
+GL_ENTRY(void, glLightfv, GLenum, GLenum, const GLfloat *)
+GL_ENTRY(void, glLightx, GLenum, GLenum, GLfixed)
+GL_ENTRY(void, glLightxv, GLenum, GLenum, const GLfixed *)
+GL_ENTRY(void, glMaterialf, GLenum, GLenum, GLfloat)
+GL_ENTRY(void, glMaterialfv, GLenum, GLenum, const GLfloat *)
+GL_ENTRY(void, glMaterialx, GLenum, GLenum, GLfixed)
+GL_ENTRY(void, glMaterialxv, GLenum, GLenum, const GLfixed *)
+GL_ENTRY(void, glFogf, GLenum, GLfloat)
+GL_ENTRY(void, glFogfv, GLenum, const GLfloat *)
+GL_ENTRY(void, glFogx, GLenum, GLfixed)
+GL_ENTRY(void, glFogxv, GLenum, const GLfixed *)
+GL_ENTRY(void, glVertexPointer, GLint, GLenum, GLsizei, const GLvoid *)
+GL_ENTRY(void, glColorPointer, GLint, GLenum, GLsizei, const GLvoid *)
+GL_ENTRY(void, glNormalPointer, GLenum, GLsizei, const GLvoid *)
+GL_ENTRY(void, glTexCoordPointer, GLint, GLenum, GLsizei, const GLvoid *)
+GL_ENTRY(void, glEnableClientState, GLenum)
+GL_ENTRY(void, glDisableClientState, GLenum)
+GL_ENTRY(void, glClientActiveTexture, GLenum)
+GL_ENTRY(void, glDrawArrays, GLenum, GLint first, GLsizei)
+GL_ENTRY(void, glDrawElements, GLenum, GLsizei, GLenum, const GLvoid *)
+GL_ENTRY(void, glLoadIdentity, void)
+GL_ENTRY(void, glLoadMatrixf, const GLfloat*)
+GL_ENTRY(void, glLoadMatrixx, const GLfixed*)
+GL_ENTRY(void, glMatrixMode, GLenum mode)
+GL_ENTRY(void, glMultMatrixf, const GLfloat*)
+GL_ENTRY(void, glMultMatrixx, const GLfixed*)
+GL_ENTRY(void, glPopMatrix, void)
+GL_ENTRY(void, glPushMatrix, void)
+GL_ENTRY(void, glFrustumf, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)
+GL_ENTRY(void, glFrustumx, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)
+GL_ENTRY(void, glOrthof, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)
+GL_ENTRY(void, glOrthox, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)
+GL_ENTRY(void, glRotatef, GLfloat, GLfloat, GLfloat, GLfloat)
+GL_ENTRY(void, glRotatex, GLfixed, GLfixed, GLfixed, GLfixed)
+GL_ENTRY(void, glScalef, GLfloat, GLfloat, GLfloat)
+GL_ENTRY(void, glScalex, GLfixed, GLfixed, GLfixed)
+GL_ENTRY(void, glTranslatef, GLfloat, GLfloat, GLfloat)
+GL_ENTRY(void, glTranslatex, GLfixed, GLfixed, GLfixed)
+GL_ENTRY(void, glViewport, GLint, GLint, GLsizei, GLsizei)
+GL_ENTRY(void, glActiveTexture, GLenum)
+GL_ENTRY(void, glBindTexture, GLenum, GLuint)
+GL_ENTRY(void, glGenTextures, GLsizei, GLuint*)
+GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *)
+GL_ENTRY(void, glMultiTexCoord4f, GLenum, GLfloat, GLfloat, GLfloat, GLfloat)
+GL_ENTRY(void, glMultiTexCoord4x, GLenum, GLfixed, GLfixed, GLfixed, GLfixed)
+GL_ENTRY(void, glPixelStorei, GLenum, GLint)
+GL_ENTRY(void, glTexEnvf, GLenum, GLenum, GLfloat)
+GL_ENTRY(void, glTexEnvfv, GLenum, GLenum, const GLfloat*)
+GL_ENTRY(void, glTexEnvx, GLenum, GLenum, GLfixed)
+GL_ENTRY(void, glTexEnvxv, GLenum, GLenum, const GLfixed*)
+GL_ENTRY(void, glTexParameterf, GLenum, GLenum, GLfloat)
+GL_ENTRY(void, glTexParameterx, GLenum, GLenum, GLfixed)
+GL_ENTRY(void, glCompressedTexImage2D,    GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)
+GL_ENTRY(void, glCompressedTexSubImage2D, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)
+GL_ENTRY(void, glCopyTexImage2D, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)
+GL_ENTRY(void, glCopyTexSubImage2D, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)
+GL_ENTRY(void, glTexImage2D, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)
+GL_ENTRY(void, glTexSubImage2D, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)
+GL_ENTRY(void, glReadPixels, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *)
+
+// 1.1 additions
+GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat*)
+GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed*)
+GL_ENTRY(void, glBindBuffer, GLenum, GLuint)
+GL_ENTRY(void, glBufferData, GLenum, GLsizeiptr, const GLvoid*, GLenum)
+GL_ENTRY(void, glBufferSubData, GLenum, GLintptr, GLsizeiptr, const GLvoid*)
+GL_ENTRY(void, glDeleteBuffers, GLsizei, const GLuint*)
+GL_ENTRY(void, glGenBuffers, GLsizei, GLuint*)
+GL_ENTRY(void, glGetBooleanv, GLenum, GLboolean *)
+GL_ENTRY(void, glGetFixedv, GLenum, GLfixed *)
+GL_ENTRY(void, glGetFloatv, GLenum, GLfloat *)
+GL_ENTRY(void, glGetPointerv, GLenum, void **)
+GL_ENTRY(void, glGetBufferParameteriv, GLenum, GLenum, GLint *)
+GL_ENTRY(void, glGetClipPlanef, GLenum, GLfloat[4])
+GL_ENTRY(void, glGetClipPlanex, GLenum, GLfixed[4])
+GL_ENTRY(void, glGetLightxv, GLenum, GLenum, GLfixed *)
+GL_ENTRY(void, glGetLightfv, GLenum, GLenum, GLfloat *)
+GL_ENTRY(void, glGetMaterialxv, GLenum, GLenum, GLfixed *)
+GL_ENTRY(void, glGetMaterialfv, GLenum, GLenum, GLfloat *)
+GL_ENTRY(void, glGetTexEnvfv, GLenum, GLenum, GLfloat *)
+GL_ENTRY(void, glGetTexEnviv, GLenum, GLenum, GLint *)
+GL_ENTRY(void, glGetTexEnvxv, GLenum, GLenum, GLfixed *)
+GL_ENTRY(void, glGetTexParameterfv, GLenum, GLenum, GLfloat *)
+GL_ENTRY(void, glGetTexParameteriv, GLenum, GLenum, GLint *)
+GL_ENTRY(void, glGetTexParameterxv, GLenum, GLenum, GLfixed *)
+GL_ENTRY(GLboolean, glIsBuffer, GLuint)
+GL_ENTRY(GLboolean, glIsEnabled, GLenum)
+GL_ENTRY(GLboolean, glIsTexture, GLuint)
+GL_ENTRY(void, glPointParameterf, GLenum, GLfloat)
+GL_ENTRY(void, glPointParameterfv, GLenum, const GLfloat *)
+GL_ENTRY(void, glPointParameterx, GLenum, GLfixed)
+GL_ENTRY(void, glPointParameterxv, GLenum, const GLfixed *)
+GL_ENTRY(void, glColor4ub, GLubyte, GLubyte, GLubyte, GLubyte)
+GL_ENTRY(void, glTexEnvi, GLenum, GLenum, GLint)
+GL_ENTRY(void, glTexEnviv, GLenum, GLenum, const GLint *)
+GL_ENTRY(void, glTexParameterfv, GLenum, GLenum, const GLfloat *)
+GL_ENTRY(void, glTexParameteriv, GLenum, GLenum, const GLint *)
+GL_ENTRY(void, glTexParameteri, GLenum, GLenum, GLint)
+GL_ENTRY(void, glTexParameterxv, GLenum, GLenum, const GLfixed *)
+GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid*)
+
+// Extensions
+GL_ENTRY(void, glDrawTexsOES, GLshort, GLshort, GLshort, GLshort, GLshort)
+GL_ENTRY(void, glDrawTexiOES, GLint, GLint, GLint, GLint, GLint)
+GL_ENTRY(void, glDrawTexfOES, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)
+GL_ENTRY(void, glDrawTexxOES, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)
+GL_ENTRY(void, glDrawTexsvOES, const GLshort*)
+GL_ENTRY(void, glDrawTexivOES, const GLint*)
+GL_ENTRY(void, glDrawTexfvOES, const GLfloat*)
+GL_ENTRY(void, glDrawTexxvOES, const GLfixed*)
+GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed* mantissa, GLint* exponent)
+
diff --git a/opengl/libGLES_CM/gl_enums.in b/opengl/libGLES_CM/gl_enums.in
new file mode 100644
index 0000000..ffc2fad
--- /dev/null
+++ b/opengl/libGLES_CM/gl_enums.in
@@ -0,0 +1,261 @@
+GLENUM(GL_POINTS, 0x0000)
+GLENUM(GL_LINES, 0x0001)
+GLENUM(GL_LINE_LOOP, 0x0002)
+GLENUM(GL_LINE_STRIP, 0x0003)
+GLENUM(GL_TRIANGLES, 0x0004)
+GLENUM(GL_TRIANGLE_STRIP, 0x0005)
+GLENUM(GL_TRIANGLE_FAN, 0x0006)
+GLENUM(GL_ADD, 0x0104)
+GLENUM(GL_NEVER, 0x0200)
+GLENUM(GL_LESS, 0x0201)
+GLENUM(GL_EQUAL, 0x0202)
+GLENUM(GL_LEQUAL, 0x0203)
+GLENUM(GL_GREATER, 0x0204)
+GLENUM(GL_NOTEQUAL, 0x0205)
+GLENUM(GL_GEQUAL, 0x0206)
+GLENUM(GL_ALWAYS, 0x0207)
+GLENUM(GL_SRC_COLOR, 0x0300)
+GLENUM(GL_ONE_MINUS_SRC_COLOR, 0x0301)
+GLENUM(GL_SRC_ALPHA, 0x0302)
+GLENUM(GL_ONE_MINUS_SRC_ALPHA, 0x0303)
+GLENUM(GL_DST_ALPHA, 0x0304)
+GLENUM(GL_ONE_MINUS_DST_ALPHA, 0x0305)
+GLENUM(GL_DST_COLOR, 0x0306)
+GLENUM(GL_ONE_MINUS_DST_COLOR, 0x0307)
+GLENUM(GL_SRC_ALPHA_SATURATE, 0x0308)
+GLENUM(GL_FRONT, 0x0404)
+GLENUM(GL_BACK, 0x0405)
+GLENUM(GL_FRONT_AND_BACK, 0x0408)
+GLENUM(GL_INVALID_ENUM, 0x0500)
+GLENUM(GL_INVALID_VALUE, 0x0501)
+GLENUM(GL_INVALID_OPERATION, 0x0502)
+GLENUM(GL_STACK_OVERFLOW, 0x0503)
+GLENUM(GL_STACK_UNDERFLOW, 0x0504)
+GLENUM(GL_OUT_OF_MEMORY, 0x0505)
+GLENUM(GL_EXP, 0x0800)
+GLENUM(GL_EXP2, 0x0801)
+GLENUM(GL_CW, 0x0900)
+GLENUM(GL_CCW, 0x0901)
+GLENUM(GL_POINT_SMOOTH, 0x0B10)
+GLENUM(GL_SMOOTH_POINT_SIZE_RANGE, 0x0B12)
+GLENUM(GL_LINE_SMOOTH, 0x0B20)
+GLENUM(GL_SMOOTH_LINE_WIDTH_RANGE, 0x0B22)
+GLENUM(GL_CULL_FACE, 0x0B44)
+GLENUM(GL_LIGHTING, 0x0B50)
+GLENUM(GL_LIGHT_MODEL_TWO_SIDE, 0x0B52)
+GLENUM(GL_LIGHT_MODEL_AMBIENT, 0x0B53)
+GLENUM(GL_COLOR_MATERIAL, 0x0B57)
+GLENUM(GL_FOG, 0x0B60)
+GLENUM(GL_FOG_DENSITY, 0x0B62)
+GLENUM(GL_FOG_START, 0x0B63)
+GLENUM(GL_FOG_END, 0x0B64)
+GLENUM(GL_FOG_MODE, 0x0B65)
+GLENUM(GL_FOG_COLOR, 0x0B66)
+GLENUM(GL_DEPTH_TEST, 0x0B71)
+GLENUM(GL_STENCIL_TEST, 0x0B90)
+GLENUM(GL_NORMALIZE, 0x0BA1)
+GLENUM(GL_ALPHA_TEST, 0x0BC0)
+GLENUM(GL_DITHER, 0x0BD0)
+GLENUM(GL_BLEND, 0x0BE2)
+GLENUM(GL_COLOR_LOGIC_OP, 0x0BF2)
+GLENUM(GL_SCISSOR_TEST, 0x0C11)
+GLENUM(GL_PERSPECTIVE_CORRECTION_HINT, 0x0C50)
+GLENUM(GL_POINT_SMOOTH_HINT, 0x0C51)
+GLENUM(GL_LINE_SMOOTH_HINT, 0x0C52)
+GLENUM(GL_POLYGON_SMOOTH_HINT, 0x0C53)
+GLENUM(GL_FOG_HINT, 0x0C54)
+GLENUM(GL_UNPACK_ALIGNMENT, 0x0CF5)
+GLENUM(GL_PACK_ALIGNMENT, 0x0D05)
+GLENUM(GL_MAX_LIGHTS, 0x0D31)
+GLENUM(GL_MAX_CLIP_PLANES, 0x0D32)
+GLENUM(GL_MAX_TEXTURE_SIZE, 0x0D33)
+GLENUM(GL_MAX_MODELVIEW_STACK_DEPTH, 0x0D36)
+GLENUM(GL_MAX_PROJECTION_STACK_DEPTH, 0x0D38)
+GLENUM(GL_MAX_TEXTURE_STACK_DEPTH, 0x0D39)
+GLENUM(GL_MAX_VIEWPORT_DIMS, 0x0D3A)
+GLENUM(GL_RED_BITS, 0x0D52)
+GLENUM(GL_GREEN_BITS, 0x0D53)
+GLENUM(GL_BLUE_BITS, 0x0D54)
+GLENUM(GL_ALPHA_BITS, 0x0D55)
+GLENUM(GL_DEPTH_BITS, 0x0D56)
+GLENUM(GL_STENCIL_BITS, 0x0D57)
+GLENUM(GL_TEXTURE_2D, 0x0DE1)
+GLENUM(GL_DONT_CARE, 0x1100)
+GLENUM(GL_FASTEST, 0x1101)
+GLENUM(GL_NICEST, 0x1102)
+GLENUM(GL_AMBIENT, 0x1200)
+GLENUM(GL_DIFFUSE, 0x1201)
+GLENUM(GL_SPECULAR, 0x1202)
+GLENUM(GL_POSITION, 0x1203)
+GLENUM(GL_SPOT_DIRECTION, 0x1204)
+GLENUM(GL_SPOT_EXPONENT, 0x1205)
+GLENUM(GL_SPOT_CUTOFF, 0x1206)
+GLENUM(GL_CONSTANT_ATTENUATION, 0x1207)
+GLENUM(GL_LINEAR_ATTENUATION, 0x1208)
+GLENUM(GL_QUADRATIC_ATTENUATION, 0x1209)
+GLENUM(GL_BYTE, 0x1400)
+GLENUM(GL_UNSIGNED_BYTE, 0x1401)
+GLENUM(GL_SHORT, 0x1402)
+GLENUM(GL_UNSIGNED_SHORT, 0x1403)
+GLENUM(GL_FLOAT, 0x1406)
+GLENUM(GL_FIXED, 0x140C)
+GLENUM(GL_CLEAR, 0x1500)
+GLENUM(GL_AND, 0x1501)
+GLENUM(GL_AND_REVERSE, 0x1502)
+GLENUM(GL_COPY, 0x1503)
+GLENUM(GL_AND_INVERTED, 0x1504)
+GLENUM(GL_NOOP, 0x1505)
+GLENUM(GL_XOR, 0x1506)
+GLENUM(GL_OR, 0x1507)
+GLENUM(GL_NOR, 0x1508)
+GLENUM(GL_EQUIV, 0x1509)
+GLENUM(GL_INVERT, 0x150A)
+GLENUM(GL_OR_REVERSE, 0x150B)
+GLENUM(GL_COPY_INVERTED, 0x150C)
+GLENUM(GL_OR_INVERTED, 0x150D)
+GLENUM(GL_NAND, 0x150E)
+GLENUM(GL_SET, 0x150F)
+GLENUM(GL_EMISSION, 0x1600)
+GLENUM(GL_SHININESS, 0x1601)
+GLENUM(GL_AMBIENT_AND_DIFFUSE, 0x1602)
+GLENUM(GL_MODELVIEW, 0x1700)
+GLENUM(GL_PROJECTION, 0x1701)
+GLENUM(GL_TEXTURE, 0x1702)
+GLENUM(GL_ALPHA, 0x1906)
+GLENUM(GL_RGB, 0x1907)
+GLENUM(GL_RGBA, 0x1908)
+GLENUM(GL_LUMINANCE, 0x1909)
+GLENUM(GL_LUMINANCE_ALPHA, 0x190A)
+GLENUM(GL_FLAT, 0x1D00)
+GLENUM(GL_SMOOTH, 0x1D01)
+GLENUM(GL_KEEP, 0x1E00)
+GLENUM(GL_REPLACE, 0x1E01)
+GLENUM(GL_REPLACE, 0x1E01)
+GLENUM(GL_INCR, 0x1E02)
+GLENUM(GL_DECR, 0x1E03)
+GLENUM(GL_VENDOR, 0x1F00)
+GLENUM(GL_RENDERER, 0x1F01)
+GLENUM(GL_VERSION, 0x1F02)
+GLENUM(GL_EXTENSIONS, 0x1F03)
+GLENUM(GL_MODULATE, 0x2100)
+GLENUM(GL_DECAL, 0x2101)
+GLENUM(GL_TEXTURE_ENV_MODE, 0x2200)
+GLENUM(GL_TEXTURE_ENV_COLOR, 0x2201)
+GLENUM(GL_TEXTURE_ENV, 0x2300)
+GLENUM(GL_NEAREST, 0x2600)
+GLENUM(GL_LINEAR, 0x2601)
+GLENUM(GL_NEAREST_MIPMAP_NEAREST, 0x2700)
+GLENUM(GL_LINEAR_MIPMAP_NEAREST, 0x2701)
+GLENUM(GL_NEAREST_MIPMAP_LINEAR, 0x2702)
+GLENUM(GL_LINEAR_MIPMAP_LINEAR, 0x2703)
+GLENUM(GL_TEXTURE_MAG_FILTER, 0x2800)
+GLENUM(GL_TEXTURE_MIN_FILTER, 0x2801)
+GLENUM(GL_TEXTURE_WRAP_S, 0x2802)
+GLENUM(GL_TEXTURE_WRAP_T, 0x2803)
+GLENUM(GL_CLAMP, 0x2900)
+GLENUM(GL_REPEAT, 0x2901)
+GLENUM(GL_CLIP_PLANE0, 0x3000)
+GLENUM(GL_CLIP_PLANE1, 0x3001)
+GLENUM(GL_CLIP_PLANE2, 0x3002)
+GLENUM(GL_CLIP_PLANE3, 0x3003)
+GLENUM(GL_CLIP_PLANE4, 0x3004)
+GLENUM(GL_CLIP_PLANE5, 0x3005)
+GLENUM(GL_LIGHT0, 0x4000)
+GLENUM(GL_LIGHT1, 0x4001)
+GLENUM(GL_LIGHT2, 0x4002)
+GLENUM(GL_LIGHT3, 0x4003)
+GLENUM(GL_LIGHT4, 0x4004)
+GLENUM(GL_LIGHT5, 0x4005)
+GLENUM(GL_LIGHT6, 0x4006)
+GLENUM(GL_LIGHT7, 0x4007)
+GLENUM(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0x7E80)
+GLENUM(GL_UNSIGNED_SHORT_4_4_4_4, 0x8033)
+GLENUM(GL_UNSIGNED_SHORT_5_5_5_1, 0x8034)
+GLENUM(GL_POLYGON_OFFSET_FILL, 0x8037)
+GLENUM(GL_RESCALE_NORMAL, 0x803A)
+GLENUM(GL_VERTEX_ARRAY, 0x8074)
+GLENUM(GL_NORMAL_ARRAY, 0x8075)
+GLENUM(GL_COLOR_ARRAY, 0x8076)
+GLENUM(GL_TEXTURE_COORD_ARRAY, 0x8078)
+GLENUM(GL_MULTISAMPLE, 0x809D)
+GLENUM(GL_SAMPLE_ALPHA_TO_COVERAGE, 0x809E)
+GLENUM(GL_SAMPLE_ALPHA_TO_ONE, 0x809F)
+GLENUM(GL_SAMPLE_COVERAGE, 0x80A0)
+GLENUM(GL_MAX_ELEMENTS_VERTICES, 0x80E8)
+GLENUM(GL_MAX_ELEMENTS_INDICES, 0x80E9)
+GLENUM(GL_CLAMP_TO_EDGE, 0x812F)
+GLENUM(GL_GENERATE_MIPMAP, 0x8191)
+GLENUM(GL_GENERATE_MIPMAP_HINT, 0x8192)
+GLENUM(GL_UNSIGNED_SHORT_5_6_5, 0x8363)
+GLENUM(GL_ALIASED_POINT_SIZE_RANGE, 0x846D)
+GLENUM(GL_ALIASED_LINE_WIDTH_RANGE, 0x846E)
+GLENUM(GL_TEXTURE0, 0x84C0)
+GLENUM(GL_TEXTURE1, 0x84C1)
+GLENUM(GL_TEXTURE2, 0x84C2)
+GLENUM(GL_TEXTURE3, 0x84C3)
+GLENUM(GL_TEXTURE4, 0x84C4)
+GLENUM(GL_TEXTURE5, 0x84C5)
+GLENUM(GL_TEXTURE6, 0x84C6)
+GLENUM(GL_TEXTURE7, 0x84C7)
+GLENUM(GL_TEXTURE8, 0x84C8)
+GLENUM(GL_TEXTURE9, 0x84C9)
+GLENUM(GL_TEXTURE10, 0x84CA)
+GLENUM(GL_TEXTURE11, 0x84CB)
+GLENUM(GL_TEXTURE12, 0x84CC)
+GLENUM(GL_TEXTURE13, 0x84CD)
+GLENUM(GL_TEXTURE14, 0x84CE)
+GLENUM(GL_TEXTURE15, 0x84CF)
+GLENUM(GL_TEXTURE16, 0x84D0)
+GLENUM(GL_TEXTURE17, 0x84D1)
+GLENUM(GL_TEXTURE18, 0x84D2)
+GLENUM(GL_TEXTURE19, 0x84D3)
+GLENUM(GL_TEXTURE20, 0x84D4)
+GLENUM(GL_TEXTURE21, 0x84D5)
+GLENUM(GL_TEXTURE22, 0x84D6)
+GLENUM(GL_TEXTURE23, 0x84D7)
+GLENUM(GL_TEXTURE24, 0x84D8)
+GLENUM(GL_TEXTURE25, 0x84D9)
+GLENUM(GL_TEXTURE26, 0x84DA)
+GLENUM(GL_TEXTURE27, 0x84DB)
+GLENUM(GL_TEXTURE28, 0x84DC)
+GLENUM(GL_TEXTURE29, 0x84DD)
+GLENUM(GL_TEXTURE30, 0x84DE)
+GLENUM(GL_TEXTURE31, 0x84DF)
+GLENUM(GL_MAX_TEXTURE_UNITS, 0x84E2)
+GLENUM(GL_NUM_COMPRESSED_TEXTURE_FORMATS, 0x86A2)
+GLENUM(GL_COMPRESSED_TEXTURE_FORMATS, 0x86A3)
+GLENUM(GL_BUFFER_SIZE, 0x8764)
+GLENUM(GL_BUFFER_USAGE, 0x8765)
+GLENUM(GL_POINT_SPRITE_OES, 0x8861)
+GLENUM(GL_COORD_REPLACE_OES, 0x8862)
+GLENUM(GL_ARRAY_BUFFER, 0x8892)
+GLENUM(GL_ELEMENT_ARRAY_BUFFER, 0x8893)
+GLENUM(GL_ARRAY_BUFFER_BINDING, 0x8894)
+GLENUM(GL_ELEMENT_ARRAY_BUFFER_BINDING, 0x8895)
+GLENUM(GL_VERTEX_ARRAY_BUFFER_BINDING, 0x8896)
+GLENUM(GL_NORMAL_ARRAY_BUFFER_BINDING, 0x8897)
+GLENUM(GL_COLOR_ARRAY_BUFFER_BINDING, 0x8898)
+GLENUM(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, 0x889A)
+GLENUM(GL_STATIC_DRAW, 0x88E4)
+GLENUM(GL_DYNAMIC_DRAW, 0x88E8)
+GLENUM(GL_POINT_SIZE_ARRAY_TYPE_OES, 0x898A)
+GLENUM(GL_POINT_SIZE_ARRAY_STRIDE_OES, 0x898B)
+GLENUM(GL_POINT_SIZE_ARRAY_POINTER_OES, 0x898C)
+GLENUM(GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES, 0x898D)
+GLENUM(GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES, 0x898E)
+GLENUM(GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES, 0x898F)
+GLENUM(GL_PALETTE4_RGB8_OES, 0x8B90)
+GLENUM(GL_PALETTE4_RGBA8_OES, 0x8B91)
+GLENUM(GL_PALETTE4_R5_G6_B5_OES, 0x8B92)
+GLENUM(GL_PALETTE4_RGBA4_OES, 0x8B93)
+GLENUM(GL_PALETTE4_RGB5_A1_OES, 0x8B94)
+GLENUM(GL_PALETTE8_RGB8_OES, 0x8B95)
+GLENUM(GL_PALETTE8_RGBA8_OES, 0x8B96)
+GLENUM(GL_PALETTE8_R5_G6_B5_OES, 0x8B97)
+GLENUM(GL_PALETTE8_RGBA4_OES, 0x8B98)
+GLENUM(GL_PALETTE8_RGB5_A1_OES, 0x8B99)
+GLENUM(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, 0x8B9A)
+GLENUM(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, 0x8B9B)
+GLENUM(GL_POINT_SIZE_ARRAY_OES, 0x8B9C)
+GLENUM(GL_TEXTURE_CROP_RECT_OES, 0x8B9D)
+GLENUM(GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES, 0x8B9F)
diff --git a/opengl/libGLES_CM/gl_logger.cpp b/opengl/libGLES_CM/gl_logger.cpp
new file mode 100644
index 0000000..14b5a39
--- /dev/null
+++ b/opengl/libGLES_CM/gl_logger.cpp
@@ -0,0 +1,1059 @@
+/*
+ ** 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 "GLLogger"
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include <dlfcn.h>
+
+#include <sys/ioctl.h>
+
+#include <GLES/egl.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h>
+
+#include <utils/String8.h>
+
+#include "gl_logger.h"
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+#undef NELEM
+#define NELEM(x) (sizeof(x)/sizeof(*(x)))
+
+template<typename T>
+static int binarySearch(T const sortedArray[], int first, int last, EGLint key)
+{
+   while (first <= last) {
+       int mid = (first + last) / 2;
+       if (key > sortedArray[mid].key) {
+           first = mid + 1;
+       } else if (key < sortedArray[mid].key) {
+           last = mid - 1;
+       } else {
+           return mid;
+       }
+   }
+   return -1;
+}
+
+struct pair_t {
+    const char* name;
+    int         key;
+};
+
+static const pair_t gEnumMap[] = {
+    #define GLENUM(NAME, VALUE) { #NAME, VALUE },
+    #include "gl_enums.in"
+    #undef GLENUM
+};
+
+// ----------------------------------------------------------------------------
+
+template<typename TYPE>
+class GLLogValue {
+public:
+    GLLogValue(TYPE value) : mValue(value) { }
+    const TYPE& getValue() const { return mValue; }
+    String8 toString() const {
+        return convertToString(mValue);
+    }
+private:
+    const TYPE& mValue;
+    String8 convertToString(unsigned int v) const {
+        char buf[16];
+        snprintf(buf, 16, "%u", v);
+        return String8(buf);
+    }
+    String8 convertToString(unsigned long v) const {
+        char buf[16];
+        snprintf(buf, 16, "%lu", v);
+        return String8(buf);
+    }
+    String8 convertToString(int v) const {
+        char buf[16];
+        snprintf(buf, 16, "%d", v);
+        return String8(buf);
+    }
+    String8 convertToString(long v) const {
+        char buf[16];
+        snprintf(buf, 16, "%ld", v);
+        return String8(buf);
+    }
+    String8 convertToString(float v) const {
+        char buf[16];
+        snprintf(buf, 16, "%f", v);
+        return String8(buf);
+    }
+    String8 convertToString(void const* v) const {
+        char buf[16];
+        snprintf(buf, 16, "%p", v);
+        return String8(buf);
+    }
+};
+
+class GLLogEnum : public GLLogValue<GLenum> {
+public:
+    GLLogEnum(GLenum v) : GLLogValue<GLenum>(v) { }
+    String8 toString() const {
+        GLenum v = getValue();
+        int i = binarySearch<pair_t>(gEnumMap, 0, NELEM(gEnumMap)-1, v);
+        if (i >= 0) {
+            return String8(gEnumMap[i].name);
+        } else {
+            char buf[16];
+            snprintf(buf, 16, "0x%04x", v);
+            return String8(buf);
+        }
+    }
+};
+
+class GLLogClearBitfield : public GLLogValue<GLbitfield> {
+public:
+    GLLogClearBitfield(GLbitfield v) : GLLogValue<GLbitfield>(v) { }
+    String8 toString() const {
+        char buf[16];
+        snprintf(buf, 16, "0x%08x", getValue());
+        return String8(buf);
+    }
+};
+
+class GLLogBool : public GLLogValue<GLboolean> {
+public:
+    GLLogBool(GLboolean v) : GLLogValue<GLboolean>(v) { }
+    String8 toString() const {
+        GLboolean v = getValue();
+        if (v == GL_TRUE)   return String8("GL_TRUE");
+        if (v == GL_FALSE)  return String8("GL_FALSE");
+        return GLLogValue<GLboolean>::toString();
+    }
+};
+
+class GLLogFixed : public GLLogValue<GLfixed> {
+public:
+    GLLogFixed(GLfixed v) : GLLogValue<GLfixed>(v) { }
+    String8 toString() const {
+        char buf[16];
+        snprintf(buf, 16, "0x%08x", getValue());
+        return String8(buf);
+    }
+};
+
+
+template <typename TYPE>
+class GLLogBuffer : public GLLogValue<TYPE *> {
+public:
+    GLLogBuffer(TYPE* buffer, size_t count = -1)
+        : GLLogValue<TYPE*>(buffer)
+    { // output buffer
+    }
+    GLLogBuffer(TYPE const* buffer, size_t count = -1)
+    : GLLogValue<TYPE*>(const_cast<TYPE*>(buffer))
+    { // input buffer
+    }
+};
+
+class GLLog
+{
+public:
+    GLLog(const char* name) : mNumParams(0) {
+        mString.append(name);
+        mString.append("(");
+    }
+
+    ~GLLog() {
+        LOGD("%s);", mString.string());
+    }
+
+    GLLog& operator << (unsigned char v) {
+        return *this << GLLogValue<unsigned int>(v);
+    }
+    GLLog& operator << (short v) {
+        return *this << GLLogValue<unsigned int>(v);
+    }
+    GLLog& operator << (unsigned int v) {
+        return *this << GLLogValue<unsigned int>(v);
+    }
+    GLLog& operator << (int v) {
+        return *this << GLLogValue<int>(v);
+    }
+    GLLog& operator << (long v) {
+        return *this << GLLogValue<long>(v);
+    }
+    GLLog& operator << (unsigned long v) {
+        return *this << GLLogValue<unsigned long>(v);
+    }
+    GLLog& operator << (float v) {
+        return *this << GLLogValue<float>(v);
+    }
+    GLLog& operator << (const void* v) {
+        return *this << GLLogValue<const void* >(v);
+    }
+
+    template <typename TYPE>
+    GLLog& operator << (const TYPE& rhs) {
+        if (mNumParams > 0)
+            mString.append(", ");
+        mString.append(rhs.toString());
+        mNumParams++;
+        return *this;
+    }
+
+    const String8& string() const { return mString; }
+private:
+    GLLog(const GLLog&);
+
+    String8 mString;
+    int mNumParams;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+#define API_ENTRY(api)                      log_##api
+#define CALL_GL_API(_x, ...)
+#define CALL_GL_API_RETURN(_x, ...)         return(0);
+
+void API_ENTRY(glActiveTexture)(GLenum texture) {
+    CALL_GL_API(glActiveTexture, texture);
+    GLLog("glActiveTexture") << GLLogEnum(texture);
+}
+
+void API_ENTRY(glAlphaFunc)(GLenum func, GLclampf ref) {
+    CALL_GL_API(glAlphaFunc, func, ref);
+    GLLog("glAlphaFunc") << GLLogEnum(func) << ref;
+}
+
+void API_ENTRY(glAlphaFuncx)(GLenum func, GLclampx ref) {
+    CALL_GL_API(glAlphaFuncx, func, ref);
+    GLLog("glAlphaFuncx") << GLLogEnum(func) << GLLogFixed(ref);
+}
+
+void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
+    CALL_GL_API(glBindTexture, target, texture);
+    GLLog("glBindTexture") << GLLogEnum(target) << texture;
+}
+
+void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
+    CALL_GL_API(glBlendFunc, sfactor, dfactor);
+    GLLog("glBlendFunc") << GLLogEnum(sfactor) << GLLogEnum(dfactor);
+}
+
+void API_ENTRY(glClear)(GLbitfield mask) {
+    CALL_GL_API(glClear, mask);
+    GLLog("glClear") << GLLogClearBitfield(mask);
+}
+
+void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+    CALL_GL_API(glClearColor, red, green, blue, alpha);
+    GLLog("glClearColor") << red << green << blue << alpha;
+}
+
+void API_ENTRY(glClearColorx)(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
+    CALL_GL_API(glClearColorx, red, green, blue, alpha);
+    GLLog("glClearColorx") << GLLogFixed(red) << GLLogFixed(green) << GLLogFixed(blue) << GLLogFixed(alpha);
+}
+
+void API_ENTRY(glClearDepthf)(GLclampf depth) {
+    CALL_GL_API(glClearDepthf, depth);
+    GLLog("glClearDepthf") << depth;
+}
+
+void API_ENTRY(glClearDepthx)(GLclampx depth) {
+    CALL_GL_API(glClearDepthx, depth);
+    GLLog("glClearDepthx") << GLLogFixed(depth);
+}
+
+void API_ENTRY(glClearStencil)(GLint s) {
+    CALL_GL_API(glClearStencil, s);
+    GLLog("glClearStencil") << s;
+}
+
+void API_ENTRY(glClientActiveTexture)(GLenum texture) {
+    CALL_GL_API(glClientActiveTexture, texture);
+    GLLog("glClientActiveTexture") << GLLogEnum(texture);
+}
+
+void API_ENTRY(glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
+    CALL_GL_API(glColor4f, red, green, blue, alpha);
+    GLLog("glColor4f") << red << green << blue << alpha;
+}
+
+void API_ENTRY(glColor4x)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
+    CALL_GL_API(glColor4x, red, green, blue, alpha);
+    GLLog("glColor4x") << GLLogFixed(red) << GLLogFixed(green) << GLLogFixed(blue) << GLLogFixed(alpha);
+}
+
+void API_ENTRY(glColorMask)(GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
+    CALL_GL_API(glColorMask, r, g, b, a);
+    GLLog("glColorMask") << GLLogBool(r) << GLLogBool(g) << GLLogBool(b) << GLLogBool(a);
+}
+
+void API_ENTRY(glColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+    CALL_GL_API(glColorPointer, size, type, stride, ptr);
+    GLLog("glColorPointer") << size << GLLogEnum(type) << stride << ptr;
+}
+
+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);
+    GLLog("glCompressedTexImage2D")
+                << GLLogEnum(target) << level << GLLogEnum(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 GLvoid *data) {
+    CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset,
+            width, height, format, imageSize, data);
+    GLLog("glCompressedTexSubImage2D")
+            << GLLogEnum(target) << level << xoffset << yoffset
+            << width << height << GLLogEnum(format) << imageSize << data;
+}
+
+void API_ENTRY(glCopyTexImage2D)(  GLenum target, GLint level, GLenum internalformat,
+                        GLint x, GLint y, GLsizei width, GLsizei height,
+                        GLint border) {
+    CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y,
+            width, height, border);
+    GLLog("glCopyTexImage2D")
+            << GLLogEnum(target) << level << GLLogEnum(internalformat)
+            << x << y << width << height << border;
+}
+
+void API_ENTRY(glCopyTexSubImage2D)(   GLenum target, GLint level, GLint xoffset,
+                            GLint yoffset, GLint x, GLint y, GLsizei width,
+                            GLsizei height) {
+    CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y,
+            width, height);
+    GLLog("glCopyTexSubImage2D")
+            << GLLogEnum(target) << level << xoffset << yoffset
+            << x << y << width << height;
+}
+
+void API_ENTRY(glCullFace)(GLenum mode) {
+    CALL_GL_API(glCullFace, mode);
+    GLLog("glCullFace") << GLLogEnum(mode);
+}
+
+void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint *textures) {
+    CALL_GL_API(glDeleteTextures, n, textures);
+    GLLog("glDeleteTextures") << n << GLLogBuffer<GLuint>(textures, n);
+}
+
+void API_ENTRY(glDepthFunc)(GLenum func) {
+    CALL_GL_API(glDepthFunc, func);
+    GLLog("glDepthFunc") << GLLogEnum(func);
+}
+
+void API_ENTRY(glDepthMask)(GLboolean flag) {
+    CALL_GL_API(glDepthMask, flag);
+    GLLog("glDepthMask") << GLLogBool(flag);
+}
+
+void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) {
+    CALL_GL_API(glDepthRangef, zNear, zFar);
+    GLLog("glDepthRangef") << zNear << zFar;
+}
+
+void API_ENTRY(glDepthRangex)(GLclampx zNear, GLclampx zFar) {
+    CALL_GL_API(glDepthRangex, zNear, zFar);
+    GLLog("glDepthRangex") << GLLogFixed(zNear) << GLLogFixed(zFar);
+}
+
+void API_ENTRY(glDisable)(GLenum cap) {
+    CALL_GL_API(glDisable, cap);
+    GLLog("glDisable") << GLLogEnum(cap);
+}
+
+void API_ENTRY(glDisableClientState)(GLenum array) {
+    CALL_GL_API(glDisableClientState, array);
+    GLLog("glDisableClientState") << GLLogEnum(array);
+}
+
+void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
+    CALL_GL_API(glDrawArrays, mode, first, count);
+    GLLog("glDrawArrays") << GLLogEnum(mode) << first << count;
+}
+
+void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count,
+                    GLenum type, const GLvoid *indices) {
+    CALL_GL_API(glDrawElements, mode, count, type, indices);
+    GLLog log("glDrawElements");
+    log << GLLogEnum(mode) << count << GLLogEnum(type);
+    if (type == GL_UNSIGNED_BYTE) {
+        log << GLLogBuffer<GLubyte>(static_cast<const GLubyte*>(indices), count);
+    } else {
+        log << GLLogBuffer<GLushort>(static_cast<const GLushort*>(indices), count);
+    }
+    log;
+}
+
+void API_ENTRY(glEnable)(GLenum cap) {
+    CALL_GL_API(glEnable, cap);
+    GLLog("glEnable") << GLLogEnum(cap);
+}
+
+void API_ENTRY(glEnableClientState)(GLenum array) {
+    CALL_GL_API(glEnableClientState, array);
+    GLLog("glEnableClientState") << GLLogEnum(array);
+}
+
+void API_ENTRY(glFinish)(void) {
+    CALL_GL_API(glFinish);
+    GLLog("glFinish");
+}
+
+void API_ENTRY(glFlush)(void) {
+    CALL_GL_API(glFlush);
+    GLLog("glFlush");
+}
+
+void API_ENTRY(glFogf)(GLenum pname, GLfloat param) {
+    CALL_GL_API(glFogf, pname, param);
+    GLLog("glFogf") << GLLogEnum(pname) << param;
+}
+
+void API_ENTRY(glFogfv)(GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glFogfv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glFogfv") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+
+void API_ENTRY(glFogx)(GLenum pname, GLfixed param) {
+    CALL_GL_API(glFogx, pname, param);
+    GLLog("glFogx") << GLLogEnum(pname) << GLLogFixed(param);
+}
+
+void API_ENTRY(glFogxv)(GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glFogxv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glFogfx") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+
+void API_ENTRY(glFrontFace)(GLenum mode) {
+    CALL_GL_API(glFrontFace, mode);
+    GLLog("glFrontFace") << GLLogEnum(mode);
+ }
+
+void API_ENTRY(glFrustumf)(GLfloat left, GLfloat right,
+                GLfloat bottom, GLfloat top,
+                GLfloat zNear, GLfloat zFar) {
+    CALL_GL_API(glFrustumf, left, right, bottom, top, zNear, zFar);
+    GLLog("glFrustumf") << left << right << bottom << top << zNear << zFar;
+}
+
+void API_ENTRY(glFrustumx)(GLfixed left, GLfixed right,
+                GLfixed bottom, GLfixed top,
+                GLfixed zNear, GLfixed zFar) {
+    CALL_GL_API(glFrustumx, left, right, bottom, top, zNear, zFar);
+    GLLog("glFrustumx")
+            << GLLogFixed(left) << GLLogFixed(right)
+            << GLLogFixed(bottom) << GLLogFixed(top)
+            << GLLogFixed(zNear) << GLLogFixed(zFar);
+}
+
+void API_ENTRY(glGenTextures)(GLsizei n, GLuint *textures) {
+    CALL_GL_API(glGenTextures, n, textures);
+    GLLog("glGenTextures") << n << GLLogBuffer<GLuint>(textures, n);
+}
+
+GLenum API_ENTRY(glGetError)(void) {
+    GLLog("glGetError");
+    CALL_GL_API_RETURN(glGetError);
+}
+
+void API_ENTRY(glGetIntegerv)(GLenum pname, GLint *params) {
+    CALL_GL_API(glGetIntegerv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetIntegerv") << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
+}
+
+const GLubyte * API_ENTRY(glGetString)(GLenum name) {
+    GLLog("glGetString") << GLLogEnum(name);
+    CALL_GL_API_RETURN(glGetString, name);
+}
+
+void API_ENTRY(glHint)(GLenum target, GLenum mode) {
+    CALL_GL_API(glHint, target, mode);
+    GLLog("GLenum") << GLLogEnum(target) << GLLogEnum(mode);
+}
+
+void API_ENTRY(glLightModelf)(GLenum pname, GLfloat param) {
+    CALL_GL_API(glLightModelf, pname, param);
+    GLLog("glLightModelf") << GLLogEnum(pname) << param;
+}
+
+void API_ENTRY(glLightModelfv)(GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glLightModelfv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glLightModelfv") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+
+void API_ENTRY(glLightModelx)(GLenum pname, GLfixed param) {
+    CALL_GL_API(glLightModelx, pname, param);
+    GLLog("glLightModelx") << GLLogEnum(pname) << GLLogFixed(param);
+}
+
+void API_ENTRY(glLightModelxv)(GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glLightModelxv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glLightModelxv") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+
+void API_ENTRY(glLightf)(GLenum light, GLenum pname, GLfloat param) {
+    CALL_GL_API(glLightf, light, pname, param);
+    GLLog("glLightf") << GLLogEnum(light) << GLLogEnum(pname) << param;
+}
+
+void API_ENTRY(glLightfv)(GLenum light, GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glLightfv, light, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glLightfv") << GLLogEnum(light) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+
+void API_ENTRY(glLightx)(GLenum light, GLenum pname, GLfixed param) {
+   CALL_GL_API(glLightx, light, pname, param);
+   GLLog("glLightx") << GLLogEnum(light) << GLLogEnum(pname) << GLLogFixed(param);
+}
+
+void API_ENTRY(glLightxv)(GLenum light, GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glLightxv, light, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glLightxv") << GLLogEnum(light) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+
+void API_ENTRY(glLineWidth)(GLfloat width) {
+    CALL_GL_API(glLineWidth, width);
+    GLLog("glLineWidth") << width;
+}
+
+void API_ENTRY(glLineWidthx)(GLfixed width) {
+    CALL_GL_API(glLineWidthx, width);
+    GLLog("glLineWidth") << GLLogFixed(width);
+}
+
+void API_ENTRY(glLoadIdentity)(void) {
+    CALL_GL_API(glLoadIdentity);
+    GLLog("glLoadIdentity");
+}
+
+void API_ENTRY(glLoadMatrixf)(const GLfloat *m) {
+    CALL_GL_API(glLoadMatrixf, m);
+    GLLog("glLoadMatrixf") << GLLogBuffer<GLfloat>(m, 16);
+}
+
+void API_ENTRY(glLoadMatrixx)(const GLfixed *m) {
+    CALL_GL_API(glLoadMatrixx, m);
+    GLLog("glLoadMatrixx") << GLLogBuffer<GLfixed>(m, 16);
+}
+
+void API_ENTRY(glLogicOp)(GLenum opcode) {
+    CALL_GL_API(glLogicOp, opcode);
+    GLLog("glLogicOp") << GLLogEnum(opcode);
+}
+
+void API_ENTRY(glMaterialf)(GLenum face, GLenum pname, GLfloat param) {
+    CALL_GL_API(glMaterialf, face, pname, param);
+    GLLog("glMaterialf") << GLLogEnum(face) << GLLogEnum(pname) << param;
+}
+
+void API_ENTRY(glMaterialfv)(GLenum face, GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glMaterialfv, face, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glMaterialfv") << GLLogEnum(face) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+
+void API_ENTRY(glMaterialx)(GLenum face, GLenum pname, GLfixed param) {
+    CALL_GL_API(glMaterialx, face, pname, param);
+    GLLog("glMaterialx") << GLLogEnum(face) << GLLogEnum(pname) << GLLogFixed(param);
+}
+
+void API_ENTRY(glMaterialxv)(GLenum face, GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glMaterialxv, face, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glMaterialxv") << GLLogEnum(face) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+
+void API_ENTRY(glMatrixMode)(GLenum mode) {
+    CALL_GL_API(glMatrixMode, mode);
+    GLLog("glMatrixMode") << GLLogEnum(mode);
+}
+
+void API_ENTRY(glMultMatrixf)(const GLfloat *m) {
+    CALL_GL_API(glMultMatrixf, m);
+    GLLog("glMultMatrixf") << GLLogBuffer<GLfloat>(m, 16);
+}
+
+void API_ENTRY(glMultMatrixx)(const GLfixed *m) {
+    CALL_GL_API(glMultMatrixx, m);
+    GLLog("glMultMatrixx") << GLLogBuffer<GLfixed>(m, 16);
+}
+
+void API_ENTRY(glMultiTexCoord4f)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
+    CALL_GL_API(glMultiTexCoord4f, target, s, t, r, q);
+    GLLog("glMultiTexCoord4f") << GLLogEnum(target) << s << t << r << q;
+}
+
+void API_ENTRY(glMultiTexCoord4x)(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
+    CALL_GL_API(glMultiTexCoord4x, target, s, t, r, q);
+    GLLog("glMultiTexCoord4x") << GLLogEnum(target)
+        << GLLogFixed(s) << GLLogFixed(t) << GLLogFixed(r) << GLLogFixed(q);
+}
+
+void API_ENTRY(glNormal3f)(GLfloat nx, GLfloat ny, GLfloat nz) {
+    CALL_GL_API(glNormal3f, nx, ny, nz);
+    GLLog("glNormal3f") << nx << ny << nz;
+}
+
+void API_ENTRY(glNormal3x)(GLfixed nx, GLfixed ny, GLfixed nz) {
+    CALL_GL_API(glNormal3x, nx, ny, nz);
+    GLLog("glNormal3x") << GLLogFixed(nx) << GLLogFixed(ny) << GLLogFixed(nz);
+}
+
+void API_ENTRY(glNormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) {
+    CALL_GL_API(glNormalPointer, type, stride, pointer);
+    GLLog("glNormalPointer") << GLLogEnum(type) << stride << pointer;
+}
+
+void API_ENTRY(glOrthof)(  GLfloat left, GLfloat right,
+                GLfloat bottom, GLfloat top,
+                GLfloat zNear, GLfloat zFar) {
+    CALL_GL_API(glOrthof, left, right, bottom, top, zNear, zFar);
+    GLLog("glOrthof") << left << right << bottom << top << zNear << zFar;
+}
+
+void API_ENTRY(glOrthox)(  GLfixed left, GLfixed right,
+                GLfixed bottom, GLfixed top,
+                GLfixed zNear, GLfixed zFar) {
+    CALL_GL_API(glOrthox, left, right, bottom, top, zNear, zFar);
+    GLLog("glOrthox") << GLLogFixed(left) << GLLogFixed(right)
+            << GLLogFixed(bottom) << GLLogFixed(top)
+            << GLLogFixed(zNear) << GLLogFixed(zFar);
+}
+
+void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
+    CALL_GL_API(glPixelStorei, pname, param);
+    GLLog("glPixelStorei") << GLLogEnum(pname) << param;
+}
+
+void API_ENTRY(glPointSize)(GLfloat size) {
+    CALL_GL_API(glPointSize, size);
+    GLLog("glPointSize") << size;
+}
+
+void API_ENTRY(glPointSizex)(GLfixed size) {
+    CALL_GL_API(glPointSizex, size);
+    GLLog("glPointSizex") << GLLogFixed(size);
+}
+
+void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
+    CALL_GL_API(glPolygonOffset, factor, units);
+    GLLog("glPolygonOffset") << factor << units;
+}
+
+void API_ENTRY(glPolygonOffsetx)(GLfixed factor, GLfixed units) {
+    CALL_GL_API(glPolygonOffsetx, factor, units);
+    GLLog("glPolygonOffsetx") << GLLogFixed(factor) << GLLogFixed(units);
+}
+
+void API_ENTRY(glPopMatrix)(void) {
+    CALL_GL_API(glPopMatrix);
+    GLLog("glPopMatrix");
+}
+
+void API_ENTRY(glPushMatrix)(void) {
+    CALL_GL_API(glPushMatrix);
+    GLLog("glPushMatrix");
+}
+
+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);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glReadPixels") << x << y << width << height << GLLogEnum(format) << GLLogEnum(type)
+            << GLLogBuffer<unsigned char>(static_cast<unsigned char *>(pixels));
+}
+
+void API_ENTRY(glRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
+    CALL_GL_API(glRotatef, angle, x, y, z);
+    GLLog("glRotatef") << angle << x << y << z;
+}
+
+void API_ENTRY(glRotatex)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
+    CALL_GL_API(glRotatex, angle, x, y, z);
+    GLLog("glRotatex") << GLLogFixed(angle) << GLLogFixed(x) << GLLogFixed(y) << GLLogFixed(z);
+}
+
+void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) {
+    CALL_GL_API(glSampleCoverage, value, invert);
+    GLLog("glSampleCoverage") << value << GLLogBool(invert);
+}
+
+void API_ENTRY(glSampleCoveragex)(GLclampx value, GLboolean invert) {
+    CALL_GL_API(glSampleCoveragex, value, invert);
+    GLLog("glSampleCoveragex") << GLLogFixed(value) << GLLogBool(invert);
+}
+
+void API_ENTRY(glScalef)(GLfloat x, GLfloat y, GLfloat z) {
+    CALL_GL_API(glScalef, x, y, z);
+    GLLog("glScalef") << x << y << z;
+}
+
+void API_ENTRY(glScalex)(GLfixed x, GLfixed y, GLfixed z) {
+    CALL_GL_API(glScalex, x, y, z);
+    GLLog("glScalex") << GLLogFixed(x) << GLLogFixed(y) << GLLogFixed(z);
+}
+
+void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
+    CALL_GL_API(glScissor, x, y, width, height);
+    GLLog("glScissor") << x << y << width << height;
+}
+
+void API_ENTRY(glShadeModel)(GLenum mode) {
+    CALL_GL_API(glShadeModel, mode);
+    GLLog("glShadeModel") << GLLogEnum(mode);
+}
+
+void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
+    CALL_GL_API(glStencilFunc, func, ref, mask);
+    GLLog("glStencilFunc") << GLLogEnum(func) << ref << mask;
+}
+
+void API_ENTRY(glStencilMask)(GLuint mask) {
+    CALL_GL_API(glStencilMask, mask);
+    GLLog("glStencilMask") << mask;
+}
+
+void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
+    CALL_GL_API(glStencilOp, fail, zfail, zpass);
+    GLLog("glStencilOp") << GLLogEnum(fail) << GLLogEnum(zfail) << GLLogEnum(zpass);
+}
+
+void API_ENTRY(glTexCoordPointer)( GLint size, GLenum type,
+                        GLsizei stride, const GLvoid *pointer) {
+    CALL_GL_API(glTexCoordPointer, size, type, stride, pointer);
+    GLLog("glTexCoordPointer") << size << GLLogEnum(type) << stride << pointer;
+}
+
+void API_ENTRY(glTexEnvf)(GLenum target, GLenum pname, GLfloat param) {
+    CALL_GL_API(glTexEnvf, target, pname, param);
+    GLLog("glTexEnvf") << GLLogEnum(target) << GLLogEnum(pname) << param;
+}
+
+void API_ENTRY(glTexEnvfv)(GLenum target, GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glTexEnvfv, target, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glTexEnvx") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+
+void API_ENTRY(glTexEnvx)(GLenum target, GLenum pname, GLfixed param) {
+    CALL_GL_API(glTexEnvx, target, pname, param);
+    GLLog("glTexEnvx") << GLLogEnum(target) << GLLogEnum(pname) << GLLogFixed(param);
+}
+
+void API_ENTRY(glTexEnvxv)(GLenum target, GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glTexEnvxv, target, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glTexEnvxv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+
+void API_ENTRY(glTexImage2D)(  GLenum target, GLint level, GLenum 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);
+    GLLog("glTexImage2D") << GLLogEnum(target) << level << GLLogEnum(internalformat)
+            << width << height << border << GLLogEnum(format) << GLLogEnum(type)
+            << GLLogBuffer<unsigned char>( static_cast<const unsigned char *>(pixels));
+}
+
+void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
+    CALL_GL_API(glTexParameterf, target, pname, param);
+    GLLog("glTexParameterf") << GLLogEnum(target) << GLLogEnum(pname) << param;
+}
+
+void API_ENTRY(glTexParameterx)(GLenum target, GLenum pname, GLfixed param) {
+    CALL_GL_API(glTexParameterx, target, pname, param);
+    GLLog("glTexParameterx") << GLLogEnum(target) << GLLogEnum(pname) << GLLogFixed(param);
+}
+
+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);
+    GLLog("glTexSubImage2D") << GLLogEnum(target) << level << xoffset << yoffset
+            << width << height << GLLogEnum(format) << GLLogEnum(type)
+            << GLLogBuffer<unsigned char>( static_cast<const unsigned char *>(pixels));
+}
+
+void API_ENTRY(glTranslatef)(GLfloat x, GLfloat y, GLfloat z) {
+    CALL_GL_API(glTranslatef, x, y, z);
+    GLLog("glTranslatef") << x << y << z;
+}
+
+void API_ENTRY(glTranslatex)(GLfixed x, GLfixed y, GLfixed z) {
+    CALL_GL_API(glTranslatex, x, y, z);
+    GLLog("glTranslatex") << GLLogFixed(x) << GLLogFixed(y) << GLLogFixed(z);
+}
+
+void API_ENTRY(glVertexPointer)(   GLint size, GLenum type,
+                        GLsizei stride, const GLvoid *pointer) {
+    CALL_GL_API(glVertexPointer, size, type, stride, pointer);
+    GLLog("glVertexPointer") << size << GLLogEnum(type) << stride << pointer;
+}
+
+void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
+    CALL_GL_API(glViewport, x, y, width, height);
+    GLLog("glViewport") << x << y << width << height;
+}
+
+// ES 1.1
+void API_ENTRY(glClipPlanef)(GLenum plane, const GLfloat *equation) {
+    CALL_GL_API(glClipPlanef, plane, equation);
+    GLLog("glClipPlanef") << GLLogEnum(plane) << GLLogBuffer<GLfloat>(equation, 4);
+}
+void API_ENTRY(glClipPlanex)(GLenum plane, const GLfixed *equation) {
+    CALL_GL_API(glClipPlanex, plane, equation);
+    GLLog("glClipPlanex") << GLLogEnum(plane) << GLLogBuffer<GLfixed>(equation, 4);
+}
+void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
+    CALL_GL_API(glBindBuffer, target, buffer);
+    GLLog("glBindBuffer") << GLLogEnum(target) << buffer;
+}
+void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
+    CALL_GL_API(glBufferData, target, size, data, usage);
+    GLLog("glBufferData") << GLLogEnum(target) << size
+        << GLLogBuffer<unsigned char>(static_cast<const unsigned char*>(data), size);
+}
+void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
+    CALL_GL_API(glBufferSubData, target, offset, size, data);
+    GLLog("glBufferSubData") << GLLogEnum(target) << offset << size
+        << GLLogBuffer<unsigned char>(static_cast<const unsigned char*>(data), size);
+}
+void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint* buffers) {
+    CALL_GL_API(glDeleteBuffers, n, buffers);
+    GLLog("glDeleteBuffers") << n << GLLogBuffer<GLuint>(buffers, n);
+}
+void API_ENTRY(glGenBuffers)(GLsizei n, GLuint* buffers) {
+    CALL_GL_API(glGenBuffers, n, buffers);
+    GLLog("glGenBuffers") << n << GLLogBuffer<GLuint>(buffers, n);
+}
+void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean *params) {
+    CALL_GL_API(glGetBooleanv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetBooleanv") << GLLogEnum(pname) << GLLogBuffer<GLboolean>(params);
+}
+void API_ENTRY(glGetFixedv)(GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetFixedv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetFixedv") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetFloatv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetFloatv") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+void API_ENTRY(glGetPointerv)(GLenum pname, void **params) {
+    CALL_GL_API(glGetPointerv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetPointerv") << GLLogEnum(pname) << GLLogBuffer<void*>(params);
+}
+void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint *params) {
+    // XXX: we need to compute the size of this buffer
+    CALL_GL_API(glGetBufferParameteriv, target, pname, params);
+    GLLog("glGetBufferParameteriv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
+}
+void API_ENTRY(glGetClipPlanef)(GLenum pname, GLfloat eqn[4]) {
+    CALL_GL_API(glGetClipPlanef, pname, eqn);
+    GLLog("glGetClipPlanef") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(eqn, 4);
+}
+void API_ENTRY(glGetClipPlanex)(GLenum pname, GLfixed eqn[4]) {
+    CALL_GL_API(glGetClipPlanex, pname, eqn);
+    GLLog("glGetClipPlanex") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(eqn, 4);
+}
+void API_ENTRY(glGetLightxv)(GLenum light, GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetLightxv, light, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetLightxv") << GLLogEnum(light) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+void API_ENTRY(glGetLightfv)(GLenum light, GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetLightfv, light, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetLightfv") << GLLogEnum(light) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetMaterialxv, face, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetMaterialxv") << GLLogEnum(face) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+void API_ENTRY(glGetMaterialfv)(GLenum face, GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetMaterialfv, face, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetMaterialfv") << GLLogEnum(face) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+void API_ENTRY(glGetTexEnvfv)(GLenum env, GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetTexEnvfv, env, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetTexEnvfv") << GLLogEnum(env) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+void API_ENTRY(glGetTexEnviv)(GLenum env, GLenum pname, GLint *params) {
+    CALL_GL_API(glGetTexEnviv, env, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetTexEnviv") << GLLogEnum(env) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
+}
+void API_ENTRY(glGetTexEnvxv)(GLenum env, GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetTexEnvxv, env, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetTexEnvxv") << GLLogEnum(env) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) {
+    CALL_GL_API(glGetTexParameterfv, target, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetTexParameterfv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint *params) {
+    CALL_GL_API(glGetTexParameteriv, target, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetTexParameteriv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
+}
+void API_ENTRY(glGetTexParameterxv)(GLenum target, GLenum pname, GLfixed *params) {
+    CALL_GL_API(glGetTexParameterxv, target, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glGetTexParameterxv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) {
+    GLLog("glIsBuffer") << buffer;
+    CALL_GL_API_RETURN(glIsBuffer, buffer);
+}
+GLboolean API_ENTRY(glIsEnabled)(GLenum cap) {
+    GLLog("glIsEnabled") << GLLogEnum(cap);
+    CALL_GL_API_RETURN(glIsEnabled, cap);
+}
+GLboolean API_ENTRY(glIsTexture)(GLuint texture) {
+    GLLog("glIsTexture") << texture;
+    CALL_GL_API_RETURN(glIsTexture, texture);
+}
+void API_ENTRY(glPointParameterf)(GLenum pname, GLfloat param) {
+    CALL_GL_API(glPointParameterf, pname, param);
+    GLLog("glPointParameterf") << GLLogEnum(pname) << param;
+}
+void API_ENTRY(glPointParameterfv)(GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glPointParameterfv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glPointParameterfv") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+void API_ENTRY(glPointParameterx)(GLenum pname, GLfixed param) {
+    CALL_GL_API(glPointParameterx, pname, param);
+    GLLog("glPointParameterx") << GLLogEnum(pname) << GLLogFixed(param);
+}
+void API_ENTRY(glPointParameterxv)(GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glPointParameterxv, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glPointParameterxv") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+void API_ENTRY(glColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
+    CALL_GL_API(glColor4ub, red, green, blue, alpha);
+    GLLog("glColor4ub") << red << green << blue << alpha;
+}
+void API_ENTRY(glTexEnvi)(GLenum target, GLenum pname, GLint param) {
+    CALL_GL_API(glTexEnvi, target, pname, param);
+    GLLog("glTexEnvi") << GLLogEnum(target) << GLLogEnum(pname) << param;
+}
+void API_ENTRY(glTexEnviv)(GLenum target, GLenum pname, const GLint *params) {
+    CALL_GL_API(glTexEnviv, target, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glTexEnviv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
+}
+
+void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) {
+    CALL_GL_API(glTexParameterfv, target, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glTexParameterfv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
+}
+
+void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) {
+    CALL_GL_API(glTexParameteriv, target, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glTexParameteriv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
+}
+
+void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) {
+    CALL_GL_API(glTexParameteri, target, pname, param);
+    GLLog("glTexParameteri") << GLLogEnum(target) << GLLogEnum(pname) << param;
+}
+void API_ENTRY(glTexParameterxv)(GLenum target, GLenum pname, const GLfixed *params) {
+    CALL_GL_API(glTexParameterxv, target, pname, params);
+    // XXX: we need to compute the size of this buffer
+    GLLog("glTexParameterxv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
+}
+void API_ENTRY(glPointSizePointerOES)(GLenum type, GLsizei stride, const GLvoid *pointer) {
+    CALL_GL_API(glPointSizePointerOES, type, stride, pointer);
+    GLLog("glPointSizePointerOES") << GLLogEnum(type) << stride << pointer;
+}
+
+// Extensions
+void API_ENTRY(glDrawTexsOES)(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) {
+    CALL_GL_API(glDrawTexsOES, x, y, z, w, h);
+    GLLog("glDrawTexsOES") << x << y << z << w << h;
+}
+void API_ENTRY(glDrawTexiOES)(GLint x, GLint y, GLint z, GLint w, GLint h) {
+    CALL_GL_API(glDrawTexiOES, x, y, z, w, h);
+    GLLog("glDrawTexiOES") << x << y << z << w << h;
+}
+void API_ENTRY(glDrawTexfOES)(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h) {
+    CALL_GL_API(glDrawTexfOES, x, y, z, w, h);
+    GLLog("glDrawTexfOES") << x << y << z << w << h;
+}
+void API_ENTRY(glDrawTexxOES)(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) {
+    CALL_GL_API(glDrawTexxOES, x, y, z, w, h);
+    GLLog("glDrawTexfOES") << GLLogFixed(x) << GLLogFixed(y) << GLLogFixed(z) << GLLogFixed(w) << GLLogFixed(h);
+}
+void API_ENTRY(glDrawTexsvOES)(const GLshort* coords) {
+    CALL_GL_API(glDrawTexsvOES, coords);
+    GLLog("glDrawTexsvOES") << GLLogBuffer<GLshort>(coords, 5);
+}
+void API_ENTRY(glDrawTexivOES)(const GLint* coords) {
+    CALL_GL_API(glDrawTexivOES, coords);
+    GLLog("glDrawTexivOES") << GLLogBuffer<GLint>(coords, 5);
+}
+void API_ENTRY(glDrawTexfvOES)(const GLfloat* coords) {
+    CALL_GL_API(glDrawTexfvOES, coords);
+    GLLog("glDrawTexfvOES") << GLLogBuffer<GLfloat>(coords, 5);
+}
+void API_ENTRY(glDrawTexxvOES)(const GLfixed* coords) {
+    CALL_GL_API(glDrawTexxvOES, coords);
+    GLLog("glDrawTexxvOES") << GLLogBuffer<GLfixed>(coords, 5);
+}
+GLbitfield API_ENTRY(glQueryMatrixxOES)(GLfixed* mantissa, GLint* exponent) {
+    GLLog("glQueryMatrixxOES") << GLLogBuffer<GLfixed>(mantissa, 16) << GLLogBuffer<GLfixed>(exponent, 16);
+    CALL_GL_API_RETURN(glQueryMatrixxOES, mantissa, exponent);
+}
diff --git a/opengl/libGLES_CM/gl_logger.h b/opengl/libGLES_CM/gl_logger.h
new file mode 100644
index 0000000..59e31c7
--- /dev/null
+++ b/opengl/libGLES_CM/gl_logger.h
@@ -0,0 +1,26 @@
+/* 
+ ** 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_GL_LOGGER_H
+#define ANDROID_GL_LOGGER_H
+
+extern "C" {
+#define GL_ENTRY(r, api, ...) r log_##api(__VA_ARGS__);
+#include "gl_entries.cpp"
+#undef GL_ENTRY
+};
+
+#endif /* ANDROID_GL_LOGGER_H */
diff --git a/opengl/libGLES_CM/gl_wrapper.cpp b/opengl/libGLES_CM/gl_wrapper.cpp
new file mode 100644
index 0000000..5da4f9a
--- /dev/null
+++ b/opengl/libGLES_CM/gl_wrapper.cpp
@@ -0,0 +1,1663 @@
+/* 
+ ** 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 "GLLogger"
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include <dlfcn.h>
+
+#include <sys/ioctl.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+#include <GLES/egl.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h>
+#include <cutils/memory.h>
+
+#include <utils/IMemory.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/IServiceManager.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Parcel.h>
+
+#include <ui/EGLDisplaySurface.h>
+#include <ui/ISurfaceComposer.h>
+
+#include "gl_logger.h"
+
+#undef NELEM
+
+#define GL_LOGGER                   0
+#define USE_SLOW_BINDING            0
+#define NELEM(x)                    (sizeof(x)/sizeof(*(x)))
+#define MAX_NUMBER_OF_GL_EXTENSIONS 32
+#define MAKE_CONFIG(_impl, _index)  ((EGLConfig)(((_impl)<<24) | (_index)))
+#define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r)
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+//  EGLDisplay are global, not attached to a given thread
+static const unsigned int NUM_DISPLAYS = 1;
+static const unsigned int IMPL_HARDWARE                 = 0;
+static const unsigned int IMPL_SOFTWARE                 = 1;
+static const unsigned int IMPL_HARDWARE_CONTEXT_LOST    = 2;
+static const unsigned int IMPL_SOFTWARE_CONTEXT_LOST    = 3;
+static const unsigned int IMPL_NO_CONTEXT               = 4;
+
+// ----------------------------------------------------------------------------
+
+struct gl_hooks_t;
+
+struct egl_connection_t
+{
+    void volatile *     dso;
+    gl_hooks_t *        hooks;
+    EGLint              major;
+    EGLint              minor;
+    int                 unavailable;
+};
+
+template <int MAGIC>
+struct egl_object_t
+{
+    egl_object_t() : magic(MAGIC) { }
+    ~egl_object_t() { magic = 0; }
+    bool isValid() const { return magic == MAGIC; }
+private:
+    uint32_t    magic;
+};
+
+struct egl_display_t : public egl_object_t<'_dpy'>
+{
+    EGLDisplay  dpys[2];
+    EGLConfig*  configs[2];
+    EGLint      numConfigs[2];
+    EGLint      numTotalConfigs;
+    char const* extensionsString;
+    volatile int32_t refs;
+    struct strings_t {
+        char const * vendor;
+        char const * version;
+        char const * clientApi;
+        char const * extensions;
+        char const * extensions_config;
+    };
+    strings_t   queryString[2];
+};
+
+struct egl_surface_t : public egl_object_t<'_srf'>
+{
+    egl_surface_t(EGLDisplay dpy, EGLSurface surface,
+            NativeWindowType window, int impl, egl_connection_t const* cnx) 
+    : dpy(dpy), surface(surface), window(window), impl(impl), cnx(cnx)
+    {
+        // NOTE: window must be incRef'ed and connected already
+    }
+    ~egl_surface_t() {
+        if (window) {
+            if (window->disconnect)
+                window->disconnect(window);
+            window->decRef(window);
+        }
+    }
+    EGLDisplay                  dpy;
+    EGLSurface                  surface;
+    NativeWindowType            window;
+    int                         impl;
+    egl_connection_t const*     cnx;
+};
+
+struct egl_context_t : public egl_object_t<'_ctx'>
+{
+    egl_context_t(EGLDisplay dpy, EGLContext context,
+            int impl, egl_connection_t const* cnx) 
+    : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx)
+    {
+    }
+    EGLDisplay                  dpy;
+    EGLContext                  context;
+    EGLSurface                  read;
+    EGLSurface                  draw;
+    int                         impl;
+    egl_connection_t const*     cnx;
+};
+
+struct tls_t
+{
+    tls_t() : error(EGL_SUCCESS), ctx(0) { }
+    EGLint      error;
+    EGLContext  ctx;
+};
+
+
+// GL / EGL hooks
+
+typedef void(*proc_t)();
+
+struct gl_hooks_t {
+    struct gl_t {
+        #define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
+        #include "gl_entries.cpp"
+        #undef GL_ENTRY
+    } gl;
+    struct egl_t {
+        #define EGL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
+        #include "egl_entries.cpp"
+        #undef EGL_ENTRY
+    } egl;
+    struct gl_ext_t {
+        void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void);
+    } ext;
+};
+
+static char const * const gl_names[] = {
+    #define GL_ENTRY(_r, _api, ...) #_api,
+    #include "gl_entries.cpp"
+    #undef GL_ENTRY
+    NULL
+};
+
+static char const * const egl_names[] = {
+    #define EGL_ENTRY(_r, _api, ...) #_api,
+    #include "egl_entries.cpp"
+    #undef EGL_ENTRY
+    NULL
+};
+
+static void gl_unimplemented() {
+    LOGE("called unimplemented OpenGL ES API");
+}
+
+// ----------------------------------------------------------------------------
+
+static egl_connection_t gEGLImpl[2];
+static egl_display_t gDisplay[NUM_DISPLAYS];
+static gl_hooks_t gHooks[5];
+static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_key_t gEGLThreadLocalStorageKey = -1;
+
+// ----------------------------------------------------------------------------
+
+#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && !GL_LOGGER
+
+#include <sys/tls.h>
+// We have a dedicated TLS slot in bionic
+static inline void setGlThreadSpecific(gl_hooks_t const *value) {
+    ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL_API] = (uint32_t)value;
+}
+static gl_hooks_t const* getGlThreadSpecific() {
+    gl_hooks_t const* hooks = (gl_hooks_t const *)(((unsigned const *)__get_tls())[TLS_SLOT_OPENGL_API]);
+    if (hooks) return hooks;
+    return &gHooks[IMPL_NO_CONTEXT];
+}
+
+#else
+
+static pthread_key_t gGLWrapperKey = -1;
+static inline void setGlThreadSpecific(gl_hooks_t const *value) {
+    pthread_setspecific(gGLWrapperKey, value);
+}
+static gl_hooks_t const* getGlThreadSpecific() {
+    gl_hooks_t const* hooks =  static_cast<gl_hooks_t*>(pthread_getspecific(gGLWrapperKey));
+    if (hooks) return hooks;
+    return &gHooks[IMPL_NO_CONTEXT];
+}
+
+#endif
+
+static __attribute__((noinline))
+const char *egl_strerror(EGLint err)
+{
+    switch (err){
+        case EGL_SUCCESS:               return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:       return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:            return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:             return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:         return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG:            return "EGL_BAD_CONFIG";
+        case EGL_BAD_CONTEXT:           return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE:   return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:           return "EGL_BAD_DISPLAY";
+        case EGL_BAD_MATCH:             return "EGL_BAD_MATCH";
+        case EGL_BAD_NATIVE_PIXMAP:     return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW:     return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_BAD_PARAMETER:         return "EGL_BAD_PARAMETER";
+        case EGL_BAD_SURFACE:           return "EGL_BAD_SURFACE";
+        case EGL_CONTEXT_LOST:          return "EGL_CONTEXT_LOST";
+        default: return "UNKNOWN";
+    }
+}
+
+static __attribute__((noinline))
+void clearTLS() {
+    if (gEGLThreadLocalStorageKey != -1) {
+        tls_t* tls = (tls_t*)pthread_getspecific(gEGLThreadLocalStorageKey);
+        if (tls) {
+            delete tls;
+            pthread_setspecific(gEGLThreadLocalStorageKey, 0);
+        }
+    }
+}
+
+static tls_t* getTLS()
+{
+    tls_t* tls = (tls_t*)pthread_getspecific(gEGLThreadLocalStorageKey);
+    if (tls == 0) {
+        tls = new tls_t;
+        pthread_setspecific(gEGLThreadLocalStorageKey, tls);
+    }
+    return tls;
+}
+
+template<typename T>
+static __attribute__((noinline))
+T setErrorEtc(const char* caller, int line, EGLint error, T returnValue) {
+    if (gEGLThreadLocalStorageKey == -1) {
+        pthread_mutex_lock(&gThreadLocalStorageKeyMutex);
+        if (gEGLThreadLocalStorageKey == -1)
+            pthread_key_create(&gEGLThreadLocalStorageKey, NULL);
+        pthread_mutex_unlock(&gThreadLocalStorageKeyMutex);
+    }
+    tls_t* tls = getTLS();
+    if (tls->error != error) {
+        LOGE("%s:%d error %x (%s)", caller, line, error, egl_strerror(error));
+        tls->error = error;
+    }
+    return returnValue;
+}
+
+static __attribute__((noinline))
+GLint getError() {
+    if (gEGLThreadLocalStorageKey == -1)
+        return EGL_SUCCESS;
+    tls_t* tls = (tls_t*)pthread_getspecific(gEGLThreadLocalStorageKey);
+    if (!tls) return EGL_SUCCESS;
+    GLint error = tls->error;
+    tls->error = EGL_SUCCESS;
+    return error;
+}
+
+static __attribute__((noinline))
+void setContext(EGLContext ctx) {
+    if (gEGLThreadLocalStorageKey == -1) {
+        pthread_mutex_lock(&gThreadLocalStorageKeyMutex);
+        if (gEGLThreadLocalStorageKey == -1)
+            pthread_key_create(&gEGLThreadLocalStorageKey, NULL);
+        pthread_mutex_unlock(&gThreadLocalStorageKeyMutex);
+    }
+    tls_t* tls = getTLS();
+    tls->ctx = ctx;
+}
+
+static __attribute__((noinline))
+EGLContext getContext() {
+    if (gEGLThreadLocalStorageKey == -1)
+        return EGL_NO_CONTEXT;
+    tls_t* tls = (tls_t*)pthread_getspecific(gEGLThreadLocalStorageKey);
+    if (!tls) return EGL_NO_CONTEXT;
+    return tls->ctx;
+}
+
+/*****************************************************************************/
+
+/*
+ * we provide our own allocators for the GPU regions, these
+ * allocators go through surfaceflinger 
+ */
+
+static Mutex                            gRegionsLock;
+static request_gpu_t                    gRegions;
+static sp<ISurfaceComposer>             gSurfaceManager;
+ISurfaceComposer*                       GLES_localSurfaceManager = 0;
+
+const sp<ISurfaceComposer>& getSurfaceFlinger()
+{
+    Mutex::Autolock _l(gRegionsLock);
+
+    /*
+     * There is a little bit of voodoo magic here. We want to access
+     * surfaceflinger for allocating GPU regions, however, when we are
+     * running as part of surfaceflinger, we want to bypass the
+     * service manager because surfaceflinger might not be registered yet.
+     * SurfaceFlinger will populate "GLES_localSurfaceManager" with its
+     * own address, so we can just use that.
+     */
+    if (gSurfaceManager == 0) {
+        if (GLES_localSurfaceManager) {
+            // we're running in SurfaceFlinger's context
+            gSurfaceManager =  GLES_localSurfaceManager;
+        } else {
+            // we're a remote process or not part of surfaceflinger,
+            // go through the service manager
+            sp<IServiceManager> sm = defaultServiceManager();
+            if (sm != NULL) {
+                sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
+                gSurfaceManager = interface_cast<ISurfaceComposer>(binder);
+            }
+        }
+    }
+    return gSurfaceManager;
+}
+
+class GPURevokeRequester : public BnGPUCallback
+{
+public:
+    virtual void gpuLost() {
+        LOGD("CONTEXT_LOST: Releasing GPU upon request from SurfaceFlinger.");
+        gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_HARDWARE_CONTEXT_LOST];
+    }
+};
+
+static sp<GPURevokeRequester> gRevokerCallback;
+
+static request_gpu_t* gpu_acquire(void* user)
+{
+    sp<ISurfaceComposer> server( getSurfaceFlinger() );
+
+    Mutex::Autolock _l(gRegionsLock);
+    if (server == NULL) {
+        return 0;
+    }
+    
+    ISurfaceComposer::gpu_info_t info;
+    gRevokerCallback = new GPURevokeRequester();
+    status_t err = server->requestGPU(gRevokerCallback, &info);
+    if (err != NO_ERROR) {
+        LOGD("requestGPU returned %d", err);
+        return 0;
+    }
+
+    bool failed = false;
+    request_gpu_t* gpu = &gRegions;
+    memset(gpu, 0, sizeof(*gpu));
+    
+    if (info.regs != 0) {
+        sp<IMemoryHeap> heap(info.regs->getMemory());
+        if (heap != 0) {
+            int fd = heap->heapID();
+            gpu->regs.fd = fd;
+            gpu->regs.base = info.regs->pointer(); 
+            gpu->regs.size = info.regs->size(); 
+            gpu->regs.user = info.regs.get();
+#if HAVE_ANDROID_OS
+            struct pmem_region region;
+            if (ioctl(fd, PMEM_GET_PHYS, &region) >= 0)
+                gpu->regs.phys = (void*)region.offset;
+#endif
+            info.regs->incStrong(gpu);
+        } else {
+            LOGE("GPU register handle %p is invalid!", info.regs.get());
+            failed = true;
+        }
+    }
+
+    for (size_t i=0 ; i<info.count && !failed ; i++) {
+        sp<IMemory>& region(info.regions[i].region);
+        if (region != 0) {
+            sp<IMemoryHeap> heap(region->getMemory());
+            if (heap != 0) {
+                const int fd = heap->heapID();
+                gpu->gpu[i].fd = fd;
+                gpu->gpu[i].base = region->pointer(); 
+                gpu->gpu[i].size = region->size(); 
+                gpu->gpu[i].user = region.get();
+                gpu->gpu[i].offset = info.regions[i].reserved;
+#if HAVE_ANDROID_OS
+                struct pmem_region reg;
+                if (ioctl(fd, PMEM_GET_PHYS, &reg) >= 0)
+                    gpu->gpu[i].phys = (void*)reg.offset;
+#endif
+                region->incStrong(gpu);
+            } else {
+                LOGE("GPU region handle [%d, %p] is invalid!", i, region.get());
+                failed = true;
+            }
+        }
+    }
+    
+    if (failed) {
+        // something went wrong, clean up everything!
+        if (gpu->regs.user) {
+            static_cast<IMemory*>(gpu->regs.user)->decStrong(gpu);
+            for (size_t i=0 ; i<info.count ; i++) {
+                if (gpu->gpu[i].user) {
+                    static_cast<IMemory*>(gpu->gpu[i].user)->decStrong(gpu);
+                }
+            }
+        }
+    }
+    
+    gpu->count = info.count;
+    return gpu;
+}
+
+static int gpu_release(void*, request_gpu_t* gpu)
+{
+    sp<IMemory> regs;
+
+    { // scope for lock
+        Mutex::Autolock _l(gRegionsLock);
+        regs = static_cast<IMemory*>(gpu->regs.user);   
+        gpu->regs.user = 0;
+        if (regs != 0) regs->decStrong(gpu);
+        
+        for (int i=0 ; i<gpu->count ; i++) {
+            sp<IMemory> r(static_cast<IMemory*>(gpu->gpu[i].user));
+            gpu->gpu[i].user = 0;
+            if (r != 0) r->decStrong(gpu);
+        }
+    }
+    
+    // there is a special transaction to relinquish the GPU
+    // (it will happen automatically anyway if we don't do this)
+    Parcel data, reply;
+    // NOTE: this transaction does not require an interface token
+    regs->asBinder()->transact(1000, data, &reply);
+    return 1;
+}
+
+/*****************************************************************************/
+
+static __attribute__((noinline))
+void *load_driver(const char* driver, gl_hooks_t* hooks)
+{
+    void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL);
+    LOGE_IF(!dso,
+            "couldn't load <%s> library (%s)",
+            driver, dlerror());
+
+    if (dso) {
+        void** curr;
+        char const * const * api;
+        gl_hooks_t::gl_t* gl = &hooks->gl;
+        curr = (void**)gl;
+        api = gl_names;
+        while (*api) {
+            void* f = dlsym(dso, *api);
+            //LOGD("<%s> @ 0x%p", *api, f);
+            if (f == NULL) {
+                //LOGW("<%s> not found in %s", *api, driver);
+                f = (void*)gl_unimplemented;
+            }
+            *curr++ = f;
+            api++;
+        }
+        gl_hooks_t::egl_t* egl = &hooks->egl;
+        curr = (void**)egl;
+        api = egl_names;
+        while (*api) {
+            void* f = dlsym(dso, *api);
+            if (f == NULL) {
+                //LOGW("<%s> not found in %s", *api, driver);
+                f = (void*)0;
+            }
+            *curr++ = f;
+            api++;
+        }
+
+        // hook this driver up with surfaceflinger if needed
+        register_gpu_t register_gpu = 
+            (register_gpu_t)dlsym(dso, "oem_register_gpu");
+
+        if (register_gpu != NULL) {
+            if (getSurfaceFlinger() != 0) {
+                register_gpu(dso, gpu_acquire, gpu_release);
+            }
+        }
+    }
+    return dso;
+}
+
+template<typename T>
+static __attribute__((noinline))
+int binarySearch(
+        T const sortedArray[], int first, int last, T key)
+{
+    while (first <= last) {
+        int mid = (first + last) / 2;
+        if (key > sortedArray[mid]) { 
+            first = mid + 1;
+        } else if (key < sortedArray[mid]) { 
+            last = mid - 1;
+        } else {
+            return mid;
+        }
+    }
+    return -1;
+}
+
+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);
+}
+
+static char const * const gVendorString     = "Android";
+static char const * const gVersionString    = "1.2 Android META-EGL";
+static char const * const gClientApiString  = "OpenGL ES";
+
+struct extention_map_t {
+    const char* name;
+    void (*address)(void);
+};
+
+static const extention_map_t gExtentionMap[] = {
+    { "eglSwapRectangleANDROID",         (void(*)())&eglSwapRectangleANDROID },
+    { "eglQueryStringConfigANDROID",     (void(*)())&eglQueryStringConfigANDROID },
+};
+
+static extention_map_t gGLExtentionMap[MAX_NUMBER_OF_GL_EXTENSIONS];
+
+static void(*findProcAddress(const char* name,
+        const extention_map_t* map, size_t n))() 
+{
+    for (uint32_t i=0 ; i<n ; i++) {
+        if (!strcmp(name, map[i].name)) {
+            return map[i].address;
+        }
+    }
+    return NULL;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+
+// ----------------------------------------------------------------------------
+// extensions for the framework
+// ----------------------------------------------------------------------------
+
+void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
+        const GLvoid *ptr, GLsizei count) {
+    glColorPointer(size, type, stride, ptr);
+}
+void glNormalPointerBounds(GLenum type, GLsizei stride,
+        const GLvoid *pointer, GLsizei count) {
+    glNormalPointer(type, stride, pointer);
+}
+void glTexCoordPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count) {
+    glTexCoordPointer(size, type, stride, pointer);
+}
+void glVertexPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count) {
+    glVertexPointer(size, type, stride, pointer);
+}
+
+
+// ----------------------------------------------------------------------------
+// Actual GL wrappers
+// ----------------------------------------------------------------------------
+
+#if __OPTIMIZE__ && defined(__arm__) && !defined(__thumb__) && !USE_SLOW_BINDING && !GL_LOGGER
+
+    #define API_ENTRY(_api) __attribute__((naked)) _api
+    #define CALL_GL_API(_api, ...)                              \
+         asm volatile(                                          \
+            "mov   r12, #0xFFFF0FFF   \n"                       \
+            "ldr   r12, [r12, #-15]   \n"                       \
+            "ldr   r12, [r12, %[tls]] \n"                       \
+            "cmp   r12, #0            \n"                       \
+            "ldrne pc,  [r12, %[api]] \n"                       \
+            "bx    lr                 \n"                       \
+            :                                                   \
+            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
+              [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
+            :                                                   \
+            );
+    
+    #define CALL_GL_API_RETURN(_api, ...) \
+        CALL_GL_API(_api, __VA_ARGS__) \
+        return 0; // placate gcc's warnings. never reached.
+
+#else
+
+    #define API_ENTRY(_api) _api
+    #if GL_LOGGER
+
+        #define CALL_GL_API(_api, ...)          \
+            gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
+            log_##_api(__VA_ARGS__); \
+            _c->_api(__VA_ARGS__);
+        
+        #define CALL_GL_API_RETURN(_api, ...)   \
+            gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
+            log_##_api(__VA_ARGS__); \
+            return _c->_api(__VA_ARGS__)
+
+    #else
+
+        #define CALL_GL_API(_api, ...)          \
+            gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
+            _c->_api(__VA_ARGS__);
+        
+        #define CALL_GL_API_RETURN(_api, ...)   \
+            gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
+            return _c->_api(__VA_ARGS__)
+
+    #endif
+
+#endif
+
+#include "gl_api.cpp"
+
+#undef API_ENTRY
+#undef CALL_GL_API
+#undef CALL_GL_API_RETURN
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+static int gl_context_lost() {
+    setGlThreadSpecific(&gHooks[IMPL_HARDWARE_CONTEXT_LOST]);
+    return 0;
+}
+static int egl_context_lost() {
+    setGlThreadSpecific(&gHooks[IMPL_HARDWARE_CONTEXT_LOST]);
+    return EGL_FALSE;
+}
+static EGLBoolean egl_context_lost_swap_buffers(void*, void*) {
+    usleep(100000); // don't use all the CPU
+    setGlThreadSpecific(&gHooks[IMPL_HARDWARE_CONTEXT_LOST]);
+    return EGL_FALSE;
+}
+static GLint egl_context_lost_get_error() {
+    return EGL_CONTEXT_LOST;
+}
+static int ext_context_lost() {
+    return 0;
+}
+
+static void gl_no_context() {
+    LOGE("call to OpenGL ES API with no current context");
+}
+static void early_egl_init(void) 
+{
+#if !defined(HAVE_ANDROID_OS) || USE_SLOW_BINDING || GL_LOGGER
+    pthread_key_create(&gGLWrapperKey, NULL);
+#endif
+    uint32_t addr = (uint32_t)((void*)gl_no_context);
+    android_memset32((uint32_t*)(void*)&gHooks[IMPL_NO_CONTEXT], addr, sizeof(gHooks[IMPL_NO_CONTEXT]));
+    setGlThreadSpecific(&gHooks[IMPL_NO_CONTEXT]);
+}
+
+static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+static int sEarlyInitState = pthread_once(&once_control, &early_egl_init);
+
+
+static inline
+egl_display_t* get_display(EGLDisplay dpy)
+{
+    uintptr_t index = uintptr_t(dpy)-1U;
+    return (index >= NUM_DISPLAYS) ? NULL : &gDisplay[index];
+}
+
+static inline
+egl_surface_t* get_surface(EGLSurface surface)
+{
+    egl_surface_t* s = (egl_surface_t *)surface;
+    return s;
+}
+
+static inline
+egl_context_t* get_context(EGLContext context)
+{
+    egl_context_t* c = (egl_context_t *)context;
+    return c;
+}
+
+static egl_connection_t* validate_display_config(
+        EGLDisplay dpy, EGLConfig config,
+        egl_display_t const*& dp, int& impl, int& index)
+{
+    dp = get_display(dpy);
+    if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL);
+
+    impl = uintptr_t(config)>>24;
+    if (uint32_t(impl) >= 2) {
+        return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
+    } 
+    index = uintptr_t(config) & 0xFFFFFF;
+    if (index >= dp->numConfigs[impl]) {
+        return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
+    }
+    egl_connection_t* const cnx = &gEGLImpl[impl];
+    if (cnx->dso == 0) {
+        return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
+    }
+    return cnx;
+}
+
+static EGLBoolean validate_display_context(EGLDisplay dpy, EGLContext ctx)
+{
+    if ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    if (!get_display(dpy)->isValid())
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    if (!ctx) // TODO: make sure context is a valid object
+        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+    if (!get_context(ctx)->isValid())
+        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+    return EGL_TRUE;
+}
+
+static EGLBoolean validate_display_surface(EGLDisplay dpy, EGLSurface surface)
+{
+    if ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    if (!get_display(dpy)->isValid())
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    if (!surface) // TODO: make sure surface is a valid object
+        return setError(EGL_BAD_SURFACE, EGL_FALSE);
+    if (!get_surface(surface)->isValid())
+        return setError(EGL_BAD_SURFACE, EGL_FALSE);
+    return EGL_TRUE;
+}
+
+static void add_extension(egl_display_t* dp, char const*& p, const char* ext)
+{
+    if (!strstr(p, ext)) {
+        p = (char const*)realloc((void*)p, strlen(p) + 1 + strlen(ext) + 1);
+        strcat((char*)p, " ");
+        strcat((char*)p, ext);
+    }
+    if (!strstr(dp->extensionsString, ext)) {
+        char const*& es = dp->extensionsString;
+        es = (char const*)realloc((void*)es, strlen(es) + 1 + strlen(ext) + 1);
+        strcat((char*)es, " ");
+        strcat((char*)es, ext);
+    }    
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+EGLDisplay eglGetDisplay(NativeDisplayType display)
+{
+    if (sEarlyInitState) {
+        return EGL_NO_DISPLAY;
+    }
+
+    uint32_t index = uint32_t(display);
+    if (index >= NUM_DISPLAYS) {
+        return EGL_NO_DISPLAY;
+    }
+    
+    EGLDisplay dpy = EGLDisplay(uintptr_t(display) + 1LU);
+    egl_display_t* d = &gDisplay[index];
+        
+    // dynamically load all our EGL implementations for that display
+    // and call into the real eglGetGisplay()
+    egl_connection_t* cnx = &gEGLImpl[IMPL_SOFTWARE];
+    if (cnx->dso == 0) {
+        cnx->hooks = &gHooks[IMPL_SOFTWARE];
+        cnx->dso = load_driver("libagl.so", cnx->hooks);
+    }
+    if (cnx->dso && d->dpys[IMPL_SOFTWARE]==EGL_NO_DISPLAY) {
+        d->dpys[IMPL_SOFTWARE] = cnx->hooks->egl.eglGetDisplay(display);
+        LOGE_IF(d->dpys[IMPL_SOFTWARE]==EGL_NO_DISPLAY,
+                "No EGLDisplay for software EGL!");
+    }
+
+    cnx = &gEGLImpl[IMPL_HARDWARE];
+    if (cnx->dso == 0 && cnx->unavailable == 0) {
+        char value[PROPERTY_VALUE_MAX];
+        property_get("debug.egl.hw", value, "1");
+        if (atoi(value) != 0) {
+            cnx->hooks = &gHooks[IMPL_HARDWARE];
+            cnx->dso = load_driver("libhgl.so", cnx->hooks);
+        } else {
+            LOGD("3D hardware acceleration is disabled");
+        }
+    }
+    if (cnx->dso && d->dpys[IMPL_HARDWARE]==EGL_NO_DISPLAY) {
+        android_memset32(
+                (uint32_t*)(void*)&gHooks[IMPL_HARDWARE_CONTEXT_LOST].gl,
+                (uint32_t)((void*)gl_context_lost),
+                sizeof(gHooks[IMPL_HARDWARE_CONTEXT_LOST].gl));
+        android_memset32(
+                (uint32_t*)(void*)&gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl,
+                (uint32_t)((void*)egl_context_lost),
+                sizeof(gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl));
+        android_memset32(
+                (uint32_t*)(void*)&gHooks[IMPL_HARDWARE_CONTEXT_LOST].ext,
+                (uint32_t)((void*)ext_context_lost),
+                sizeof(gHooks[IMPL_HARDWARE_CONTEXT_LOST].ext));
+
+        gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl.eglSwapBuffers =
+                egl_context_lost_swap_buffers;
+        
+        gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl.eglGetError =
+                egl_context_lost_get_error;
+
+        gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl.eglTerminate =
+                gHooks[IMPL_HARDWARE].egl.eglTerminate;
+        
+        d->dpys[IMPL_HARDWARE] = cnx->hooks->egl.eglGetDisplay(display);
+        if (d->dpys[IMPL_HARDWARE] == EGL_NO_DISPLAY) {
+            dlclose((void*)cnx->dso);
+            cnx->dso = 0;
+            // in case of failure, we want to make sure we don't try again
+            // as it's expensive.
+            cnx->unavailable = 1;
+        }
+    }
+
+    return dpy;
+}
+
+// ----------------------------------------------------------------------------
+// Initialization
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+    egl_display_t * const dp = get_display(dpy);
+    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    if (android_atomic_inc(&dp->refs) > 0) {
+        if (major != NULL) *major = 1;
+        if (minor != NULL) *minor = 2;
+        return EGL_TRUE;
+    }
+    
+    setGlThreadSpecific(&gHooks[IMPL_NO_CONTEXT]);
+    
+    // initialize each EGL and
+    // build our own extension string first, based on the extension we know
+    // and the extension supported by our client implementation
+    dp->extensionsString = strdup("EGL_ANDROID_query_string_config");
+    for (int i=0 ; i<2 ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        cnx->major = -1;
+        cnx->minor = -1;
+        if (cnx->dso && cnx->hooks->egl.eglInitialize(
+                dp->dpys[i], &cnx->major, &cnx->minor)) {
+
+            //LOGD("initialized %d dpy=%p, ver=%d.%d, cnx=%p",
+            //        i, dp->dpys[i], cnx->major, cnx->minor, cnx);
+
+            // get the query-strings for this display for each implementation
+            dp->queryString[i].vendor =
+                cnx->hooks->egl.eglQueryString(dp->dpys[i], EGL_VENDOR);
+            dp->queryString[i].version =
+                cnx->hooks->egl.eglQueryString(dp->dpys[i], EGL_VERSION);
+            dp->queryString[i].extensions = strdup(
+                cnx->hooks->egl.eglQueryString(dp->dpys[i], EGL_EXTENSIONS));
+            dp->queryString[i].clientApi =
+                cnx->hooks->egl.eglQueryString(dp->dpys[i], EGL_CLIENT_APIS);
+            
+            // Dynamically insert extensions we know about
+            if (cnx->hooks->egl.eglSwapRectangleANDROID)
+                add_extension(dp, dp->queryString[i].extensions,
+                        "EGL_ANDROID_swap_rectangle");
+
+            if (cnx->hooks->egl.eglQueryStringConfigANDROID)
+                add_extension(dp, dp->queryString[i].extensions,
+                        "EGL_ANDROID_query_string_config");
+        }
+    }
+            
+    // Build the extension list that depends on the current config.
+    // It is the intersection of our extension list and the
+    // underlaying EGL's extensions list
+    EGLBoolean res = EGL_FALSE;
+    for (int i=0 ; i<2 ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso && cnx->major>=0 && cnx->minor>=0) {
+            char const* const their_extensions = dp->queryString[i].extensions;            
+            char* our_extensions = strdup(dp->extensionsString);
+            char* const our_extensions_org = our_extensions;
+            char* extensions_config = (char*)calloc(strlen(our_extensions)+2, 1);
+            char* p;
+            do {
+                p = strchr(our_extensions, ' ');
+                if (p)  *p++ = 0;
+                else    p = strchr(our_extensions, 0);
+                if (strstr(their_extensions, our_extensions)) {
+                    strcat(extensions_config, our_extensions);
+                    strcat(extensions_config, " ");
+                }
+                our_extensions = p;
+            } while (*p);
+            free((void*)our_extensions_org);
+
+            // remove the trailling white space
+            if (extensions_config[0] != 0) {
+                size_t l = strlen(extensions_config) - 1; // new size
+                extensions_config[l] = 0; // remove the trailling white space
+                extensions_config = (char*)realloc(extensions_config, l+1);
+            } else {
+                extensions_config = (char*)realloc(extensions_config, 1);
+            }
+            dp->queryString[i].extensions_config = extensions_config;
+
+            EGLint n;
+            if (cnx->hooks->egl.eglGetConfigs(dp->dpys[i], 0, 0, &n)) {
+                dp->configs[i] = (EGLConfig*)malloc(sizeof(EGLConfig)*n);
+                if (dp->configs[i]) {
+                    if (cnx->hooks->egl.eglGetConfigs(
+                            dp->dpys[i], dp->configs[i], n, &dp->numConfigs[i]))
+                    {
+                        // sort the configurations so we can do binary searches
+                        qsort(  dp->configs[i],
+                                dp->numConfigs[i],
+                                sizeof(EGLConfig), cmp_configs);
+
+                        dp->numTotalConfigs += n;
+                        res = EGL_TRUE;
+                    }
+                }
+            }
+        }
+    }
+
+    if (res == EGL_TRUE) {
+        if (major != NULL) *major = 1;
+        if (minor != NULL) *minor = 2;
+        return EGL_TRUE;
+    }
+    return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+    egl_display_t* const dp = get_display(dpy);
+    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    if (android_atomic_dec(&dp->refs) != 1)
+        return EGL_TRUE;
+        
+    EGLBoolean res = EGL_FALSE;
+    for (int i=0 ; i<2 ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso) {
+            cnx->hooks->egl.eglTerminate(dp->dpys[i]);
+            
+            /* REVISIT: it's unclear what to do if eglTerminate() fails,
+             * on one end we shouldn't care, on the other end if it fails
+             * it might not be safe to call dlclose() (there could be some
+             * threads around). */
+            
+            free(dp->configs[i]);
+            free((void*)dp->queryString[i].extensions_config);
+            free((void*)dp->queryString[i].extensions);
+            dp->numConfigs[i] = 0;
+            dp->dpys[i] = EGL_NO_DISPLAY;
+            dlclose((void*)cnx->dso);
+            cnx->dso = 0;
+            res = EGL_TRUE;
+        }
+    }
+    free((void*)dp->extensionsString);
+    dp->extensionsString = 0;
+    dp->numTotalConfigs = 0;
+    clearTLS();
+    return res;
+}
+
+// ----------------------------------------------------------------------------
+// configuration
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglGetConfigs(   EGLDisplay dpy,
+                            EGLConfig *configs,
+                            EGLint config_size, EGLint *num_config)
+{
+    egl_display_t const * const dp = get_display(dpy);
+    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    GLint numConfigs = dp->numTotalConfigs;
+    if (!configs) {
+        *num_config = numConfigs;
+        return EGL_TRUE;
+    }
+    GLint n = 0;
+    for (int j=0 ; j<2 ; j++) {
+        for (int i=0 ; i<dp->numConfigs[j] && config_size ; i++) {
+            *configs++ = MAKE_CONFIG(j, i);
+            config_size--;
+            n++;
+        }
+    }    
+    
+    *num_config = n;
+    return EGL_TRUE;
+}
+
+EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
+                            EGLConfig *configs, EGLint config_size,
+                            EGLint *num_config)
+{
+    egl_display_t const * const dp = get_display(dpy);
+    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    if (configs == 0) {
+        *num_config = 0;
+        return EGL_TRUE;
+    }
+
+    EGLBoolean res = EGL_FALSE;
+    *num_config = 0;
+    for (int i=0 ; i<2 ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso) {
+            EGLint n;
+            if (cnx->hooks->egl.eglChooseConfig(
+                    dp->dpys[i], attrib_list, configs, config_size, &n))
+            {
+                // now we need to convert these client EGLConfig to our
+                // internal EGLConfig format. This is done in O(n log n).
+                for (int j=0 ; j<n ; j++) {
+                    int index = binarySearch<EGLConfig>(
+                            dp->configs[i], 0, dp->numConfigs[i]-1, configs[j]);
+                    if (index >= 0) {
+                        configs[j] = MAKE_CONFIG(i, index);
+                    } else {
+                        return setError(EGL_BAD_CONFIG, EGL_FALSE);
+                    }
+                }
+                configs += n;
+                config_size -= n;
+                *num_config += n;
+                res = EGL_TRUE;
+            }
+        }
+    }
+    return res;
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+        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);
+    if (!cnx) return EGL_FALSE;
+    return cnx->hooks->egl.eglGetConfigAttrib(
+            dp->dpys[i], dp->configs[i][index], attribute, value);
+}
+
+// ----------------------------------------------------------------------------
+// surfaces
+// ----------------------------------------------------------------------------
+
+EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
+                                    NativeWindowType window,
+                                    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);
+    if (cnx) {
+        // window must be connected upon calling underlying
+        // eglCreateWindowSurface
+        if (window) {
+            window->incRef(window);
+            if (window->connect)
+                window->connect(window);
+        }
+
+        EGLSurface surface = cnx->hooks->egl.eglCreateWindowSurface(
+                dp->dpys[i], dp->configs[i][index], window, attrib_list);       
+        if (surface != EGL_NO_SURFACE) {
+            egl_surface_t* s = new egl_surface_t(dpy, surface, window, i, cnx);
+            return s;
+        }
+        
+        // something went wrong, disconnect and free window
+        // (will disconnect() automatically)
+        if (window) {
+            window->decRef(window);
+        }        
+    }
+    return EGL_NO_SURFACE;
+}
+
+EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
+                                    NativePixmapType pixmap,
+                                    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);
+    if (cnx) {
+        EGLSurface surface = cnx->hooks->egl.eglCreatePixmapSurface(
+                dp->dpys[i], dp->configs[i][index], pixmap, attrib_list);
+        if (surface != EGL_NO_SURFACE) {
+            egl_surface_t* s = new egl_surface_t(dpy, surface, NULL, i, cnx);
+            return s;
+        }
+    }
+    return EGL_NO_SURFACE;
+}
+
+EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, 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);
+    if (cnx) {
+        EGLSurface surface = cnx->hooks->egl.eglCreatePbufferSurface(
+                dp->dpys[i], dp->configs[i][index], attrib_list);
+        if (surface != EGL_NO_SURFACE) {
+            egl_surface_t* s = new egl_surface_t(dpy, surface, NULL, i, cnx);
+            return s;
+        }
+    }
+    return EGL_NO_SURFACE;
+}
+                                    
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+    if (!validate_display_surface(dpy, surface))
+        return EGL_FALSE;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+
+    EGLBoolean result = s->cnx->hooks->egl.eglDestroySurface(
+            dp->dpys[s->impl], s->surface);
+    
+    delete s;
+    return result;
+}
+
+EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
+                            EGLint attribute, EGLint *value)
+{
+    if (!validate_display_surface(dpy, surface))
+        return EGL_FALSE;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+
+    return s->cnx->hooks->egl.eglQuerySurface(
+            dp->dpys[s->impl], s->surface, attribute, value);
+}
+
+// ----------------------------------------------------------------------------
+// contextes
+// ----------------------------------------------------------------------------
+
+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);
+    if (cnx) {
+        EGLContext context = cnx->hooks->egl.eglCreateContext(
+                dp->dpys[i], dp->configs[i][index], share_list, attrib_list);
+        if (context != EGL_NO_CONTEXT) {
+            egl_context_t* c = new egl_context_t(dpy, context, i, cnx);
+            return c;
+        }
+    }
+    return EGL_NO_CONTEXT;
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+    if (!validate_display_context(dpy, ctx))
+        return EGL_FALSE;
+    egl_display_t const * const dp = get_display(dpy);
+    egl_context_t * const c = get_context(ctx);
+    EGLBoolean result = c->cnx->hooks->egl.eglDestroyContext(
+            dp->dpys[c->impl], c->context);
+    delete c;
+    return result;
+}
+
+EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
+                            EGLSurface read, EGLContext ctx)
+{
+    egl_display_t const * const dp = get_display(dpy);
+    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    if (read == EGL_NO_SURFACE && draw  == EGL_NO_SURFACE &&
+            ctx == EGL_NO_CONTEXT) 
+    {
+        EGLBoolean result = EGL_TRUE;
+        ctx = getContext();
+        if (ctx) {
+            egl_context_t * const c = get_context(ctx);
+            result = c->cnx->hooks->egl.eglMakeCurrent(dp->dpys[c->impl], 0, 0, 0);
+            if (result == EGL_TRUE) {
+                setGlThreadSpecific(&gHooks[IMPL_NO_CONTEXT]);
+                setContext(EGL_NO_CONTEXT);
+            }
+        }
+        return result;
+    }
+
+    if (!validate_display_context(dpy, ctx))
+        return EGL_FALSE;    
+    
+    egl_context_t * const c = get_context(ctx);
+    if (draw != EGL_NO_SURFACE) {
+        egl_surface_t const * d = get_surface(draw);
+        if (!d) return setError(EGL_BAD_SURFACE, EGL_FALSE);
+        if (d->impl != c->impl)
+            return setError(EGL_BAD_MATCH, EGL_FALSE);
+        draw = d->surface;
+    }
+    if (read != EGL_NO_SURFACE) {
+        egl_surface_t const * r = get_surface(read);
+        if (!r) return setError(EGL_BAD_SURFACE, EGL_FALSE);
+        if (r->impl != c->impl)
+            return setError(EGL_BAD_MATCH, EGL_FALSE);
+        read = r->surface;
+    }
+    EGLBoolean result = c->cnx->hooks->egl.eglMakeCurrent(
+            dp->dpys[c->impl], draw, read, c->context);
+
+    if (result == EGL_TRUE) {
+        setGlThreadSpecific(c->cnx->hooks);
+        setContext(ctx);
+        c->read = read;
+        c->draw = draw;
+    }
+    return result;
+}
+
+
+EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
+                            EGLint attribute, EGLint *value)
+{
+    if (!validate_display_context(dpy, ctx))
+        return EGL_FALSE;    
+    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_context_t * const c = get_context(ctx);
+
+    return c->cnx->hooks->egl.eglQueryContext(
+            dp->dpys[c->impl], c->context, attribute, value);
+}
+
+EGLContext eglGetCurrentContext(void)
+{
+    EGLContext ctx = getContext();
+    return ctx;
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+    EGLContext ctx = getContext();
+    if (ctx) {
+        egl_context_t const * const c = get_context(ctx);
+        if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
+        switch (readdraw) {
+            case EGL_READ: return c->read;
+            case EGL_DRAW: return c->draw;            
+            default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+        }
+    }
+    return EGL_NO_SURFACE;
+}
+
+EGLDisplay eglGetCurrentDisplay(void)
+{
+    EGLContext ctx = getContext();
+    if (ctx) {
+        egl_context_t const * const c = get_context(ctx);
+        if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
+        return c->dpy;
+    }
+    return EGL_NO_DISPLAY;
+}
+
+EGLBoolean eglWaitGL(void)
+{
+    EGLBoolean res = EGL_TRUE;
+    EGLContext ctx = getContext();
+    if (ctx) {
+        egl_context_t const * const c = get_context(ctx);
+        if (!c) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+        if (uint32_t(c->impl)>=2)
+            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+        egl_connection_t* const cnx = &gEGLImpl[c->impl];
+        if (!cnx->dso) 
+            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+        res = cnx->hooks->egl.eglWaitGL();
+    }
+    return res;
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+    EGLBoolean res = EGL_TRUE;
+    EGLContext ctx = getContext();
+    if (ctx) {
+        egl_context_t const * const c = get_context(ctx);
+        if (!c) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+        if (uint32_t(c->impl)>=2)
+            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+        egl_connection_t* const cnx = &gEGLImpl[c->impl];
+        if (!cnx->dso) 
+            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+        res = cnx->hooks->egl.eglWaitNative(engine);
+    }
+    return res;
+}
+
+EGLint eglGetError(void)
+{
+    EGLint result = EGL_SUCCESS;
+    for (int i=0 ; i<2 ; i++) {
+        EGLint err = EGL_SUCCESS;
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso)
+            err = cnx->hooks->egl.eglGetError();
+        if (err!=EGL_SUCCESS && result==EGL_SUCCESS)
+            result = err;
+    }
+    if (result == EGL_SUCCESS)
+        result = getError();
+    return result;
+}
+
+void (*eglGetProcAddress(const char *procname))()
+{
+    void (*addr)();
+    addr = findProcAddress(procname, gExtentionMap, NELEM(gExtentionMap));
+    if (addr) return addr;
+
+    return NULL; // TODO: finish implementation below
+
+    addr = findProcAddress(procname, gGLExtentionMap, NELEM(gGLExtentionMap));
+    if (addr) return addr;
+    
+    addr = 0;
+    int slot = -1;
+    for (int i=0 ; i<2 ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso) {
+            if (cnx->hooks->egl.eglGetProcAddress) {
+                addr = cnx->hooks->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;
+                }
+            }
+        }
+    }
+    
+    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
+     * 
+     */
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
+{
+    if (!validate_display_surface(dpy, draw))
+        return EGL_FALSE;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(draw);
+    return s->cnx->hooks->egl.eglSwapBuffers(dp->dpys[s->impl], s->surface);
+}
+
+EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
+                            NativePixmapType target)
+{
+    if (!validate_display_surface(dpy, surface))
+        return EGL_FALSE;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+    return s->cnx->hooks->egl.eglCopyBuffers(
+            dp->dpys[s->impl], s->surface, target);
+}
+
+const char* eglQueryString(EGLDisplay dpy, EGLint name)
+{
+    egl_display_t const * const dp = get_display(dpy);
+    switch (name) {
+        case EGL_VENDOR:
+            return gVendorString;
+        case EGL_VERSION:
+            return gVersionString;
+        case EGL_EXTENSIONS:
+            return dp->extensionsString;
+        case EGL_CLIENT_APIS:
+            return gClientApiString;
+    }
+    return setError(EGL_BAD_PARAMETER, (const char *)0);
+}
+
+
+// ----------------------------------------------------------------------------
+// EGL 1.1
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglSurfaceAttrib(
+        EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+    if (!validate_display_surface(dpy, surface))
+        return EGL_FALSE;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+    if (s->cnx->hooks->egl.eglSurfaceAttrib) {
+        return s->cnx->hooks->egl.eglSurfaceAttrib(
+                dp->dpys[s->impl], s->surface, attribute, value);
+    }
+    return setError(EGL_BAD_SURFACE, EGL_FALSE);
+}
+
+EGLBoolean eglBindTexImage(
+        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    if (!validate_display_surface(dpy, surface))
+        return EGL_FALSE;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+    if (s->cnx->hooks->egl.eglBindTexImage) {
+        return s->cnx->hooks->egl.eglBindTexImage(
+                dp->dpys[s->impl], s->surface, buffer);
+    }
+    return setError(EGL_BAD_SURFACE, EGL_FALSE);
+}
+
+EGLBoolean eglReleaseTexImage(
+        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    if (!validate_display_surface(dpy, surface))
+        return EGL_FALSE;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+    if (s->cnx->hooks->egl.eglReleaseTexImage) {
+        return s->cnx->hooks->egl.eglReleaseTexImage(
+                dp->dpys[s->impl], s->surface, buffer);
+    }
+    return setError(EGL_BAD_SURFACE, EGL_FALSE);
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+    egl_display_t * const dp = get_display(dpy);
+    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    EGLBoolean res = EGL_TRUE;
+    for (int i=0 ; i<2 ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso) {
+            if (cnx->hooks->egl.eglSwapInterval) {
+                if (cnx->hooks->egl.eglSwapInterval(dp->dpys[i], interval) == EGL_FALSE) {
+                    res = EGL_FALSE;
+                }
+            }
+        }
+    }
+    return res;
+}
+
+
+// ----------------------------------------------------------------------------
+// EGL 1.2
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglWaitClient(void)
+{
+    EGLBoolean res = EGL_TRUE;
+    EGLContext ctx = getContext();
+    if (ctx) {
+        egl_context_t const * const c = get_context(ctx);
+        if (!c) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+        if (uint32_t(c->impl)>=2)
+            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+        egl_connection_t* const cnx = &gEGLImpl[c->impl];
+        if (!cnx->dso) 
+            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+        if (cnx->hooks->egl.eglWaitClient) {
+            res = cnx->hooks->egl.eglWaitClient();
+        } else {
+            res = cnx->hooks->egl.eglWaitGL();
+        }
+    }
+    return res;
+}
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+    // bind this API on all EGLs
+    EGLBoolean res = EGL_TRUE;
+    for (int i=0 ; i<2 ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso) {
+            if (cnx->hooks->egl.eglBindAPI) {
+                if (cnx->hooks->egl.eglBindAPI(api) == EGL_FALSE) {
+                    res = EGL_FALSE;
+                }
+            }
+        }
+    }
+    return res;
+}
+
+EGLenum eglQueryAPI(void)
+{
+    for (int i=0 ; i<2 ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso) {
+            if (cnx->hooks->egl.eglQueryAPI) {
+                // the first one we find is okay, because they all
+                // should be the same
+                return cnx->hooks->egl.eglQueryAPI();
+            }
+        }
+    }
+    // or, it can only be OpenGL ES
+    return EGL_OPENGL_ES_API;
+}
+
+EGLBoolean eglReleaseThread(void)
+{
+    for (int i=0 ; i<2 ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso) {
+            if (cnx->hooks->egl.eglReleaseThread) {
+                cnx->hooks->egl.eglReleaseThread();
+            }
+        }
+    }
+    clearTLS();    
+    return EGL_TRUE;
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(
+          EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
+          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);
+    if (!cnx) return EGL_FALSE;
+    if (cnx->hooks->egl.eglCreatePbufferFromClientBuffer) {
+        return cnx->hooks->egl.eglCreatePbufferFromClientBuffer(
+                dp->dpys[i], buftype, buffer, dp->configs[i][index], attrib_list);
+    }
+    return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
+}
+
+// ----------------------------------------------------------------------------
+// Android extentions
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglSwapRectangleANDROID(
+        EGLDisplay dpy, EGLSurface draw,
+        EGLint l, EGLint t, EGLint w, EGLint h)
+{    
+    if (!validate_display_surface(dpy, draw))
+        return EGL_FALSE;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(draw);
+    if (s->cnx->hooks->egl.eglSwapRectangleANDROID) {
+        return s->cnx->hooks->egl.eglSwapRectangleANDROID(
+                dp->dpys[s->impl], s->surface, l, t, w, h);
+    }
+    return setError(EGL_BAD_SURFACE, EGL_FALSE);
+}
+
+const char* eglQueryStringConfigANDROID(
+        EGLDisplay dpy, EGLConfig config, EGLint name)
+{
+    egl_display_t const* dp = 0;
+    int i=0, index=0;
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    if (cnx) {
+        return dp->queryString[i].extensions_config;
+    }
+    return setError(EGL_BAD_PARAMETER, (const char *)0);
+}
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
new file mode 100644
index 0000000..a3dff76
--- /dev/null
+++ b/opengl/libagl/Android.mk
@@ -0,0 +1,34 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# Build the software OpenGL ES library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	egl.cpp                     \
+	state.cpp		            \
+	texture.cpp		            \
+    Tokenizer.cpp               \
+    TokenManager.cpp            \
+    TextureObjectManager.cpp    \
+    BufferObjectManager.cpp     \
+	array.cpp.arm		        \
+	fp.cpp.arm		            \
+	light.cpp.arm		        \
+	matrix.cpp.arm		        \
+	mipmap.cpp.arm		        \
+	primitives.cpp.arm	        \
+	vertex.cpp.arm
+
+ifeq ($(TARGET_ARCH),arm)
+	LOCAL_SRC_FILES += fixed_asm.S iterators.S
+	LOCAL_CFLAGS += -fstrict-aliasing
+endif
+
+LOCAL_SHARED_LIBRARIES := libcutils libutils libpixelflinger
+LOCAL_LDLIBS := -lpthread -ldl
+LOCAL_MODULE:= libagl
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/libagl/BufferObjectManager.cpp b/opengl/libagl/BufferObjectManager.cpp
new file mode 100644
index 0000000..6bf28ee
--- /dev/null
+++ b/opengl/libagl/BufferObjectManager.cpp
@@ -0,0 +1,103 @@
+/*
+ ** 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.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <utils/Atomic.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/Errors.h>
+
+#include <GLES/gl.h>
+
+#include "BufferObjectManager.h"
+
+
+namespace android {
+
+using namespace gl;
+
+// ----------------------------------------------------------------------------
+
+EGLBufferObjectManager::EGLBufferObjectManager() 
+: TokenManager(), mCount(0)
+{
+}
+
+EGLBufferObjectManager::~EGLBufferObjectManager()
+{
+    // destroy all the buffer objects and their storage
+    GLsizei n = mBuffers.size();
+    for (GLsizei i=0 ; i<n ; i++) {
+        buffer_t* bo = mBuffers.valueAt(i);
+        free(bo->data);
+        delete bo;
+    }
+}
+
+buffer_t const* EGLBufferObjectManager::bind(GLuint buffer)
+{
+    Mutex::Autolock _l(mLock);
+    int32_t i = mBuffers.indexOfKey(buffer);
+    if (i >= 0) {
+        return mBuffers.valueAt(i);
+    }
+    buffer_t* bo = new buffer_t;
+    bo->data = 0;
+    bo->usage = GL_STATIC_DRAW;
+    bo->size = 0;
+    bo->name = buffer;
+    mBuffers.add(buffer, bo);
+    return bo;
+}
+
+int EGLBufferObjectManager::allocateStore(buffer_t* bo,
+        GLsizeiptr size, GLenum usage)
+{
+    Mutex::Autolock _l(mLock);
+    if (size != bo->size) {
+       uint8_t* data = (uint8_t*)malloc(size);
+        if (data == 0)
+            return -1;
+        free(bo->data);
+        bo->data = data;
+        bo->size = size;
+    }
+    bo->usage = usage;
+    return 0;
+}
+
+void EGLBufferObjectManager::deleteBuffers(GLsizei n, const GLuint* buffers)
+{
+    Mutex::Autolock _l(mLock);
+    while (n--) {
+        const GLuint t = *buffers++;
+        if (t) {
+            int32_t index = mBuffers.indexOfKey(t);
+            if (index >= 0) {
+                buffer_t* bo = mBuffers.valueAt(index);
+                free(bo->data);
+                mBuffers.removeItemsAt(index);
+                delete bo;
+            }
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/opengl/libagl/BufferObjectManager.h b/opengl/libagl/BufferObjectManager.h
new file mode 100644
index 0000000..9e9340a
--- /dev/null
+++ b/opengl/libagl/BufferObjectManager.h
@@ -0,0 +1,85 @@
+/*
+ **
+ ** Copyright 2006, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License"); 
+ ** you may not use this file except in compliance with the License. 
+ ** You may obtain a copy of the License at 
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0 
+ **
+ ** Unless required by applicable law or agreed to in writing, software 
+ ** distributed under the License is distributed on an "AS IS" BASIS, 
+ ** WITHOUT 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_BUFFER_OBJECT_MANAGER_H
+#define ANDROID_OPENGLES_BUFFER_OBJECT_MANAGER_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <utils/Atomic.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/Errors.h>
+
+#include <GLES/gl.h>
+
+#include "Tokenizer.h"
+#include "TokenManager.h"
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+namespace gl {
+
+struct buffer_t {
+    GLsizeiptr      size;
+    GLenum          usage;
+    uint8_t*        data;
+    uint32_t        name;
+};
+
+};
+
+class EGLBufferObjectManager : public TokenManager
+{
+public:
+    EGLBufferObjectManager();
+    ~EGLBufferObjectManager();
+
+    // protocol for sp<>
+    inline  void    incStrong(const void* id) const;
+    inline  void    decStrong(const void* id) const;
+    typedef void    weakref_type;
+
+    gl::buffer_t const* bind(GLuint buffer);
+    int                 allocateStore(gl::buffer_t* bo, GLsizeiptr size, GLenum usage);
+    void                deleteBuffers(GLsizei n, const GLuint* buffers);
+
+private:
+    mutable volatile int32_t            mCount;
+    mutable Mutex                       mLock;
+    KeyedVector<GLuint, gl::buffer_t*>  mBuffers;
+};
+
+void EGLBufferObjectManager::incStrong(const void* id) const {
+    android_atomic_inc(&mCount);
+}
+void EGLBufferObjectManager::decStrong(const void* id) const {
+    if (android_atomic_dec(&mCount) == 1) {
+        delete this;
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_BUFFER_OBJECT_MANAGER_H
+
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
new file mode 100644
index 0000000..12fae63
--- /dev/null
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -0,0 +1,309 @@
+/*
+ ** Copyright 2006, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License"); 
+ ** you may not use this file except in compliance with the License. 
+ ** You may obtain a copy of the License at 
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0 
+ **
+ ** Unless required by applicable law or agreed to in writing, software 
+ ** distributed under the License is distributed on an "AS IS" BASIS, 
+ ** WITHOUT 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 <stdlib.h>
+#include "context.h"
+#include "TextureObjectManager.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+EGLTextureObject::EGLTextureObject()
+    : mCount(0), mSize(0)
+{
+    init();
+}
+
+EGLTextureObject::~EGLTextureObject()
+{
+    if (!direct) {
+        if (mSize && surface.data)
+            free(surface.data);
+        if (mMipmaps)
+            freeMipmaps();
+    }
+}
+
+void EGLTextureObject::init()
+{
+    memset(&surface, 0, sizeof(surface));
+    surface.version = sizeof(surface);
+    mMipmaps = 0;
+    mNumExtraLod = 0;
+    mIsComplete = false;
+    wraps = GL_REPEAT;
+    wrapt = GL_REPEAT;
+    min_filter = GL_LINEAR;
+    mag_filter = GL_LINEAR;
+    internalformat = 0;
+    memset(crop_rect, 0, sizeof(crop_rect));
+    generate_mipmap = GL_FALSE;
+    direct = GL_FALSE;
+}
+
+void EGLTextureObject::copyParameters(const sp<EGLTextureObject>& old)
+{
+    wraps = old->wraps;
+    wrapt = old->wrapt;
+    min_filter = old->min_filter;
+    mag_filter = old->mag_filter;
+    memcpy(crop_rect, old->crop_rect, sizeof(crop_rect));
+    generate_mipmap = old->generate_mipmap;
+    direct = old->direct;
+}
+
+status_t EGLTextureObject::allocateMipmaps()
+{
+    // here, by construction, mMipmaps=0 && mNumExtraLod=0
+
+    if (!surface.data)
+        return NO_INIT;
+
+    int w = surface.width;
+    int h = surface.height;
+    const int numLods = 31 - gglClz(max(w,h));
+    if (numLods <= 0)
+        return NO_ERROR;
+
+    mMipmaps = (GGLSurface*)malloc(numLods * sizeof(GGLSurface));
+    if (!mMipmaps)
+        return NO_MEMORY;
+
+    memset(mMipmaps, 0, numLods * sizeof(GGLSurface));
+    mNumExtraLod = numLods;
+    return NO_ERROR;
+}
+
+void EGLTextureObject::freeMipmaps()
+{
+    if (mMipmaps) {
+        for (int i=0 ; i<mNumExtraLod ; i++) {
+            if (mMipmaps[i].data) {
+                free(mMipmaps[i].data);
+            }
+        }
+        free(mMipmaps);
+        mMipmaps = 0;
+        mNumExtraLod = 0;
+    }
+}
+
+const GGLSurface& EGLTextureObject::mip(int lod) const
+{
+    if (lod<=0 || !mMipmaps)
+        return surface;
+    lod = min(lod-1, mNumExtraLod-1);
+    return mMipmaps[lod];
+}
+
+GGLSurface& EGLTextureObject::editMip(int lod)
+{
+    return const_cast<GGLSurface&>(mip(lod));
+}
+
+status_t EGLTextureObject::setSurface(GGLSurface const* s)
+{
+    // XXX: glFlush() on 's'
+    if (mSize && surface.data) {
+        free(surface.data);
+    }
+    surface = *s;
+    internalformat = 0;
+
+    // we should keep the crop_rect, but it's delicate because
+    // the new size of the surface could make it invalid.
+    // so for now, we just loose it.
+    memset(crop_rect, 0, sizeof(crop_rect));
+
+    // it would be nice id we could keep the generate_mipmap flag
+    // we would have to generate them right now though.
+    generate_mipmap = GL_FALSE;
+
+    direct = GL_TRUE;
+    mSize = 0;  // we don't own this surface
+    if (mMipmaps)
+        freeMipmaps();
+    mIsComplete = true;
+    return NO_ERROR;
+}
+
+status_t EGLTextureObject::reallocate(
+        GLint level, int w, int h, int s,
+        int format, int compressedFormat, int bpr)
+{
+    const size_t size = h * bpr;
+    if (level == 0) 
+    {
+        if (size!=mSize || !surface.data) {
+            if (mSize && surface.data) {
+                free(surface.data);
+            }
+            surface.data = (GGLubyte*)malloc(size);
+            if (!surface.data) {
+                mSize = 0;
+                mIsComplete = false;
+                return NO_MEMORY;
+            }
+            mSize = size;
+        }
+        surface.version = sizeof(GGLSurface);
+        surface.width  = w;
+        surface.height = h;
+        surface.stride = s;
+        surface.format = format;
+        surface.compressedFormat = compressedFormat;
+        if (mMipmaps)
+            freeMipmaps();
+        mIsComplete = true;
+    }
+    else
+    {
+        if (!mMipmaps) {
+            if (allocateMipmaps() != NO_ERROR)
+                return NO_MEMORY;
+        }
+
+        LOGW_IF(level-1 >= mNumExtraLod, 
+                "specifying mipmap level %d, but # of level is %d",
+                level, mNumExtraLod+1);        
+
+        GGLSurface& mipmap = editMip(level);
+        if (mipmap.data)
+            free(mipmap.data);
+
+        mipmap.data = (GGLubyte*)malloc(size);
+        if (!mipmap.data) {
+            memset(&mipmap, 0, sizeof(GGLSurface));
+            mIsComplete = false;
+            return NO_MEMORY;
+        }
+
+        mipmap.version = sizeof(GGLSurface);
+        mipmap.width  = w;
+        mipmap.height = h;
+        mipmap.stride = s;
+        mipmap.format = format;
+        mipmap.compressedFormat = compressedFormat;
+
+        // check if the texture is complete
+        mIsComplete = true;
+        const GGLSurface* prev = &surface;
+        for (int i=0 ; i<mNumExtraLod ; i++) {
+            const GGLSurface* curr = mMipmaps + i;
+            if (curr->format != surface.format) {
+                mIsComplete = false;
+                break;
+            }
+
+            uint32_t w = (prev->width  >> 1) ? : 1;
+            uint32_t h = (prev->height >> 1) ? : 1;
+            if (w != curr->width || h != curr->height) {
+                mIsComplete = false;
+                break;
+            }
+            prev = curr;
+        }
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+EGLSurfaceManager::EGLSurfaceManager()
+    : TokenManager(), mCount(0)
+{
+}
+
+EGLSurfaceManager::~EGLSurfaceManager()
+{
+    // everything gets freed automatically here...
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::createTexture(GLuint name)
+{
+    sp<EGLTextureObject> result;
+
+    Mutex::Autolock _l(mLock);
+    if (mTextures.indexOfKey(name) >= 0)
+        return result; // already exists!
+
+    result = new EGLTextureObject();
+
+    status_t err = mTextures.add(name, result);
+    if (err < 0)
+        result.clear();
+
+    return result;
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::removeTexture(GLuint name)
+{
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mTextures.indexOfKey(name);
+    if (index >= 0) {
+        sp<EGLTextureObject> result(mTextures.valueAt(index));
+        mTextures.removeItemsAt(index);
+        return result;
+    }
+    return 0;
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::replaceTexture(GLuint name)
+{
+    sp<EGLTextureObject> tex;
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mTextures.indexOfKey(name);
+    if (index >= 0) {
+        const sp<EGLTextureObject>& old = mTextures.valueAt(index);
+        const uint32_t refs = old->getStrongCount();
+        if (ggl_likely(refs == 1)) {
+            // we're the only owner
+            tex = old;
+        } else {
+            // keep the texture's parameters
+            tex = new EGLTextureObject();
+            tex->copyParameters(old);
+            mTextures.removeItemsAt(index);
+            mTextures.add(name, tex);
+        }
+    }
+    return tex;
+}
+
+void EGLSurfaceManager::deleteTextures(GLsizei n, const GLuint *tokens)
+{
+    // free all texures
+    Mutex::Autolock _l(mLock);
+    for (GLsizei i=0 ; i<n ; i++) {
+        const GLuint t(*tokens++);
+        if (t) {
+            mTextures.removeItem(t);
+        }
+    }
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::texture(GLuint name)
+{
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mTextures.indexOfKey(name);
+    if (index >= 0)
+        return mTextures.valueAt(index);
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h
new file mode 100644
index 0000000..74ed1a4
--- /dev/null
+++ b/opengl/libagl/TextureObjectManager.h
@@ -0,0 +1,140 @@
+/*
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_SURFACE_H
+#define ANDROID_OPENGLES_SURFACE_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <utils/Atomic.h>
+#include <utils/threads.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/Errors.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+#include "Tokenizer.h"
+#include "TokenManager.h"
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class EGLTextureObject
+{
+public:
+                    EGLTextureObject();
+                   ~EGLTextureObject();
+
+    // protocol for sp<>
+    inline  void        incStrong(const void* id) const;
+    inline  void        decStrong(const void* id) const;
+    inline  uint32_t    getStrongCount() const;
+
+    status_t            setSurface(GGLSurface const* s);
+    status_t            reallocate(GLint level,
+                            int w, int h, int s,
+                            int format, int compressedFormat, int bpr);
+    inline  size_t      size() const;
+    const GGLSurface&   mip(int lod) const;
+    GGLSurface&         editMip(int lod);
+    bool                hasMipmaps() const { return mMipmaps!=0; }
+    bool                isComplete() const { return mIsComplete; }
+    void                copyParameters(const sp<EGLTextureObject>& old);
+
+private:
+        status_t        allocateMipmaps();
+            void        freeMipmaps();
+            void        init();
+    mutable int32_t     mCount;
+    size_t              mSize;
+    GGLSurface          *mMipmaps;
+    int                 mNumExtraLod;
+    bool                mIsComplete;
+
+public:
+    GGLSurface          surface;
+    GLenum              wraps;
+    GLenum              wrapt;
+    GLenum              min_filter;
+    GLenum              mag_filter;
+    GLenum              internalformat;
+    GLint               crop_rect[4];
+    GLint               generate_mipmap;
+    GLint               direct;
+};
+
+void EGLTextureObject::incStrong(const void* id) const {
+    android_atomic_inc(&mCount);
+}
+void EGLTextureObject::decStrong(const void* id) const {
+    if (android_atomic_dec(&mCount) == 1) {
+        delete this;
+    }
+}
+uint32_t EGLTextureObject::getStrongCount() const {
+    return mCount;
+}
+size_t EGLTextureObject::size() const {
+    return mSize;
+}
+
+// ----------------------------------------------------------------------------
+
+class EGLSurfaceManager : public TokenManager
+{
+public:
+                EGLSurfaceManager();
+                ~EGLSurfaceManager();
+
+    // protocol for sp<>
+    inline  void    incStrong(const void* id) const;
+    inline  void    decStrong(const void* id) const;
+    typedef void    weakref_type;
+
+    sp<EGLTextureObject>    createTexture(GLuint name);
+    sp<EGLTextureObject>    removeTexture(GLuint name);
+    sp<EGLTextureObject>    replaceTexture(GLuint name);
+    void                    deleteTextures(GLsizei n, const GLuint *tokens);
+    sp<EGLTextureObject>    texture(GLuint name);
+
+private:
+    mutable int32_t                             mCount;
+    mutable Mutex                               mLock;
+    KeyedVector< GLuint, sp<EGLTextureObject> > mTextures;
+};
+
+void EGLSurfaceManager::incStrong(const void* id) const {
+    android_atomic_inc(&mCount);
+}
+void EGLSurfaceManager::decStrong(const void* id) const {
+    if (android_atomic_dec(&mCount) == 1) {
+        delete this;
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_SURFACE_H
+
diff --git a/opengl/libagl/TokenManager.cpp b/opengl/libagl/TokenManager.cpp
new file mode 100644
index 0000000..eea6025
--- /dev/null
+++ b/opengl/libagl/TokenManager.cpp
@@ -0,0 +1,62 @@
+/* libs/opengles/surface.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 <stdlib.h>
+#include "TokenManager.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+TokenManager::TokenManager()
+{
+    // token 0 is always reserved
+    mTokenizer.reserve(0);
+}
+
+TokenManager::~TokenManager()
+{
+}
+
+status_t TokenManager::getToken(GLsizei n, GLuint *tokens)
+{
+    Mutex::Autolock _l(mLock);
+    for (GLsizei i=0 ; i<n ; i++)
+        *tokens++ = mTokenizer.acquire();
+    return NO_ERROR;
+}
+
+void TokenManager::recycleTokens(GLsizei n, const GLuint *tokens)
+{
+    Mutex::Autolock _l(mLock);
+    for (int i=0 ; i<n ; i++) {
+        const GLuint token = *tokens++;
+        if (token) {
+            mTokenizer.release(token);
+        }
+    }
+}
+
+bool TokenManager::isTokenValid(GLuint token) const
+{
+    Mutex::Autolock _l(mLock);
+    return mTokenizer.isAcquired(token);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/opengl/libagl/TokenManager.h b/opengl/libagl/TokenManager.h
new file mode 100644
index 0000000..49c1469
--- /dev/null
+++ b/opengl/libagl/TokenManager.h
@@ -0,0 +1,53 @@
+/*
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_TOKEN_MANAGER_H
+#define ANDROID_OPENGLES_TOKEN_MANAGER_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+#include <GLES/gl.h>
+
+#include "Tokenizer.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class TokenManager
+{
+public:
+                TokenManager();
+                ~TokenManager();
+
+    status_t    getToken(GLsizei n, GLuint *tokens);
+    void        recycleTokens(GLsizei n, const GLuint *tokens);
+    bool        isTokenValid(GLuint token) const;
+
+private:
+    mutable Mutex   mLock;
+    Tokenizer       mTokenizer;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_TOKEN_MANAGER_H
+
diff --git a/opengl/libagl/Tokenizer.cpp b/opengl/libagl/Tokenizer.cpp
new file mode 100644
index 0000000..9b3ea1a
--- /dev/null
+++ b/opengl/libagl/Tokenizer.cpp
@@ -0,0 +1,173 @@
+/* libs/opengles/Tokenizer.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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();
+    LOGD("Tokenizer (%p, size = %u)\n", this, c);
+    for (size_t i=0 ; i<c ; i++) {
+        LOGD("%u: (%u, %u)\n", i, ranges[i].first, ranges[i].length);
+    }
+}
+
+}; // namespace android
+
diff --git a/opengl/libagl/Tokenizer.h b/opengl/libagl/Tokenizer.h
new file mode 100644
index 0000000..ac555cb
--- /dev/null
+++ b/opengl/libagl/Tokenizer.h
@@ -0,0 +1,59 @@
+/* libs/opengles/Tokenizer.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_TOKENIZER_H
+#define ANDROID_OPENGLES_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_OPENGLES_TOKENIZER_H
diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp
new file mode 100644
index 0000000..1f6757d
--- /dev/null
+++ b/opengl/libagl/array.cpp
@@ -0,0 +1,1557 @@
+/* 
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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"
+
+// ----------------------------------------------------------------------------
+
+#define VC_CACHE_STATISTICS     0
+#define VC_CACHE_TYPE_NONE      0
+#define VC_CACHE_TYPE_INDEXED   1
+#define VC_CACHE_TYPE_LRU       2
+#define VC_CACHE_TYPE           VC_CACHE_TYPE_INDEXED
+
+#if VC_CACHE_STATISTICS
+#include <utils/Timers.h>
+#endif
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+static void validate_arrays(ogles_context_t* c, GLenum mode);
+
+static void compileElements__generic(ogles_context_t*,
+        vertex_t*, GLint, GLsizei);
+static void compileElement__generic(ogles_context_t*,
+        vertex_t*, GLint);
+
+static void drawPrimitivesPoints(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesLineStrip(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesLineLoop(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesLines(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesTriangleStrip(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesTriangleFan(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesTriangles(ogles_context_t*, GLint, GLsizei);
+
+static void drawIndexedPrimitivesPoints(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesLineStrip(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesLineLoop(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesLines(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesTriangleStrip(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesTriangleFan(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesTriangles(ogles_context_t*,
+        GLsizei, const GLvoid*);
+
+// ----------------------------------------------------------------------------
+
+typedef void (*arrays_prims_fct_t)(ogles_context_t*, GLint, GLsizei);
+static const arrays_prims_fct_t drawArraysPrims[] = {
+    drawPrimitivesPoints,
+    drawPrimitivesLines,
+    drawPrimitivesLineLoop,
+    drawPrimitivesLineStrip,
+    drawPrimitivesTriangles,
+    drawPrimitivesTriangleStrip,
+    drawPrimitivesTriangleFan
+};
+
+typedef void (*elements_prims_fct_t)(ogles_context_t*, GLsizei, const GLvoid*);
+static const elements_prims_fct_t drawElementsPrims[] = {
+    drawIndexedPrimitivesPoints,
+    drawIndexedPrimitivesLines,
+    drawIndexedPrimitivesLineLoop,
+    drawIndexedPrimitivesLineStrip,
+    drawIndexedPrimitivesTriangles,
+    drawIndexedPrimitivesTriangleStrip,
+    drawIndexedPrimitivesTriangleFan
+};
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void ogles_init_array(ogles_context_t* c)
+{
+    c->arrays.vertex.size = 4;
+    c->arrays.vertex.type = GL_FLOAT;
+    c->arrays.color.size = 4;
+    c->arrays.color.type = GL_FLOAT;
+    c->arrays.normal.size = 4;
+    c->arrays.normal.type = GL_FLOAT;
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        c->arrays.texture[i].size = 4;
+        c->arrays.texture[i].type = GL_FLOAT;
+    }
+    c->vc.init();
+
+    if (!c->vc.vBuffer) {
+        // this could have failed
+        ogles_error(c, GL_OUT_OF_MEMORY);
+    }
+}
+
+void ogles_uninit_array(ogles_context_t* c)
+{
+    c->vc.uninit();
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Array fetchers
+#endif
+
+static void currentColor(ogles_context_t* c, GLfixed* v, const GLvoid*) {
+    memcpy(v, c->current.color.v, sizeof(vec4_t));
+}
+static void currentColor_clamp(ogles_context_t* c, GLfixed* v, const GLvoid*) {
+    memcpy(v, c->currentColorClamped.v, sizeof(vec4_t));
+}
+static void currentNormal(ogles_context_t* c, GLfixed* v, const GLvoid*) {
+    memcpy(v, c->currentNormal.v, sizeof(vec3_t));
+}
+static void currentTexCoord(ogles_context_t* c, GLfixed* v, const GLvoid*) {
+    memcpy(v, c->current.texture[c->arrays.tmu].v, sizeof(vec4_t));
+}
+
+
+static void fetchNop(ogles_context_t*, GLfixed*, const GLvoid*) {
+}
+static void fetch2b(ogles_context_t*, GLfixed* v, const GLbyte* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+}
+static void fetch2s(ogles_context_t*, GLfixed* v, const GLshort* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+}
+static void fetch2x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    memcpy(v, p, 2*sizeof(GLfixed));
+}
+static void fetch2f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglFloatToFixed(p[0]);
+    v[1] = gglFloatToFixed(p[1]);
+}
+static void fetch3b(ogles_context_t*, GLfixed* v, const GLbyte* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+    v[2] = gglIntToFixed(p[2]);
+}
+static void fetch3s(ogles_context_t*, GLfixed* v, const GLshort* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+    v[2] = gglIntToFixed(p[2]);
+}
+static void fetch3x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    memcpy(v, p, 3*sizeof(GLfixed));
+}
+static void fetch3f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglFloatToFixed(p[0]);
+    v[1] = gglFloatToFixed(p[1]);
+    v[2] = gglFloatToFixed(p[2]);
+}
+static void fetch4b(ogles_context_t*, GLfixed* v, const GLbyte* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+    v[2] = gglIntToFixed(p[2]);
+    v[3] = gglIntToFixed(p[3]);
+}
+static void fetch4s(ogles_context_t*, GLfixed* v, const GLshort* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+    v[2] = gglIntToFixed(p[2]);
+    v[3] = gglIntToFixed(p[3]);
+}
+static void fetch4x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    memcpy(v, p, 4*sizeof(GLfixed));
+}
+static void fetch4f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglFloatToFixed(p[0]);
+    v[1] = gglFloatToFixed(p[1]);
+    v[2] = gglFloatToFixed(p[2]);
+    v[3] = gglFloatToFixed(p[3]);
+}
+static void fetchExpand4ub(ogles_context_t*, GLfixed* v, const GLubyte* p) {
+    v[0] = GGL_UB_TO_X(p[0]);
+    v[1] = GGL_UB_TO_X(p[1]);
+    v[2] = GGL_UB_TO_X(p[2]);
+    v[3] = GGL_UB_TO_X(p[3]);
+}
+static void fetchClamp4x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    v[0] = gglClampx(p[0]);
+    v[1] = gglClampx(p[1]);
+    v[2] = gglClampx(p[2]);
+    v[3] = gglClampx(p[3]);
+}
+static void fetchClamp4f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglClampx(gglFloatToFixed(p[0]));
+    v[1] = gglClampx(gglFloatToFixed(p[1]));
+    v[2] = gglClampx(gglFloatToFixed(p[2]));
+    v[3] = gglClampx(gglFloatToFixed(p[3]));
+}
+static void fetchExpand3ub(ogles_context_t*, GLfixed* v, const GLubyte* p) {
+    v[0] = GGL_UB_TO_X(p[0]);
+    v[1] = GGL_UB_TO_X(p[1]);
+    v[2] = GGL_UB_TO_X(p[2]);
+    v[3] = 0x10000;
+}
+static void fetchClamp3x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    v[0] = gglClampx(p[0]);
+    v[1] = gglClampx(p[1]);
+    v[2] = gglClampx(p[2]);
+    v[3] = 0x10000;
+}
+static void fetchClamp3f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglClampx(gglFloatToFixed(p[0]));
+    v[1] = gglClampx(gglFloatToFixed(p[1]));
+    v[2] = gglClampx(gglFloatToFixed(p[2]));
+    v[3] = 0x10000;
+}
+static void fetchExpand3b(ogles_context_t*, GLfixed* v, const GLbyte* p) {
+    v[0] = GGL_B_TO_X(p[0]);
+    v[1] = GGL_B_TO_X(p[1]);
+    v[2] = GGL_B_TO_X(p[2]);
+}
+static void fetchExpand3s(ogles_context_t*, GLfixed* v, const GLshort* p) {
+    v[0] = GGL_S_TO_X(p[0]);
+    v[1] = GGL_S_TO_X(p[1]);
+    v[2] = GGL_S_TO_X(p[2]);
+}
+
+typedef array_t::fetcher_t fn_t; 
+
+static const fn_t color_fct[2][16] = { // size={3,4}, type={ub,f,x}
+    { 0, (fn_t)fetchExpand3ub, 0, 0, 0, 0,
+         (fn_t)fetch3f, 0, 0, 0, 0, 0,
+         (fn_t)fetch3x },
+    { 0, (fn_t)fetchExpand4ub, 0, 0, 0, 0,
+         (fn_t)fetch4f, 0, 0, 0, 0, 0,
+         (fn_t)fetch4x },
+};
+static const fn_t color_clamp_fct[2][16] = { // size={3,4}, type={ub,f,x}
+    { 0, (fn_t)fetchExpand3ub, 0, 0, 0, 0,
+         (fn_t)fetchClamp3f, 0, 0, 0, 0, 0,
+         (fn_t)fetchClamp3x },
+    { 0, (fn_t)fetchExpand4ub, 0, 0, 0, 0,
+         (fn_t)fetchClamp4f, 0, 0, 0, 0, 0,
+         (fn_t)fetchClamp4x },
+};
+static const fn_t normal_fct[1][16] = { // size={3}, type={b,s,f,x}
+    { (fn_t)fetchExpand3b, 0,
+      (fn_t)fetchExpand3s, 0, 0, 0,
+      (fn_t)fetch3f, 0, 0, 0, 0, 0,
+      (fn_t)fetch3x },
+};
+static const fn_t vertex_fct[3][16] = { // size={2,3,4}, type={b,s,f,x}
+    { (fn_t)fetch2b, 0,
+      (fn_t)fetch2s, 0, 0, 0,
+      (fn_t)fetch2f, 0, 0, 0, 0, 0,
+      (fn_t)fetch3x },
+    { (fn_t)fetch3b, 0,
+      (fn_t)fetch3s, 0, 0, 0,
+      (fn_t)fetch3f, 0, 0, 0, 0, 0,
+      (fn_t)fetch3x },
+    { (fn_t)fetch4b, 0,
+      (fn_t)fetch4s, 0, 0, 0,
+      (fn_t)fetch4f, 0, 0, 0, 0, 0,
+      (fn_t)fetch4x }
+};
+static const fn_t texture_fct[3][16] = { // size={2,3,4}, type={b,s,f,x}
+    { (fn_t)fetch2b, 0,
+      (fn_t)fetch2s, 0, 0, 0,
+      (fn_t)fetch2f, 0, 0, 0, 0, 0,
+      (fn_t)fetch2x },
+    { (fn_t)fetch3b, 0,
+      (fn_t)fetch3s, 0, 0, 0,
+      (fn_t)fetch3f, 0, 0, 0, 0, 0,
+      (fn_t)fetch3x },
+    { (fn_t)fetch4b, 0,
+      (fn_t)fetch4s, 0, 0, 0,
+      (fn_t)fetch4f, 0, 0, 0, 0, 0,
+      (fn_t)fetch4x }
+};
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark array_t
+#endif
+
+void array_t::init(
+        GLint size, GLenum type, GLsizei stride,
+        const GLvoid *pointer, const buffer_t* bo, GLsizei count)
+{
+    if (!stride) {
+        stride = size;
+        switch (type) {
+        case GL_SHORT:
+        case GL_UNSIGNED_SHORT:
+            stride *= 2;
+            break;
+        case GL_FLOAT:
+        case GL_FIXED:
+            stride *= 4;
+            break;
+        }
+    }
+    this->size = size;
+    this->type = type;
+    this->stride = stride;
+    this->pointer = pointer;
+    this->bo = bo;
+    this->bounds = count;
+}
+
+inline void array_t::resolve() 
+{
+    physical_pointer = (bo) ? (bo->data + uintptr_t(pointer)) : pointer;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark vertex_cache_t
+#endif
+
+void vertex_cache_t::init()
+{
+    // make sure the size of vertex_t allows cache-line alignment
+    CTA<(sizeof(vertex_t) & 0x1F) == 0> assertAlignedSize;
+
+    const int align = 32;
+    const size_t s = VERTEX_BUFFER_SIZE + VERTEX_CACHE_SIZE;
+    const size_t size = s*sizeof(vertex_t) + align;
+    base = malloc(size);
+    if (base) {
+        memset(base, 0, size);
+        vBuffer = (vertex_t*)((size_t(base) + align - 1) & ~(align-1));
+        vCache = vBuffer + VERTEX_BUFFER_SIZE;
+        sequence = 0;
+    }
+}
+
+void vertex_cache_t::uninit()
+{
+    free(base);
+    base = vBuffer = vCache = 0;
+}
+
+void vertex_cache_t::clear()
+{
+#if VC_CACHE_STATISTICS
+    startTime = systemTime(SYSTEM_TIME_THREAD);
+    total = 0;
+    misses = 0;
+#endif
+
+#if VC_CACHE_TYPE == VC_CACHE_TYPE_LRU
+    vertex_t* v = vBuffer;
+    size_t count = VERTEX_BUFFER_SIZE + VERTEX_CACHE_SIZE;
+    do {
+        v->mru = 0;
+        v++;
+    } while (--count);
+#endif
+
+    sequence += INDEX_SEQ;
+    if (sequence >= 0x80000000LU) {
+        sequence = INDEX_SEQ;
+        vertex_t* v = vBuffer;
+        size_t count = VERTEX_BUFFER_SIZE + VERTEX_CACHE_SIZE;
+        do {
+            v->index = 0;
+            v++;
+        } while (--count);
+    }
+}
+
+void vertex_cache_t::dump_stats(GLenum mode)
+{
+#if VC_CACHE_STATISTICS
+    nsecs_t time = systemTime(SYSTEM_TIME_THREAD) - startTime;
+    uint32_t hits = total - misses;
+    uint32_t prim_count;
+    switch (mode) {
+    case GL_POINTS:             prim_count = total;         break;
+    case GL_LINE_STRIP:         prim_count = total - 1;     break;
+    case GL_LINE_LOOP:          prim_count = total - 1;     break;
+    case GL_LINES:              prim_count = total / 2;     break;
+    case GL_TRIANGLE_STRIP:     prim_count = total - 2;     break;
+    case GL_TRIANGLE_FAN:       prim_count = total - 2;     break;
+    case GL_TRIANGLES:          prim_count = total / 3;     break;
+    default:    return;
+    }
+    printf( "total=%5u, hits=%5u, miss=%5u, hitrate=%3u%%,"
+            " prims=%5u, time=%6u us, prims/s=%d, v/t=%f\n",
+            total, hits, misses, (hits*100)/total,
+            prim_count, int(ns2us(time)), int(prim_count*float(seconds(1))/time),
+            float(misses) / prim_count);
+#endif
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+static __attribute__((noinline))
+void enableDisableClientState(ogles_context_t* c, GLenum array, bool enable)
+{
+    const int tmu = c->arrays.activeTexture;
+    array_t* a;
+    switch (array) {
+    case GL_COLOR_ARRAY:            a = &c->arrays.color;           break;
+    case GL_NORMAL_ARRAY:           a = &c->arrays.normal;          break;
+    case GL_TEXTURE_COORD_ARRAY:    a = &c->arrays.texture[tmu];    break;
+    case GL_VERTEX_ARRAY:           a = &c->arrays.vertex;          break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    a->enable = enable ? GL_TRUE : GL_FALSE;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Vertex Cache
+#endif
+
+static __attribute__((noinline))
+vertex_t* cache_vertex(ogles_context_t* c, vertex_t* v, uint32_t index)
+{
+    #if VC_CACHE_STATISTICS
+        c->vc.misses++;
+    #endif
+    if (ggl_unlikely(v->locked)) {
+        // we're just looking for an entry in the cache that is not locked.
+        // and we know that there cannot be more than 2 locked entries
+        // because a triangle needs at most 3 vertices.
+        // We never use the first and second entries because they might be in
+        // use by the striper or faner. Any other entry will do as long as
+        // it's not locked.
+        // We compute directly the index of a "free" entry from the locked
+        // state of v[2] and v[3].
+        v = c->vc.vBuffer + 2;
+        v += v[0].locked | (v[1].locked<<1);       
+    }
+    // note: compileElement clears v->flags
+    c->arrays.compileElement(c, v, index);
+    v->locked = 1;
+    return v;
+}
+
+static __attribute__((noinline))
+vertex_t* fetch_vertex(ogles_context_t* c, size_t index)
+{
+    index |= c->vc.sequence;
+
+#if VC_CACHE_TYPE == VC_CACHE_TYPE_INDEXED
+
+    vertex_t* const v = c->vc.vCache + 
+            (index & (vertex_cache_t::VERTEX_CACHE_SIZE-1));
+
+    if (ggl_likely(v->index == index)) {
+        v->locked = 1;
+        return v;
+    }
+    return cache_vertex(c, v, index);
+
+#elif VC_CACHE_TYPE == VC_CACHE_TYPE_LRU
+
+    vertex_t* v = c->vc.vCache + 
+            (index & ((vertex_cache_t::VERTEX_CACHE_SIZE-1)>>1))*2;
+
+    // always record LRU in v[0]
+    if (ggl_likely(v[0].index == index)) {
+        v[0].locked = 1;
+        v[0].mru = 0;
+        return &v[0];
+    }
+
+    if (ggl_likely(v[1].index == index)) {
+        v[1].locked = 1;
+        v[0].mru = 1;
+        return &v[1];
+    }
+
+    const int lru = 1 - v[0].mru;
+    v[0].mru = lru;
+    return cache_vertex(c, &v[lru], index);
+
+#elif VC_CACHE_TYPE == VC_CACHE_TYPE_NONE
+
+    // just for debugging...
+    vertex_t* v = c->vc.vBuffer + 2;
+    return cache_vertex(c, v, index);
+
+#endif
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Primitive Assembly
+#endif
+
+void drawPrimitivesPoints(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 1))
+        return;
+
+    // vertex cache size must be multiple of 1
+    const GLsizei vcs = 
+            (vertex_cache_t::VERTEX_BUFFER_SIZE +
+             vertex_cache_t::VERTEX_CACHE_SIZE);
+    do {
+        vertex_t* v = c->vc.vBuffer;
+        GLsizei num = count > vcs ? vcs : count; 
+        c->arrays.cull = vertex_t::CLIP_ALL;
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            do {
+                const uint32_t cc = v[0].flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderPoint(c, v);
+                v++;
+                num--;
+            } while (num);
+        }
+    } while (count);
+}
+
+// ----------------------------------------------------------------------------
+
+void drawPrimitivesLineStrip(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 2))
+        return;
+
+    vertex_t *v, *v0, *v1;
+    c->arrays.cull = vertex_t::CLIP_ALL;
+    c->arrays.compileElement(c, c->vc.vBuffer, first);
+    first += 1;
+    count -= 1;
+
+    // vertex cache size must be multiple of 1
+    const GLsizei vcs = 
+        (vertex_cache_t::VERTEX_BUFFER_SIZE +
+         vertex_cache_t::VERTEX_CACHE_SIZE - 1);
+    do {
+        v0 = c->vc.vBuffer + 0; 
+        v  = c->vc.vBuffer + 1;
+        GLsizei num = count > vcs ? vcs : count; 
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            do {
+                v1 = v++;
+                const uint32_t cc = v0->flags & v1->flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderLine(c, v0, v1);
+                v0 = v1;
+                num--;
+            } while (num);
+        }
+        // copy back the last processed vertex
+        c->vc.vBuffer[0] = *v0;
+        c->arrays.cull = v0->flags & vertex_t::CLIP_ALL;
+    } while (count);
+}
+
+void drawPrimitivesLineLoop(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 2))
+        return;
+    drawPrimitivesLineStrip(c, first, count);
+    if (ggl_likely(count >= 3)) {
+        vertex_t* v0 = c->vc.vBuffer; 
+        vertex_t* v1 = c->vc.vBuffer + 1;
+        c->arrays.compileElement(c, v1, first);
+        const uint32_t cc = v0->flags & v1->flags;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderLine(c, v0, v1);
+    }
+}
+
+void drawPrimitivesLines(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 2))
+        return;
+
+    // vertex cache size must be multiple of 2
+    const GLsizei vcs = 
+        ((vertex_cache_t::VERTEX_BUFFER_SIZE +
+        vertex_cache_t::VERTEX_CACHE_SIZE) / 2) * 2;
+    do {
+        vertex_t* v = c->vc.vBuffer;
+        GLsizei num = count > vcs ? vcs : count; 
+        c->arrays.cull = vertex_t::CLIP_ALL;
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            num -= 2;
+            do {
+                const uint32_t cc = v[0].flags & v[1].flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderLine(c, v, v+1);
+                v += 2;
+                num -= 2;
+            } while (num >= 0);
+        }
+    } while (count >= 2);
+}
+
+// ----------------------------------------------------------------------------
+
+static void drawPrimitivesTriangleFanOrStrip(ogles_context_t* c,
+        GLint first, GLsizei count, int winding)
+{
+    // winding == 2 : fan
+    // winding == 1 : strip
+
+    if (ggl_unlikely(count < 3))
+        return;
+
+    vertex_t *v, *v0, *v1, *v2;
+    c->arrays.cull = vertex_t::CLIP_ALL;
+    c->arrays.compileElements(c, c->vc.vBuffer, first, 2);
+    first += 2;
+    count -= 2;
+
+    // vertex cache size must be multiple of 2. This is extremely important
+    // because it allows us to preserve the same winding when the whole
+    // batch is culled. We also need 2 extra vertices in the array, because
+    // we always keep the two first ones.
+    const GLsizei vcs = 
+        ((vertex_cache_t::VERTEX_BUFFER_SIZE +
+          vertex_cache_t::VERTEX_CACHE_SIZE - 2) / 2) * 2;
+    do {
+        v0 = c->vc.vBuffer + 0; 
+        v1 = c->vc.vBuffer + 1; 
+        v  = c->vc.vBuffer + 2;
+        GLsizei num = count > vcs ? vcs : count; 
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            do {
+                v2 = v++;
+                const uint32_t cc = v0->flags & v1->flags & v2->flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderTriangle(c, v0, v1, v2);
+                swap(((winding^=1) ? v1 : v0), v2);
+                num--;
+            } while (num);
+        }
+        if (count) {
+            v0 = c->vc.vBuffer + 2 + num - 2;
+            v1 = c->vc.vBuffer + 2 + num - 1;
+            if ((winding&2) == 0) {
+                // for strips copy back the two last compiled vertices
+                c->vc.vBuffer[0] = *v0;
+            }
+            c->vc.vBuffer[1] = *v1;
+            c->arrays.cull = v0->flags & v1->flags & vertex_t::CLIP_ALL;
+        }
+    } while (count > 0);
+}
+
+void drawPrimitivesTriangleStrip(ogles_context_t* c, 
+        GLint first, GLsizei count) {
+    drawPrimitivesTriangleFanOrStrip(c, first, count, 1);
+}
+
+void drawPrimitivesTriangleFan(ogles_context_t* c,
+        GLint first, GLsizei count) {
+    drawPrimitivesTriangleFanOrStrip(c, first, count, 2);
+}
+
+void drawPrimitivesTriangles(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 3))
+        return;
+
+    // vertex cache size must be multiple of 3
+    const GLsizei vcs = 
+        ((vertex_cache_t::VERTEX_BUFFER_SIZE +
+        vertex_cache_t::VERTEX_CACHE_SIZE) / 3) * 3;
+    do {
+        vertex_t* v = c->vc.vBuffer;
+        GLsizei num = count > vcs ? vcs : count; 
+        c->arrays.cull = vertex_t::CLIP_ALL;
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            num -= 3;
+            do {
+                const uint32_t cc = v[0].flags & v[1].flags & v[2].flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderTriangle(c, v, v+1, v+2);
+                v += 3;
+                num -= 3;
+            } while (num >= 0);
+        }
+    } while (count >= 3);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+// this looks goofy, but gcc does a great job with this...
+static inline unsigned int read_index(int type, const GLvoid*& p) {
+    unsigned int r;
+    if (type) {
+        r = *(const GLubyte*)p;
+        p = (const GLubyte*)p + 1;
+    } else {
+        r = *(const GLushort*)p;
+        p = (const GLushort*)p + 1;
+    }
+    return r;
+}
+
+// ----------------------------------------------------------------------------
+
+void drawIndexedPrimitivesPoints(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    if (ggl_unlikely(count < 1))
+        return;
+    const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
+    do {
+        vertex_t * v = fetch_vertex(c, read_index(type, indices));
+        if (ggl_likely(!(v->flags & vertex_t::CLIP_ALL)))
+            c->prims.renderPoint(c, v);
+        v->locked = 0;
+        count--;
+    } while(count);
+}
+
+// ----------------------------------------------------------------------------
+
+void drawIndexedPrimitivesLineStrip(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    if (ggl_unlikely(count < 2))
+        return;
+    
+    vertex_t * const v = c->vc.vBuffer;
+    vertex_t* v0 = v;
+    vertex_t* v1;
+    
+    const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
+    c->arrays.compileElement(c, v0, read_index(type, indices));
+    count -= 1;
+    do {
+        v1 = fetch_vertex(c, read_index(type, indices));
+        const uint32_t cc = v0->flags & v1->flags;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderLine(c, v0, v1);
+        v0->locked = 0;
+        v0 = v1;
+        count--;
+    } while (count);
+    v1->locked = 0;
+}
+
+void drawIndexedPrimitivesLineLoop(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    if (ggl_unlikely(count <= 2)) {
+        drawIndexedPrimitivesLines(c, count, indices);
+        return;
+    }
+ 
+    vertex_t * const v = c->vc.vBuffer;
+    vertex_t* v0 = v;
+    vertex_t* v1;
+    
+    const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
+    c->arrays.compileElement(c, v0, read_index(type, indices));
+    count -= 1;
+    do {
+        v1 = fetch_vertex(c, read_index(type, indices));
+        const uint32_t cc = v0->flags & v1->flags;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderLine(c, v0, v1);
+        v0->locked = 0;
+        v0 = v1;
+        count--;
+    } while (count);
+    v1->locked = 0;
+
+    v1 = c->vc.vBuffer; 
+    const uint32_t cc = v0->flags & v1->flags;
+    if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+        c->prims.renderLine(c, v0, v1);
+}
+
+void drawIndexedPrimitivesLines(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    if (ggl_unlikely(count < 2))
+        return;
+
+    count -= 2;
+    const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
+    do {
+        vertex_t* const v0 = fetch_vertex(c, read_index(type, indices));
+        vertex_t* const v1 = fetch_vertex(c, read_index(type, indices));
+        const uint32_t cc = v0->flags & v1->flags;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderLine(c, v0, v1);
+        v0->locked = 0;
+        v1->locked = 0;
+        count -= 2;
+    } while (count >= 0);
+}
+
+// ----------------------------------------------------------------------------
+
+static void drawIndexedPrimitivesTriangleFanOrStrip(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices, int winding)
+{
+    // winding == 2 : fan
+    // winding == 1 : strip
+
+    if (ggl_unlikely(count < 3))
+        return;
+    
+    vertex_t * const v = c->vc.vBuffer;
+    vertex_t* v0 = v;
+    vertex_t* v1 = v+1;
+    vertex_t* v2;
+
+    const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
+    c->arrays.compileElement(c, v0, read_index(type, indices));
+    c->arrays.compileElement(c, v1, read_index(type, indices));
+    count -= 2;
+
+    // note: GCC 4.1.1 here makes a prety interesting optimization
+    // where it duplicates the loop below based on c->arrays.indicesType
+
+    do {
+        v2 = fetch_vertex(c, read_index(type, indices));
+        const uint32_t cc = v0->flags & v1->flags & v2->flags;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderTriangle(c, v0, v1, v2);
+        vertex_t* & consumed = ((winding^=1) ? v1 : v0);
+        consumed->locked = 0;
+        consumed = v2;
+        count--;
+    } while (count);
+    v0->locked = v1->locked = 0;
+    v2->locked = 0;
+}
+
+void drawIndexedPrimitivesTriangleStrip(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices) {
+    drawIndexedPrimitivesTriangleFanOrStrip(c, count, indices, 1);
+}
+
+void drawIndexedPrimitivesTriangleFan(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices) {
+    drawIndexedPrimitivesTriangleFanOrStrip(c, count, indices, 2);
+}
+
+void drawIndexedPrimitivesTriangles(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    if (ggl_unlikely(count < 3))
+        return;
+
+    count -= 3;
+    if (ggl_likely(c->arrays.indicesType == GL_UNSIGNED_SHORT)) {
+        // This case is probably our most common case...
+        uint16_t const * p = (uint16_t const *)indices;
+        do {
+            vertex_t* const v0 = fetch_vertex(c, *p++);
+            vertex_t* const v1 = fetch_vertex(c, *p++);
+            vertex_t* const v2 = fetch_vertex(c, *p++);
+            const uint32_t cc = v0->flags & v1->flags & v2->flags;
+            if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                c->prims.renderTriangle(c, v0, v1, v2);
+            v0->locked = 0;
+            v1->locked = 0;
+            v2->locked = 0;
+            count -= 3;
+        } while (count >= 0);
+    } else {
+        uint8_t const * p = (uint8_t const *)indices;
+        do {
+            vertex_t* const v0 = fetch_vertex(c, *p++);
+            vertex_t* const v1 = fetch_vertex(c, *p++);
+            vertex_t* const v2 = fetch_vertex(c, *p++);
+            const uint32_t cc = v0->flags & v1->flags & v2->flags;
+            if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                c->prims.renderTriangle(c, v0, v1, v2);
+            v0->locked = 0;
+            v1->locked = 0;
+            v2->locked = 0;
+            count -= 3;
+        } while (count >= 0);
+    }
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Array compilers
+#endif
+
+void compileElement__generic(ogles_context_t* c,
+        vertex_t* v, GLint first)
+{
+    v->flags = 0;
+    v->index = first;
+    first &= vertex_cache_t::INDEX_MASK;
+    const GLubyte* vp = c->arrays.vertex.element(first);
+    c->arrays.vertex.fetch(c, v->obj.v, vp);
+    c->arrays.mvp_transform(&c->transforms.mvp, &v->clip, &v->obj);
+    c->arrays.perspective(c, v);
+}
+
+void compileElements__generic(ogles_context_t* c,
+        vertex_t* v, GLint first, GLsizei count)
+{
+    const GLubyte* vp = c->arrays.vertex.element(
+            first & vertex_cache_t::INDEX_MASK);
+    const size_t stride = c->arrays.vertex.stride;
+    transform_t const* const mvp = &c->transforms.mvp;
+    do {
+        v->flags = 0;
+        v->index = first++;
+        c->arrays.vertex.fetch(c, v->obj.v, vp);
+        c->arrays.mvp_transform(mvp, &v->clip, &v->obj);
+        c->arrays.perspective(c, v);
+        vp += stride;
+        v++;
+    } while (--count);
+}
+
+/*
+void compileElements__3x_full(ogles_context_t* c,
+        vertex_t* v, GLint first, GLsizei count)
+{
+    const GLfixed* vp = (const GLfixed*)c->arrays.vertex.element(first);
+    const size_t stride = c->arrays.vertex.stride / 4;
+//    const GLfixed* const& m = c->transforms.mvp.matrix.m;
+    
+    GLfixed m[16];
+    memcpy(&m, c->transforms.mvp.matrix.m, sizeof(m));
+    
+    do {
+        const GLfixed rx = vp[0];
+        const GLfixed ry = vp[1];
+        const GLfixed rz = vp[2];
+        vp += stride;
+        v->index = first++;
+        v->clip.x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); 
+        v->clip.y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]);
+        v->clip.z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]);
+        v->clip.w = mla3a(rx, m[ 3], ry, m[ 7], rz, m[11], m[15]);
+
+        const GLfixed w = v->clip.w;
+        uint32_t clip = 0;
+        if (v->clip.x < -w)   clip |= vertex_t::CLIP_L;
+        if (v->clip.x >  w)   clip |= vertex_t::CLIP_R;
+        if (v->clip.y < -w)   clip |= vertex_t::CLIP_B;
+        if (v->clip.y >  w)   clip |= vertex_t::CLIP_T;
+        if (v->clip.z < -w)   clip |= vertex_t::CLIP_N;
+        if (v->clip.z >  w)   clip |= vertex_t::CLIP_F;
+        v->flags = clip;
+        c->arrays.cull &= clip;
+
+        //c->arrays.perspective(c, v);
+        v++;
+    } while (--count);
+}
+*/
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark clippers
+#endif
+
+static void clipVec4(vec4_t& nv, 
+        GLfixed t, const vec4_t& s, const vec4_t& p)
+{
+    for (int i=0; i<4 ; i++)
+        nv.v[i] = gglMulAddx(t, s.v[i] - p.v[i], p.v[i], 28);
+}
+
+static void clipVertex(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    clipVec4(nv->clip, t, s->clip, p->clip);
+    nv->fog = gglMulAddx(t, s->fog - p->fog, p->fog, 28);
+    ogles_vertex_project(c, nv);
+    nv->flags |=  vertex_t::LIT | vertex_t::EYE | vertex_t::TT;
+    nv->flags &= ~vertex_t::CLIP_ALL;
+}
+
+static void clipVertexC(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    clipVec4(nv->color, t, s->color, p->color);
+    clipVertex(c, nv, t, s, p);
+}
+
+static void clipVertexT(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (c->rasterizer.state.texture[i].enable)
+            clipVec4(nv->texture[i], t, s->texture[i], p->texture[i]);
+    }
+    clipVertex(c, nv, t, s, p);
+}
+
+static void clipVertexAll(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    clipVec4(nv->color, t, s->color, p->color);
+    clipVertexT(c, nv, t, s, p);
+}
+
+static void clipEye(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    nv->clear();
+    c->arrays.clipVertex(c, nv, t, p, s);
+    clipVec4(nv->eye, t, s->eye, p->eye);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void validate_arrays(ogles_context_t* c, GLenum mode)
+{
+    uint32_t enables = c->rasterizer.state.enables;
+
+    // Perspective correction is not need if Ortho transform, but
+    // the user can still provide the w coordinate manually, so we can't
+    // automatically turn it off (in fact we could when the 4th coordinate
+    // is not spcified in the vertex array).
+    // W interpolation is never needed for points.
+    GLboolean perspective = 
+        c->perspective && mode!=GL_POINTS && (enables & GGL_ENABLE_TMUS);
+    c->rasterizer.procs.enableDisable(c, GGL_W_LERP, perspective);
+    
+    // set anti-aliasing
+    GLboolean smooth = GL_FALSE;
+    switch (mode) {
+    case GL_POINTS:
+        smooth = c->point.smooth;
+        break;
+    case GL_LINES:
+    case GL_LINE_LOOP:
+    case GL_LINE_STRIP:
+        smooth = c->line.smooth;
+        break;
+    }
+    if (((enables & GGL_ENABLE_AA)?1:0) != smooth)
+        c->rasterizer.procs.enableDisable(c, GGL_AA, smooth);
+
+    // set the shade model for this primitive
+    c->rasterizer.procs.shadeModel(c,
+            (mode == GL_POINTS) ? GL_FLAT : c->lighting.shadeModel);
+
+    // compute all the matrices we'll need...
+    uint32_t want =
+            transform_state_t::MVP |
+            transform_state_t::VIEWPORT;
+    if (c->lighting.enable) { // needs normal transforms and eye coords
+        want |= transform_state_t::MVUI;
+        want |= transform_state_t::MODELVIEW;
+    }
+    if (enables & GGL_ENABLE_TMUS) { // needs texture transforms
+        want |= transform_state_t::TEXTURE;
+    }
+    if (c->clipPlanes.enable) { // needs eye coords
+        want |= transform_state_t::MODELVIEW;
+    }
+    ogles_validate_transform(c, want);
+
+    // textures...
+    if (enables & GGL_ENABLE_TMUS)
+        ogles_validate_texture(c);
+
+    // vertex compilers
+    c->arrays.compileElement = compileElement__generic;
+    c->arrays.compileElements = compileElements__generic;
+
+    // vertex transform
+    c->arrays.mvp_transform =
+        c->transforms.mvp.pointv[c->arrays.vertex.size - 2];
+
+    c->arrays.mv_transform =
+        c->transforms.modelview.transform.pointv[c->arrays.vertex.size - 2];
+    
+    /*
+     * ***********************************************************************
+     *  pick fetchers
+     * ***********************************************************************
+     */
+    
+    array_machine_t& am = c->arrays;
+    am.vertex.fetch = fetchNop;
+    am.normal.fetch = currentNormal;
+    am.color.fetch = currentColor;
+    
+    if (am.vertex.enable) {
+        am.vertex.resolve();
+        if (am.vertex.bo || am.vertex.pointer) {
+            am.vertex.fetch = vertex_fct[am.vertex.size-2][am.vertex.type & 0xF];
+        }
+    }
+
+    if (am.normal.enable) {
+        am.normal.resolve();
+        if (am.normal.bo || am.normal.pointer) {
+            am.normal.fetch = normal_fct[am.normal.size-3][am.normal.type & 0xF];
+        }
+    }
+
+    if (am.color.enable) {
+        am.color.resolve();
+        if (c->lighting.enable) {
+            if (am.color.bo || am.color.pointer) {
+                am.color.fetch = color_fct[am.color.size-3][am.color.type & 0xF];
+            }
+        } else {
+            if (am.color.bo || am.color.pointer) {
+                am.color.fetch = color_clamp_fct[am.color.size-3][am.color.type & 0xF];
+            }
+        }
+    }
+
+    int activeTmuCount = 0;
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        am.texture[i].fetch = currentTexCoord;
+        if (c->rasterizer.state.texture[i].enable) {
+
+            // texture fetchers...
+            if (am.texture[i].enable) {
+                am.texture[i].resolve();
+                if (am.texture[i].bo || am.texture[i].pointer) {
+                    am.texture[i].fetch = texture_fct[am.texture[i].size-2][am.texture[i].type & 0xF];
+                }
+            }
+
+            // texture transform...
+            const int index = c->arrays.texture[i].size - 2;
+            c->arrays.tex_transform[i] =
+                c->transforms.texture[i].transform.pointv[index];
+
+            am.tmu = i;
+            activeTmuCount++;
+        }
+    }
+
+    // pick the vertex-clipper
+    uint32_t clipper = 0;
+    // we must reload 'enables' here
+    enables = c->rasterizer.state.enables;
+    if (enables & GGL_ENABLE_SMOOTH)
+        clipper |= 1;   // we need to interpolate colors
+    if (enables & GGL_ENABLE_TMUS)
+        clipper |= 2;   // we need to interpolate textures
+    switch (clipper) {
+    case 0: c->arrays.clipVertex = clipVertex;      break;
+    case 1: c->arrays.clipVertex = clipVertexC;     break;
+    case 2: c->arrays.clipVertex = clipVertexT;     break;
+    case 3: c->arrays.clipVertex = clipVertexAll;   break;
+    }
+    c->arrays.clipEye = clipEye;
+
+    // pick the primitive rasterizer
+    ogles_validate_primitives(c);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+#if 0
+#pragma mark -
+#pragma mark array API
+#endif
+
+void glVertexPointer(
+    GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (size<2 || size>4 || stride<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (type) {
+    case GL_BYTE:
+    case GL_SHORT:
+    case GL_FIXED:
+    case GL_FLOAT:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->arrays.vertex.init(size, type, stride, pointer, c->arrays.array_buffer, 0);
+}
+
+void glColorPointer(
+    GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    // in theory ogles doesn't allow color arrays of size 3
+    // but it is very useful to 'visualize' the normal array.
+    if (size<3 || size>4 || stride<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (type) {
+    case GL_UNSIGNED_BYTE:
+    case GL_FIXED:
+    case GL_FLOAT:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->arrays.color.init(size, type, stride, pointer, c->arrays.array_buffer, 0);
+}
+
+void glNormalPointer(
+    GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (stride<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (type) {
+    case GL_BYTE:
+    case GL_SHORT:
+    case GL_FIXED:
+    case GL_FLOAT:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->arrays.normal.init(3, type, stride, pointer, c->arrays.array_buffer, 0);
+}
+
+void glTexCoordPointer(
+    GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (size<2 || size>4 || stride<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (type) {
+    case GL_BYTE:
+    case GL_SHORT:
+    case GL_FIXED:
+    case GL_FLOAT:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    const int tmu = c->arrays.activeTexture;
+    c->arrays.texture[tmu].init(size, type, stride, pointer,
+            c->arrays.array_buffer, 0);
+}
+
+
+void glEnableClientState(GLenum array) {
+    ogles_context_t* c = ogles_context_t::get();
+    enableDisableClientState(c, array, true);
+}
+
+void glDisableClientState(GLenum array) {
+    ogles_context_t* c = ogles_context_t::get();
+    enableDisableClientState(c, array, false);
+}
+
+void glClientActiveTexture(GLenum texture)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (texture<GL_TEXTURE0 || texture>=GL_TEXTURE0+GGL_TEXTURE_UNIT_COUNT) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->arrays.activeTexture = texture - GL_TEXTURE0;
+}
+
+void glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (count<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (mode) {
+    case GL_POINTS:
+    case GL_LINE_STRIP:
+    case GL_LINE_LOOP:
+    case GL_LINES:
+    case GL_TRIANGLE_STRIP:
+    case GL_TRIANGLE_FAN:
+    case GL_TRIANGLES:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    if (count == 0 || !c->arrays.vertex.enable)
+        return;
+    if ((c->cull.enable) && (c->cull.cullFace == GL_FRONT_AND_BACK))
+        return; // all triangles are culled
+
+    validate_arrays(c, mode);
+    drawArraysPrims[mode](c, first, count);
+
+#if VC_CACHE_STATISTICS
+    c->vc.total = count;
+    c->vc.dump_stats(mode);
+#endif
+}
+
+void glDrawElements(
+    GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (count<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (mode) {
+    case GL_POINTS:
+    case GL_LINE_STRIP:
+    case GL_LINE_LOOP:
+    case GL_LINES:
+    case GL_TRIANGLE_STRIP:
+    case GL_TRIANGLE_FAN:
+    case GL_TRIANGLES:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    switch (type) {
+    case GL_UNSIGNED_BYTE:
+    case GL_UNSIGNED_SHORT:
+        c->arrays.indicesType = type;
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (count == 0 || !c->arrays.vertex.enable)
+        return;
+    if ((c->cull.enable) && (c->cull.cullFace == GL_FRONT_AND_BACK))
+        return; // all triangles are culled
+
+    // clear the vertex-cache
+    c->vc.clear();
+    validate_arrays(c, mode);
+    
+    // if indices are in a buffer object, the pointer is treated as an
+    // offset in that buffer.
+    if (c->arrays.element_array_buffer) {
+        indices = c->arrays.element_array_buffer->data + uintptr_t(indices);
+    }
+
+    drawElementsPrims[mode](c, count, indices);
+
+#if VC_CACHE_STATISTICS
+    c->vc.total = count;
+    c->vc.dump_stats(mode);
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// buffers
+// ----------------------------------------------------------------------------
+
+void glBindBuffer(GLenum target, GLuint buffer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if ((target!=GL_ARRAY_BUFFER) && (target!=GL_ELEMENT_ARRAY_BUFFER)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    // create a buffer object, or bind an existing one
+    buffer_t const* bo = 0;
+    if (buffer) {
+        bo = c->bufferObjectManager->bind(buffer);
+        if (!bo) {
+            ogles_error(c, GL_OUT_OF_MEMORY);
+            return;
+        }
+    }
+    ((target == GL_ARRAY_BUFFER) ? 
+            c->arrays.array_buffer : c->arrays.element_array_buffer) = bo;
+}
+
+void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if ((target!=GL_ARRAY_BUFFER) && (target!=GL_ELEMENT_ARRAY_BUFFER)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (size<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if ((usage!=GL_STATIC_DRAW) && (usage!=GL_DYNAMIC_DRAW)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? 
+            c->arrays.array_buffer : c->arrays.element_array_buffer);
+
+    if (bo == 0) {
+        // can't modify buffer 0
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+
+    buffer_t* edit_bo = const_cast<buffer_t*>(bo);
+    if (c->bufferObjectManager->allocateStore(edit_bo, size, usage) != 0) {
+        ogles_error(c, GL_OUT_OF_MEMORY);
+        return;
+    }
+    if (data) {
+        memcpy(bo->data, data, size);
+    }
+}
+
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if ((target!=GL_ARRAY_BUFFER) && (target!=GL_ELEMENT_ARRAY_BUFFER)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (offset<0 || size<0 || data==0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? 
+            c->arrays.array_buffer : c->arrays.element_array_buffer);
+
+    if (bo == 0) {
+        // can't modify buffer 0
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+    if (offset+size > bo->size) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    memcpy(bo->data + offset, data, size);
+}
+
+void glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (n<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    for (int i=0 ; i<n ; i++) {
+        GLuint name = buffers[i];
+        if (name) {
+            // unbind bound deleted buffers...
+            if (c->arrays.element_array_buffer->name == name) {
+                c->arrays.element_array_buffer = 0;
+            }
+            if (c->arrays.array_buffer->name == name) {
+                c->arrays.array_buffer = 0;
+            }
+            if (c->arrays.vertex.bo->name == name) {
+                c->arrays.vertex.bo = 0;
+            }
+            if (c->arrays.normal.bo->name == name) {
+                c->arrays.normal.bo = 0;
+            }
+            if (c->arrays.color.bo->name == name) {
+                c->arrays.color.bo = 0;
+            }
+            for (int t=0 ; t<GGL_TEXTURE_UNIT_COUNT ; t++) {
+                if (c->arrays.texture[t].bo->name == name) {
+                    c->arrays.texture[t].bo = 0;
+                }
+            }
+        }
+    }    
+    c->bufferObjectManager->deleteBuffers(n, buffers);
+    c->bufferObjectManager->recycleTokens(n, buffers);
+}
+
+void glGenBuffers(GLsizei n, GLuint* buffers)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (n<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    c->bufferObjectManager->getToken(n, buffers);
+}
diff --git a/opengl/libagl/array.h b/opengl/libagl/array.h
new file mode 100644
index 0000000..e156978
--- /dev/null
+++ b/opengl/libagl/array.h
@@ -0,0 +1,37 @@
+/* libs/opengles/array.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_ARRAY_H
+#define ANDROID_OPENGLES_ARRAY_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+namespace android {
+
+namespace gl {
+struct ogles_context_t;
+};
+
+void ogles_init_array(ogles_context_t* c);
+void ogles_uninit_array(ogles_context_t* c);
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_ARRAY_H
+
diff --git a/opengl/libagl/context.h b/opengl/libagl/context.h
new file mode 100644
index 0000000..ef36b56
--- /dev/null
+++ b/opengl/libagl/context.h
@@ -0,0 +1,20 @@
+/* libs/opengles/context.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 <private/opengles/gl_context.h>
+
+using namespace android::gl;
diff --git a/opengl/libagl/dxt.cpp b/opengl/libagl/dxt.cpp
new file mode 100644
index 0000000..238c81f
--- /dev/null
+++ b/opengl/libagl/dxt.cpp
@@ -0,0 +1,636 @@
+/* libs/opengles/dxt.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 TIMING 0
+
+#if TIMING
+#include <sys/time.h> // for optimization timing
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include <GLES/gl.h>
+#include <utils/Endian.h>
+
+#include "context.h"
+
+#define TIMING 0
+
+namespace android {
+
+static uint8_t avg23tab[64*64];
+static volatile int tables_initialized = 0;
+
+// Definitions below are equivalent to these over the valid range of arguments
+//  #define div5(x) ((x)/5)
+//  #define div7(x) ((x)/7)
+
+// Use fixed-point to divide by 5 and 7
+// 3277 = 2^14/5 + 1
+// 2341 = 2^14/7 + 1
+#define div5(x) (((x)*3277) >> 14)
+#define div7(x) (((x)*2341) >> 14)
+
+// Table with entry [a << 6 | b] = (2*a + b)/3 for 0 <= a,b < 64
+#define avg23(x0,x1) avg23tab[((x0) << 6) | (x1)]
+
+// Extract 5/6/5 RGB
+#define red(x)   (((x) >> 11) & 0x1f)
+#define green(x) (((x) >>  5) & 0x3f)
+#define blue(x)  ( (x)        & 0x1f)
+
+/*
+ * Convert 5/6/5 RGB (as 3 ints) to 8/8/8
+ *
+ * Operation count: 8 <<, 0 &, 5 |
+ */
+inline static int rgb565SepTo888(int r, int g, int b)
+
+{
+    return ((((r << 3) | (r >> 2)) << 16) |
+            (((g << 2) | (g >> 4)) <<  8) |
+             ((b << 3) | (b >> 2)));
+}
+
+/*
+ * Convert 5/6/5 RGB (as a single 16-bit word) to 8/8/8
+ *
+ *                   r4r3r2r1 r0g5g4g3 g2g1g0b4 b3b2b1b0   rgb
+ *            r4r3r2 r1r0g5g4 g3g2g1g0 b4b3b2b1 b0 0 0 0   rgb << 3
+ * r4r3r2r1 r0r4r3r2 g5g4g3g2 g1g0g5g4 b4b3b2b1 b0b4b3b2   desired result
+ *
+ * Construct the 24-bit RGB word as:
+ *
+ * r4r3r2r1 r0------ -------- -------- -------- --------  (rgb << 8) & 0xf80000
+ *            r4r3r2 -------- -------- -------- --------  (rgb << 3) & 0x070000
+ *                   g5g4g3g2 g1g0---- -------- --------  (rgb << 5) & 0x00fc00
+ *                                g5g4 -------- --------  (rgb >> 1) & 0x000300
+ *                                     b4b3b2b1 b0------  (rgb << 3) & 0x0000f8
+ *                                                b4b3b2  (rgb >> 2) & 0x000007
+ *
+ * Operation count: 5 <<, 6 &, 5 | (n.b. rgb >> 3 is used twice)
+ */
+inline static int rgb565To888(int rgb)
+
+{
+    int rgb3 = rgb >> 3;
+    return (((rgb << 8) & 0xf80000) |
+            ( rgb3      & 0x070000) |
+            ((rgb << 5) & 0x00fc00) |
+            ((rgb >> 1) & 0x000300) |
+            ( rgb3      & 0x0000f8) |
+            ((rgb >> 2) & 0x000007));
+}
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+static uint32_t swap(uint32_t x) {
+    int b0 = (x >> 24) & 0xff;
+    int b1 = (x >> 16) & 0xff;
+    int b2 = (x >>  8) & 0xff;
+    int b3 = (x      ) & 0xff;
+    
+    return (uint32_t)((b3 << 24) | (b2 << 16) | (b1 << 8) | b0);
+}
+#endif
+
+static void
+init_tables()
+{
+    if (tables_initialized) {
+        return;
+    }
+
+    for (int i = 0; i < 64; i++) {
+        for (int j = 0; j < 64; j++) {
+            int avg = (2*i + j)/3;
+            avg23tab[(i << 6) | j] = avg;
+        }
+    }
+
+    asm volatile ("" : : : "memory");
+    tables_initialized = 1;
+}
+
+/*
+ * Utility to scan a DXT1 compressed texture to determine whether it
+ * contains a transparent pixel (color0 < color1, code == 3).  This
+ * may be useful if the application lacks information as to whether
+ * the true format is GL_COMPRESSED_RGB_S3TC_DXT1_EXT or
+ * GL_COMPRESSED_RGBA_S3TC_DXT1_EXT.
+ */
+bool
+DXT1HasAlpha(const GLvoid *data, int width, int height) {    
+#if TIMING
+    struct timeval start_t, end_t;
+    struct timezone tz;
+    
+    gettimeofday(&start_t, &tz);
+#endif
+
+    bool hasAlpha = false;
+
+    int xblocks = (width + 3)/4;
+    int yblocks = (height + 3)/4;
+    int numblocks = xblocks*yblocks;
+
+    uint32_t const *d32 = (uint32_t *)data;
+    for (int b = 0; b < numblocks; b++) {
+        uint32_t colors = *d32++;
+        
+#if __BYTE_ORDER == __BIG_ENDIAN
+        colors = swap(colors);
+#endif
+        
+        uint16_t color0 = colors & 0xffff;
+        uint16_t color1 = colors >> 16;
+        
+        if (color0 < color1) {
+            // There's no need to endian-swap within 'bits'
+            // since we don't care which pixel is the transparent one
+            uint32_t bits = *d32++;
+            
+            // Detect if any (odd, even) pair of bits are '11'
+            //      bits: b31 b30 b29 ... b3 b2 b1 b0
+            // bits >> 1: b31 b31 b30 ... b4 b3 b2 b1
+            //         &: b31 (b31 & b30) (b29 & b28) ... (b2 & b1) (b1 & b0)
+            //  & 0x55..:   0 (b31 & b30)       0     ...     0     (b1 & b0)
+            if (((bits & (bits >> 1)) & 0x55555555) != 0) {
+                hasAlpha = true;
+                goto done;
+            }
+        } else {
+            // Skip 4 bytes
+            ++d32;
+        }
+    }
+    
+ done:
+#if TIMING
+    gettimeofday(&end_t, &tz);
+    long usec = (end_t.tv_sec - start_t.tv_sec)*1000000 +
+        (end_t.tv_usec - start_t.tv_usec);
+    
+    printf("Scanned w=%d h=%d in %ld usec\n", width, height, usec);
+#endif
+    
+    return hasAlpha;
+}
+
+static void
+decodeDXT1(const GLvoid *data, int width, int height,
+           void *surface, int stride,
+           bool hasAlpha)
+    
+{
+    init_tables();
+    
+    uint32_t const *d32 = (uint32_t *)data;
+    
+    // Color table for the current block
+    uint16_t c[4];
+    c[0] = c[1] = c[2] = c[3] = 0;
+    
+    // Specified colors from the previous block
+    uint16_t prev_color0 = 0x0000;
+    uint16_t prev_color1 = 0x0000;
+    
+    uint16_t* rowPtr = (uint16_t*)surface;
+    for (int base_y = 0; base_y < height; base_y += 4, rowPtr += 4*stride) {
+        uint16_t *blockPtr = rowPtr;
+        for (int base_x = 0; base_x < width; base_x += 4, blockPtr += 4) {
+            uint32_t colors = *d32++;
+            uint32_t bits = *d32++;
+            
+#if __BYTE_ORDER == __BIG_ENDIAN
+            colors = swap(colors);
+            bits = swap(bits);
+#endif
+            
+            // Raw colors
+            uint16_t color0 = colors & 0xffff;
+            uint16_t color1 = colors >> 16;
+            
+            // If the new block has the same base colors as the
+            // previous one, we don't need to recompute the color
+            // table c[]
+            if (color0 != prev_color0 || color1 != prev_color1) {
+                // Store raw colors for comparison with next block
+                prev_color0 = color0;
+                prev_color1 = color1;
+                
+                int r0 =   red(color0);
+                int g0 = green(color0);
+                int b0 =  blue(color0);
+
+                int r1 =   red(color1);
+                int g1 = green(color1);
+                int b1 =  blue(color1);                
+                
+                if (hasAlpha) {
+                    c[0] = (r0 << 11) | ((g0 >> 1) << 6) | (b0 << 1) | 0x1;
+                    c[1] = (r1 << 11) | ((g1 >> 1) << 6) | (b1 << 1) | 0x1;
+                } else {
+                    c[0] = color0;
+                    c[1] = color1;
+                }
+                
+                int r2, g2, b2, r3, g3, b3, a3;
+                
+                int bbits = bits >> 1;
+                bool has2 = ((bbits & ~bits) & 0x55555555) != 0;
+                bool has3 = ((bbits &  bits) & 0x55555555) != 0;
+                
+                if (has2 || has3) {
+                    if (color0 > color1) {
+                        r2 = avg23(r0, r1);
+                        g2 = avg23(g0, g1);
+                        b2 = avg23(b0, b1);
+                        
+                        r3 = avg23(r1, r0);
+                        g3 = avg23(g1, g0);
+                        b3 = avg23(b1, b0);
+                        a3 = 1;
+                    } else {
+                        r2 = (r0 + r1) >> 1;
+                        g2 = (g0 + g1) >> 1;
+                        b2 = (b0 + b1) >> 1;
+                        
+                        r3 = g3 = b3 = a3 = 0;
+                    }
+                    if (hasAlpha) {
+                        c[2] = (r2 << 11) | ((g2 >> 1) << 6) |
+                            (b2 << 1) | 0x1;
+                        c[3] = (r3 << 11) | ((g3 >> 1) << 6) |
+                            (b3 << 1) | a3;
+                    } else {
+                        c[2] = (r2 << 11) | (g2 << 5) | b2;
+                        c[3] = (r3 << 11) | (g3 << 5) | b3;
+                    }
+                }
+            }
+            
+            uint16_t* blockRowPtr = blockPtr;
+            for (int y = 0; y < 4; y++, blockRowPtr += stride) {
+                // Don't process rows past the botom
+                if (base_y + y >= height) {
+                    break;
+                }
+                
+                int w = min(width - base_x, 4);
+                for (int x = 0; x < w; x++) {
+                    int code = bits & 0x3;
+                    bits >>= 2;
+                    
+                    blockRowPtr[x] = c[code];
+                }
+            }
+        }
+    }
+}
+    
+// Output data as internalformat=GL_RGBA, type=GL_UNSIGNED_BYTE
+static void
+decodeDXT3(const GLvoid *data, int width, int height,
+           void *surface, int stride)
+
+{
+    init_tables();
+    
+    uint32_t const *d32 = (uint32_t *)data;
+    
+    // Specified colors from the previous block
+    uint16_t prev_color0 = 0x0000;
+    uint16_t prev_color1 = 0x0000;
+
+    // Color table for the current block
+    uint32_t c[4];
+    c[0] = c[1] = c[2] = c[3] = 0;
+
+    uint32_t* rowPtr = (uint32_t*)surface;
+    for (int base_y = 0; base_y < height; base_y += 4, rowPtr += 4*stride) {
+        uint32_t *blockPtr = rowPtr;
+        for (int base_x = 0; base_x < width; base_x += 4, blockPtr += 4) {
+            
+#if __BYTE_ORDER == __BIG_ENDIAN
+            uint32_t alphahi = *d32++;
+            uint32_t alphalo = *d32++;
+            alphahi = swap(alphahi);
+            alphalo = swap(alphalo);
+#else
+            uint32_t alphalo = *d32++;
+            uint32_t alphahi = *d32++;
+#endif
+
+            uint32_t colors = *d32++;
+            uint32_t bits = *d32++;
+            
+#if __BYTE_ORDER == __BIG_ENDIAN
+            colors = swap(colors);
+            bits = swap(bits);
+#endif
+            
+            uint64_t alpha = ((uint64_t)alphahi << 32) | alphalo;
+
+            // Raw colors
+            uint16_t color0 = colors & 0xffff;
+            uint16_t color1 = colors >> 16;
+
+            // If the new block has the same base colors as the
+            // previous one, we don't need to recompute the color
+            // table c[]
+            if (color0 != prev_color0 || color1 != prev_color1) {
+                // Store raw colors for comparison with next block
+                prev_color0 = color0;
+                prev_color1 = color1;
+                
+                int bbits = bits >> 1;
+                bool has2 = ((bbits & ~bits) & 0x55555555) != 0;
+                bool has3 = ((bbits &  bits) & 0x55555555) != 0;
+                
+                if (has2 || has3) {
+                    int r0 =   red(color0);
+                    int g0 = green(color0);
+                    int b0 =  blue(color0);
+                    
+                    int r1 =   red(color1);
+                    int g1 = green(color1);
+                    int b1 =  blue(color1);
+                    
+                    int r2 = avg23(r0, r1);
+                    int g2 = avg23(g0, g1);
+                    int b2 = avg23(b0, b1);
+                    
+                    int r3 = avg23(r1, r0);
+                    int g3 = avg23(g1, g0);
+                    int b3 = avg23(b1, b0);
+
+                    c[0] = rgb565SepTo888(r0, g0, b0);
+                    c[1] = rgb565SepTo888(r1, g1, b1);
+                    c[2] = rgb565SepTo888(r2, g2, b2);
+                    c[3] = rgb565SepTo888(r3, g3, b3);
+                } else {
+                    // Convert to 8 bits
+                    c[0] = rgb565To888(color0);
+                    c[1] = rgb565To888(color1);
+                }
+            }
+
+            uint32_t* blockRowPtr = blockPtr;
+            for (int y = 0; y < 4; y++, blockRowPtr += stride) {
+                // Don't process rows past the botom
+                if (base_y + y >= height) {
+                    break;
+                }
+                
+                int w = min(width - base_x, 4);
+                for (int x = 0; x < w; x++) {
+                    int a = alpha & 0xf;
+                    alpha >>= 4;
+
+                    int code = bits & 0x3;
+                    bits >>= 2;
+
+                    blockRowPtr[x] = c[code] | (a << 28) | (a << 24);
+                }
+            }
+        }
+    }
+}
+
+// Output data as internalformat=GL_RGBA, type=GL_UNSIGNED_BYTE
+static void
+decodeDXT5(const GLvoid *data, int width, int height,
+           void *surface, int stride)
+
+{
+    init_tables();
+    
+    uint32_t const *d32 = (uint32_t *)data;
+    
+    // Specified alphas from the previous block
+    uint8_t prev_alpha0 = 0x00;
+    uint8_t prev_alpha1 = 0x00;
+
+    // Specified colors from the previous block
+    uint16_t prev_color0 = 0x0000;
+     uint16_t prev_color1 = 0x0000;
+
+    // Alpha table for the current block
+    uint8_t a[8];
+    a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = 0;
+
+    // Color table for the current block
+    uint32_t c[4];
+    c[0] = c[1] = c[2] = c[3] = 0;
+
+    int good_a5 = 0;
+    int bad_a5 = 0;
+    int good_a6 = 0;
+    int bad_a6 = 0;
+    int good_a7 = 0;
+    int bad_a7 = 0;
+
+    uint32_t* rowPtr = (uint32_t*)surface;
+    for (int base_y = 0; base_y < height; base_y += 4, rowPtr += 4*stride) {
+        uint32_t *blockPtr = rowPtr;
+        for (int base_x = 0; base_x < width; base_x += 4, blockPtr += 4) {
+            
+#if __BYTE_ORDER == __BIG_ENDIAN
+            uint32_t alphahi = *d32++;
+            uint32_t alphalo = *d32++;
+            alphahi = swap(alphahi);
+            alphalo = swap(alphalo);
+#else
+             uint32_t alphalo = *d32++;
+             uint32_t alphahi = *d32++;
+#endif
+
+            uint32_t colors = *d32++;
+            uint32_t bits = *d32++;
+            
+#if __BYTE_ORDER == __BIG_ENDIANx
+            colors = swap(colors);
+            bits = swap(bits);
+#endif
+            
+            uint64_t alpha = ((uint64_t)alphahi << 32) | alphalo;
+            uint64_t alpha0 = alpha & 0xff;
+            alpha >>= 8;
+            uint64_t alpha1 = alpha & 0xff;
+            alpha >>= 8;
+
+            if (alpha0 != prev_alpha0 || alpha1 != prev_alpha1) {
+                prev_alpha0 = alpha0;
+                prev_alpha1 = alpha1;
+                
+                a[0] = alpha0;
+                a[1] = alpha1;
+                int a01 = alpha0 + alpha1 - 1;
+                if (alpha0 > alpha1) {
+                    a[2] = div7(6*alpha0 +   alpha1);
+                    a[4] = div7(4*alpha0 + 3*alpha1);
+                    a[6] = div7(2*alpha0 + 5*alpha1);
+
+                    // Use symmetry to derive half of the values
+                    // A few values will be off by 1 (~.5%)
+                    // Alternate which values are computed directly
+                    // and which are derived to try to reduce bias
+                    a[3] = a01 - a[6];
+                    a[5] = a01 - a[4];
+                    a[7] = a01 - a[2];
+                } else {
+                    a[2] = div5(4*alpha0 +   alpha1);
+                    a[4] = div5(2*alpha0 + 3*alpha1);
+                    a[3] = a01 - a[4];
+                    a[5] = a01 - a[2];
+                    a[6] = 0x00;
+                    a[7] = 0xff;
+                }
+            }
+
+            // Raw colors
+            uint16_t color0 = colors & 0xffff;
+            uint16_t color1 = colors >> 16;
+
+            // If the new block has the same base colors as the
+            // previous one, we don't need to recompute the color
+            // table c[]
+            if (color0 != prev_color0 || color1 != prev_color1) {
+                // Store raw colors for comparison with next block
+                prev_color0 = color0;
+                prev_color1 = color1;
+                
+                int bbits = bits >> 1;
+                bool has2 = ((bbits & ~bits) & 0x55555555) != 0;
+                bool has3 = ((bbits &  bits) & 0x55555555) != 0;
+                
+                if (has2 || has3) {
+                    int r0 =   red(color0);
+                    int g0 = green(color0);
+                    int b0 =  blue(color0);
+                    
+                    int r1 =   red(color1);
+                    int g1 = green(color1);
+                    int b1 =  blue(color1);
+                
+                    int r2 = avg23(r0, r1);
+                    int g2 = avg23(g0, g1);
+                    int b2 = avg23(b0, b1);
+                    
+                    int r3 = avg23(r1, r0);
+                    int g3 = avg23(g1, g0);
+                    int b3 = avg23(b1, b0);
+
+                    c[0] = rgb565SepTo888(r0, g0, b0);
+                    c[1] = rgb565SepTo888(r1, g1, b1);
+                    c[2] = rgb565SepTo888(r2, g2, b2);
+                    c[3] = rgb565SepTo888(r3, g3, b3);
+                } else {
+                    // Convert to 8 bits
+                    c[0] = rgb565To888(color0);
+                    c[1] = rgb565To888(color1);
+                }                
+            }
+
+            uint32_t* blockRowPtr = blockPtr;
+            for (int y = 0; y < 4; y++, blockRowPtr += stride) {
+                // Don't process rows past the botom
+                if (base_y + y >= height) {
+                    break;
+                }
+                
+                int w = min(width - base_x, 4);
+                for (int x = 0; x < w; x++) {
+                    int acode = alpha & 0x7;
+                    alpha >>= 3;
+
+                    int code = bits & 0x3;
+                    bits >>= 2;
+
+                    blockRowPtr[x] = c[code] | (a[acode] << 24);
+                }
+            }
+        }
+    }
+}
+   
+/*
+ * Decode a DXT-compressed texture into memory.  DXT textures consist of
+ * a series of 4x4 pixel blocks in left-to-right, top-down order.
+ * The number of blocks is given by ceil(width/4)*ceil(height/4).
+ *
+ * 'data' points to the texture data. 'width' and 'height' indicate the
+ * dimensions of the texture.  We assume width and height are >= 0 but
+ * do not require them to be powers of 2 or divisible by any factor.
+ *
+ * The output is written to 'surface' with each scanline separated by
+ * 'stride' 2- or 4-byte words.
+ *
+ * 'format' indicates the type of compression and must be one of the following:
+ *
+ *   GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ *      The output is written as 5/6/5 opaque RGB (16 bit words).
+ *      8 bytes are read from 'data' for each block.
+ *
+ *   GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
+ *      The output is written as 5/5/5/1 RGBA (16 bit words)
+ *      8 bytes are read from 'data' for each block.
+ *
+ *   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
+ *   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
+ *      The output is written as 8/8/8/8 ARGB (32 bit words)
+ *      16 bytes are read from 'data' for each block.
+ */
+void
+decodeDXT(const GLvoid *data, int width, int height,
+          void *surface, int stride, int format)
+{
+#if TIMING
+    struct timeval start_t, end_t;
+    struct timezone tz;
+    
+    gettimeofday(&start_t, &tz);
+#endif
+
+    switch (format) {
+    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+        decodeDXT1(data, width, height, surface, stride, false);
+        break;
+        
+    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+        decodeDXT1(data, width, height, surface, stride, true);
+        break;
+        
+    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+        decodeDXT3(data, width, height, surface, stride);
+        break;
+        
+    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+        decodeDXT5(data, width, height, surface, stride);
+        break;
+    }
+    
+#if TIMING
+    gettimeofday(&end_t, &tz);
+    long usec = (end_t.tv_sec - start_t.tv_sec)*1000000 +
+        (end_t.tv_usec - start_t.tv_usec);
+    
+    printf("Loaded w=%d h=%d in %ld usec\n", width, height, usec);
+#endif
+}
+
+} // namespace android
diff --git a/opengl/libagl/dxt.h b/opengl/libagl/dxt.h
new file mode 100644
index 0000000..d95a36c
--- /dev/null
+++ b/opengl/libagl/dxt.h
@@ -0,0 +1,33 @@
+/* libs/opengles/dxt.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_OPENGLES_TEXTURE_H
+#define ANDROID_OPENGLES_TEXTURE_H
+
+#include <stdlib.h>
+
+#include <GLES/gl.h>
+
+namespace android {
+
+  bool DXT1HasAlpha(const GLvoid *data, int width, int height);
+  void decodeDXT(const GLvoid *data, int width, int height,
+                 void *surface, int stride, int format);
+
+} // namespace android
+
+#endif // ANDROID_OPENGLES_TEXTURE_H
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
new file mode 100644
index 0000000..854a49e
--- /dev/null
+++ b/opengl/libagl/egl.cpp
@@ -0,0 +1,1513 @@
+/* 
+**
+** 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 "EGL"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <utils/threads.h>
+
+#include <GLES/egl.h>
+
+#include <pixelflinger/format.h>
+
+#include "context.h"
+#include "state.h"
+#include "texture.h"
+#include "matrix.h"
+
+#undef NELEM
+#define NELEM(x) (sizeof(x)/sizeof(*(x)))
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+const unsigned int NUM_DISPLAYS = 1;
+
+static pthread_mutex_t gInitMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t gErrorKeyMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_key_t gEGLErrorKey = -1;
+#ifndef HAVE_ANDROID_OS
+namespace gl {
+pthread_key_t gGLKey = -1;
+}; // namspace gl
+#endif
+
+template<typename T>
+static T setError(GLint error, T returnValue) {
+    if (ggl_unlikely(gEGLErrorKey == -1)) {
+        pthread_mutex_lock(&gErrorKeyMutex);
+        if (gEGLErrorKey == -1)
+            pthread_key_create(&gEGLErrorKey, NULL);
+        pthread_mutex_unlock(&gErrorKeyMutex);
+    }
+    pthread_setspecific(gEGLErrorKey, (void*)error);
+    return returnValue;
+}
+
+static GLint getError() {
+    if (ggl_unlikely(gEGLErrorKey == -1))
+        return EGL_SUCCESS;
+    GLint error = (GLint)pthread_getspecific(gEGLErrorKey);
+    pthread_setspecific(gEGLErrorKey, (void*)EGL_SUCCESS);
+    return error;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_display_t
+{
+    egl_display_t() : type(0), initialized(0) { }
+    
+    static egl_display_t& get_display(EGLDisplay dpy);
+    
+    static EGLBoolean is_valid(EGLDisplay dpy) {
+        return ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS) ? EGL_FALSE : EGL_TRUE;
+    }
+
+    NativeDisplayType   type;
+    volatile int32_t    initialized;
+};
+
+static egl_display_t gDisplays[NUM_DISPLAYS];
+
+egl_display_t& egl_display_t::get_display(EGLDisplay dpy) {
+    return gDisplays[uintptr_t(dpy)-1U];
+}
+
+struct egl_context_t {
+    enum {
+        IS_CURRENT      =   0x00010000,
+        NEVER_CURRENT   =   0x00020000
+    };
+    uint32_t            flags;
+    EGLDisplay          dpy;
+    EGLConfig           config;
+    EGLSurface          read;
+    EGLSurface          draw;
+
+    static inline egl_context_t* context(EGLContext ctx) {
+        ogles_context_t* const gl = static_cast<ogles_context_t*>(ctx);
+        return static_cast<egl_context_t*>(gl->rasterizer.base);
+    }
+};
+
+// ----------------------------------------------------------------------------
+
+struct egl_surface_t
+{
+    enum {
+        PAGE_FLIP = 0x00000001,
+        MAGIC     = 0x31415265
+    };
+
+    uint32_t            magic;
+    EGLDisplay          dpy;
+    EGLConfig           config;
+    EGLContext          ctx;
+
+                egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat);
+    virtual     ~egl_surface_t();
+    virtual     bool    isValid() const = 0;
+    
+    virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl) = 0;
+    virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl) = 0;
+    virtual     EGLint      getWidth() const = 0;
+    virtual     EGLint      getHeight() const = 0;
+    virtual     void*       getBits() const = 0;
+
+    virtual     EGLint      getHorizontalResolution() const;
+    virtual     EGLint      getVerticalResolution() const;
+    virtual     EGLint      getRefreshRate() const;
+    virtual     EGLint      getSwapBehavior() const;
+    virtual     EGLBoolean  swapBuffers();
+    virtual     EGLBoolean  swapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
+protected:
+    GGLSurface              depth;
+};
+
+egl_surface_t::egl_surface_t(EGLDisplay dpy,
+        EGLConfig config,
+        int32_t depthFormat)
+    : magic(0x31415265), dpy(dpy), config(config), ctx(0)
+{
+    depth.version = sizeof(GGLSurface);
+    depth.data = 0;
+    depth.format = depthFormat;
+}
+egl_surface_t::~egl_surface_t()
+{
+    magic = 0;
+    free(depth.data);
+}
+EGLBoolean egl_surface_t::swapBuffers() {
+    return EGL_FALSE;
+}
+EGLBoolean egl_surface_t::swapRectangle(
+        EGLint l, EGLint t, EGLint w, EGLint h) {
+    return EGL_FALSE;
+}
+EGLint egl_surface_t::getHorizontalResolution() const {
+    return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_surface_t::getVerticalResolution() const {
+    return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_surface_t::getRefreshRate() const {
+    return (60 * EGL_DISPLAY_SCALING);
+}
+EGLint egl_surface_t::getSwapBehavior() const {
+    return EGL_BUFFER_PRESERVED;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_window_surface_t : public egl_surface_t
+{
+    egl_window_surface_t(
+            EGLDisplay dpy, EGLConfig config,
+            int32_t depthFormat,
+            egl_native_window_t* window);
+
+     ~egl_window_surface_t();
+
+    virtual     bool        isValid() const { return nativeWindow->magic == 0x600913; }    
+    virtual     EGLBoolean  swapBuffers();
+    virtual     EGLBoolean  swapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
+    virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
+    virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
+    virtual     EGLint      getWidth() const    { return nativeWindow->width;  }
+    virtual     EGLint      getHeight() const   { return nativeWindow->height; }
+    virtual     void*       getBits() const;
+    virtual     EGLint      getHorizontalResolution() const;
+    virtual     EGLint      getVerticalResolution() const;
+    virtual     EGLint      getRefreshRate() const;
+    virtual     EGLint      getSwapBehavior() const;
+private:
+    egl_native_window_t*    nativeWindow;
+};
+
+egl_window_surface_t::egl_window_surface_t(EGLDisplay dpy,
+        EGLConfig config,
+        int32_t depthFormat,
+        egl_native_window_t* window)
+    : egl_surface_t(dpy, config, depthFormat), nativeWindow(window)
+{
+    if (depthFormat) {
+        depth.width   = window->width;
+        depth.height  = window->height;
+        depth.stride  = depth.width; // use the width here
+        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+        if (depth.data == 0) {
+            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+            return;
+        }
+    }
+    nativeWindow->incRef(nativeWindow);
+}
+egl_window_surface_t::~egl_window_surface_t() {
+    nativeWindow->decRef(nativeWindow);
+}
+
+EGLBoolean egl_window_surface_t::swapBuffers()
+{
+    uint32_t flags = nativeWindow->swapBuffers(nativeWindow);
+    if (flags & EGL_NATIVES_FLAG_SIZE_CHANGED) {
+        // TODO: we probaly should reset the swap rect here
+        // if the window size has changed
+        //    window->setSwapRectangle(Rect(info.w, info.h));
+        if (depth.data) {
+            free(depth.data);
+            depth.width   = nativeWindow->width;
+            depth.height  = nativeWindow->height;
+            depth.stride  = nativeWindow->stride;
+            depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+            if (depth.data == 0) {
+                setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+                return EGL_FALSE;
+            }
+        }
+    }
+    return EGL_TRUE;
+}
+
+EGLBoolean egl_window_surface_t::swapRectangle(
+        EGLint l, EGLint t, EGLint w, EGLint h)
+{
+    nativeWindow->setSwapRectangle(nativeWindow, l, t, w, h);
+    return EGL_TRUE;
+}
+EGLBoolean egl_window_surface_t::bindDrawSurface(ogles_context_t* gl)
+{
+    GGLSurface buffer;
+    buffer.version = sizeof(GGLSurface);
+    buffer.width   = nativeWindow->width;
+    buffer.height  = nativeWindow->height;
+    buffer.stride  = nativeWindow->stride;
+    buffer.data    = (GGLubyte*)nativeWindow->base + nativeWindow->offset;
+    buffer.format  = nativeWindow->format;
+    gl->rasterizer.procs.colorBuffer(gl, &buffer);
+    if (depth.data != gl->rasterizer.state.buffers.depth.data)
+        gl->rasterizer.procs.depthBuffer(gl, &depth);
+    return EGL_TRUE;
+}
+EGLBoolean egl_window_surface_t::bindReadSurface(ogles_context_t* gl)
+{
+    GGLSurface buffer;
+    buffer.version = sizeof(GGLSurface);
+    buffer.width   = nativeWindow->width;
+    buffer.height  = nativeWindow->height;
+    buffer.stride  = nativeWindow->stride;
+    buffer.data    = (GGLubyte*)nativeWindow->base + nativeWindow->offset;
+    buffer.format  = nativeWindow->format;
+    gl->rasterizer.procs.readBuffer(gl, &buffer);
+    return EGL_TRUE;
+}
+void* egl_window_surface_t::getBits() const {
+    return (GGLubyte*)nativeWindow->base + nativeWindow->offset;
+}
+EGLint egl_window_surface_t::getHorizontalResolution() const {
+    return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_window_surface_t::getVerticalResolution() const {
+    return (nativeWindow->ydpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_window_surface_t::getRefreshRate() const {
+    return (nativeWindow->fps * EGL_DISPLAY_SCALING);
+}
+EGLint egl_window_surface_t::getSwapBehavior() const {
+    uint32_t flags = nativeWindow->flags;
+    if (flags & EGL_NATIVES_FLAG_DESTROY_BACKBUFFER)
+        return EGL_BUFFER_DESTROYED;
+    return EGL_BUFFER_PRESERVED;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_pixmap_surface_t : public egl_surface_t
+{
+    egl_pixmap_surface_t(
+            EGLDisplay dpy, EGLConfig config,
+            int32_t depthFormat,
+            egl_native_pixmap_t const * pixmap);
+
+    virtual ~egl_pixmap_surface_t() { }
+
+    virtual     bool        isValid() const { return nativePixmap.version == sizeof(egl_native_pixmap_t); }    
+    virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
+    virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
+    virtual     EGLint      getWidth() const    { return nativePixmap.width;  }
+    virtual     EGLint      getHeight() const   { return nativePixmap.height; }
+    virtual     void*       getBits() const     { return nativePixmap.data; }
+private:
+    egl_native_pixmap_t     nativePixmap;
+};
+
+egl_pixmap_surface_t::egl_pixmap_surface_t(EGLDisplay dpy,
+        EGLConfig config,
+        int32_t depthFormat,
+        egl_native_pixmap_t const * pixmap)
+    : egl_surface_t(dpy, config, depthFormat), nativePixmap(*pixmap)
+{
+    if (depthFormat) {
+        depth.width   = pixmap->width;
+        depth.height  = pixmap->height;
+        depth.stride  = depth.width; // use the width here
+        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+        if (depth.data == 0) {
+            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+            return;
+        }
+    }
+}
+EGLBoolean egl_pixmap_surface_t::bindDrawSurface(ogles_context_t* gl)
+{
+    GGLSurface buffer;
+    buffer.version = sizeof(GGLSurface);
+    buffer.width   = nativePixmap.width;
+    buffer.height  = nativePixmap.height;
+    buffer.stride  = nativePixmap.stride;
+    buffer.data    = nativePixmap.data;
+    buffer.format  = nativePixmap.format;
+    
+    gl->rasterizer.procs.colorBuffer(gl, &buffer);
+    if (depth.data != gl->rasterizer.state.buffers.depth.data)
+        gl->rasterizer.procs.depthBuffer(gl, &depth);
+    return EGL_TRUE;
+}
+EGLBoolean egl_pixmap_surface_t::bindReadSurface(ogles_context_t* gl)
+{
+    GGLSurface buffer;
+    buffer.version = sizeof(GGLSurface);
+    buffer.width   = nativePixmap.width;
+    buffer.height  = nativePixmap.height;
+    buffer.stride  = nativePixmap.stride;
+    buffer.data    = nativePixmap.data;
+    buffer.format  = nativePixmap.format;
+    gl->rasterizer.procs.readBuffer(gl, &buffer);
+    return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_pbuffer_surface_t : public egl_surface_t
+{
+    egl_pbuffer_surface_t(
+            EGLDisplay dpy, EGLConfig config, int32_t depthFormat,
+            int32_t w, int32_t h, int32_t f);
+
+    virtual ~egl_pbuffer_surface_t();
+
+    virtual     bool        isValid() const { return pbuffer.data != 0; }    
+    virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
+    virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
+    virtual     EGLint      getWidth() const    { return pbuffer.width;  }
+    virtual     EGLint      getHeight() const   { return pbuffer.height; }
+    virtual     void*       getBits() const     { return pbuffer.data; }
+private:
+    GGLSurface  pbuffer;
+};
+
+egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy,
+        EGLConfig config, int32_t depthFormat,
+        int32_t w, int32_t h, int32_t f)
+    : egl_surface_t(dpy, config, depthFormat)
+{
+    size_t size = w*h;
+    switch (f) {
+    case GGL_PIXEL_FORMAT_RGB_565:      size *= 2; break;
+    case GGL_PIXEL_FORMAT_RGBA_8888:    size *= 4; break;
+    default:
+        LOGE("incompatible pixel format for pbuffer (format=%d)", f);
+        pbuffer.data = 0;
+        break;
+    }
+    pbuffer.version = sizeof(GGLSurface);
+    pbuffer.width   = w;
+    pbuffer.height  = h;
+    pbuffer.stride  = w;
+    pbuffer.data    = (GGLubyte*)malloc(size);
+    pbuffer.format  = f;
+    
+    if (depthFormat) {
+        depth.width   = pbuffer.width;
+        depth.height  = pbuffer.height;
+        depth.stride  = depth.width; // use the width here
+        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+        if (depth.data == 0) {
+            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+            return;
+        }
+    }
+}
+egl_pbuffer_surface_t::~egl_pbuffer_surface_t() {
+    free(pbuffer.data);
+}
+EGLBoolean egl_pbuffer_surface_t::bindDrawSurface(ogles_context_t* gl)
+{
+    gl->rasterizer.procs.colorBuffer(gl, &pbuffer);
+    if (depth.data != gl->rasterizer.state.buffers.depth.data)
+        gl->rasterizer.procs.depthBuffer(gl, &depth);
+    return EGL_TRUE;
+}
+EGLBoolean egl_pbuffer_surface_t::bindReadSurface(ogles_context_t* gl)
+{
+    gl->rasterizer.procs.readBuffer(gl, &pbuffer);
+    return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+
+struct config_pair_t {
+    GLint key;
+    GLint value;
+};
+
+struct configs_t {
+    const config_pair_t* array;
+    int                  size;
+};
+
+struct config_management_t {
+    GLint key;
+    bool (*match)(GLint reqValue, GLint confValue);
+    static bool atLeast(GLint reqValue, GLint confValue) {
+        return (reqValue == EGL_DONT_CARE) || (confValue >= reqValue);
+    }
+    static bool exact(GLint reqValue, GLint confValue) {
+        return (reqValue == EGL_DONT_CARE) || (confValue == reqValue);
+    }
+    static bool mask(GLint reqValue, GLint confValue) {
+        return (confValue & reqValue) == reqValue;
+    }
+};
+
+// ----------------------------------------------------------------------------
+
+static char const * const gVendorString     = "Google Inc.";
+static char const * const gVersionString    = "1.2 Android Driver";
+static char const * const gClientApiString  = "OpenGL ES";
+static char const * const gExtensionsString =
+    "EGL_ANDROID_swap_rectangle"                " "
+    "EGL_ANDROID_copy_front_to_back"            " "
+    "EGL_ANDROID_get_render_buffer_address"
+    ;
+
+// ----------------------------------------------------------------------------
+
+struct extention_map_t {
+    const char * const name;
+    void (*address)(void);
+};
+
+static const extention_map_t gExtentionMap[] = {
+    { "eglSwapRectangleANDROID",            (void(*)())&eglSwapRectangleANDROID },
+    { "glDrawTexsOES",                      (void(*)())&glDrawTexsOES },
+    { "glDrawTexiOES",                      (void(*)())&glDrawTexiOES },
+    { "glDrawTexfOES",                      (void(*)())&glDrawTexfOES },
+    { "glDrawTexxOES",                      (void(*)())&glDrawTexxOES },
+    { "glDrawTexsvOES",                     (void(*)())&glDrawTexsvOES },
+    { "glDrawTexivOES",                     (void(*)())&glDrawTexivOES },
+    { "glDrawTexfvOES",                     (void(*)())&glDrawTexfvOES },
+    { "glDrawTexxvOES",                     (void(*)())&glDrawTexxvOES },
+    { "glQueryMatrixxOES",                  (void(*)())&glQueryMatrixxOES },
+    { "glClipPlanef",                       (void(*)())&glClipPlanef },
+    { "glClipPlanex",                       (void(*)())&glClipPlanex },
+    { "glBindBuffer",                       (void(*)())&glBindBuffer },
+    { "glBufferData",                       (void(*)())&glBufferData },
+    { "glBufferSubData",                    (void(*)())&glBufferSubData },
+    { "glDeleteBuffers",                    (void(*)())&glDeleteBuffers },
+    { "glGenBuffers",                       (void(*)())&glGenBuffers },
+};
+
+/* 
+ * In the lists below, attributes names MUST be sorted.
+ * Additinnaly, all configs must be sorted according to
+ * the EGL specification.
+ */
+
+static config_pair_t const config_base_attribute_list[] = {
+        { EGL_STENCIL_SIZE,               0                                 },
+        { EGL_CONFIG_CAVEAT,              EGL_SLOW_CONFIG                   },
+        { EGL_LEVEL,                      0                                 },
+        { EGL_MAX_PBUFFER_HEIGHT,         0                                 },
+        { EGL_MAX_PBUFFER_PIXELS,         0                                 },
+        { EGL_MAX_PBUFFER_WIDTH,          0                                 },
+        { EGL_NATIVE_RENDERABLE,          EGL_TRUE                          },
+        { EGL_NATIVE_VISUAL_ID,           0                                 },
+        { EGL_NATIVE_VISUAL_TYPE,         GGL_PIXEL_FORMAT_RGB_565          },
+        { EGL_SAMPLES,                    0                                 },
+        { EGL_SAMPLE_BUFFERS,             0                                 },
+        { EGL_TRANSPARENT_TYPE,           EGL_NONE                          },
+        { EGL_TRANSPARENT_BLUE_VALUE,     0                                 },
+        { EGL_TRANSPARENT_GREEN_VALUE,    0                                 },
+        { EGL_TRANSPARENT_RED_VALUE,      0                                 },
+        { EGL_BIND_TO_TEXTURE_RGBA,       EGL_FALSE                         },
+        { EGL_BIND_TO_TEXTURE_RGB,        EGL_FALSE                         },
+        { EGL_MIN_SWAP_INTERVAL,          1                                 },
+        { EGL_MAX_SWAP_INTERVAL,          4                                 },
+};
+
+// These configs can override the base attribute list
+
+static config_pair_t const config_0_attribute_list[] = {
+        { EGL_BUFFER_SIZE,        16 },
+        { EGL_ALPHA_SIZE,          0 },
+        { EGL_BLUE_SIZE,           5 },
+        { EGL_GREEN_SIZE,          6 },
+        { EGL_RED_SIZE,            5 },
+        { EGL_DEPTH_SIZE,          0 },
+        { EGL_CONFIG_ID,           0 },
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT | EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_1_attribute_list[] = {
+        { EGL_BUFFER_SIZE,        16 },
+        { EGL_ALPHA_SIZE,          0 },
+        { EGL_BLUE_SIZE,           5 },
+        { EGL_GREEN_SIZE,          6 },
+        { EGL_RED_SIZE,            5 },
+        { EGL_DEPTH_SIZE,         16 },
+        { EGL_CONFIG_ID,           1 },
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT | EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_2_attribute_list[] = {
+        { EGL_BUFFER_SIZE,        32 },
+        { EGL_ALPHA_SIZE,          8 },
+        { EGL_BLUE_SIZE,           8 },
+        { EGL_GREEN_SIZE,          8 },
+        { EGL_RED_SIZE,            8 },
+        { EGL_DEPTH_SIZE,          0 },
+        { EGL_CONFIG_ID,           2 },
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT | EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_3_attribute_list[] = {
+        { EGL_BUFFER_SIZE,        32 },
+        { EGL_ALPHA_SIZE,          8 },
+        { EGL_BLUE_SIZE,           8 },
+        { EGL_GREEN_SIZE,          8 },
+        { EGL_RED_SIZE,            8 },
+        { EGL_DEPTH_SIZE,         16 },
+        { EGL_CONFIG_ID,           3 },
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT | EGL_PIXMAP_BIT },
+};
+
+static configs_t const gConfigs[] = {
+        { config_0_attribute_list, NELEM(config_0_attribute_list) },
+        { config_1_attribute_list, NELEM(config_1_attribute_list) },
+        { config_2_attribute_list, NELEM(config_2_attribute_list) },
+        { config_3_attribute_list, NELEM(config_3_attribute_list) },
+};
+
+static config_management_t const gConfigManagement[] = {
+        { EGL_BUFFER_SIZE,                config_management_t::atLeast },
+        { EGL_ALPHA_SIZE,                 config_management_t::atLeast },
+        { EGL_BLUE_SIZE,                  config_management_t::atLeast },
+        { EGL_GREEN_SIZE,                 config_management_t::atLeast },
+        { EGL_RED_SIZE,                   config_management_t::atLeast },
+        { EGL_DEPTH_SIZE,                 config_management_t::atLeast },
+        { EGL_STENCIL_SIZE,               config_management_t::atLeast },
+        { EGL_CONFIG_CAVEAT,              config_management_t::exact   },
+        { EGL_CONFIG_ID,                  config_management_t::exact   },
+        { EGL_LEVEL,                      config_management_t::exact   },
+        { EGL_MAX_PBUFFER_HEIGHT,         config_management_t::exact   },
+        { EGL_MAX_PBUFFER_PIXELS,         config_management_t::exact   },
+        { EGL_MAX_PBUFFER_WIDTH,          config_management_t::exact   },
+        { EGL_NATIVE_RENDERABLE,          config_management_t::exact   },
+        { EGL_NATIVE_VISUAL_ID,           config_management_t::exact   },
+        { EGL_NATIVE_VISUAL_TYPE,         config_management_t::exact   },
+        { EGL_SAMPLES,                    config_management_t::exact   },
+        { EGL_SAMPLE_BUFFERS,             config_management_t::exact   },
+        { EGL_SURFACE_TYPE,               config_management_t::mask    },
+        { EGL_TRANSPARENT_TYPE,           config_management_t::exact   },
+        { EGL_TRANSPARENT_BLUE_VALUE,     config_management_t::exact   },
+        { EGL_TRANSPARENT_GREEN_VALUE,    config_management_t::exact   },
+        { EGL_TRANSPARENT_RED_VALUE,      config_management_t::exact   },
+        { EGL_BIND_TO_TEXTURE_RGBA,       config_management_t::exact   },
+        { EGL_BIND_TO_TEXTURE_RGB,        config_management_t::exact   },
+        { EGL_MIN_SWAP_INTERVAL,          config_management_t::exact   },
+        { EGL_MAX_SWAP_INTERVAL,          config_management_t::exact   },
+};
+
+static config_pair_t const config_defaults[] = {
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT },
+};
+
+// ----------------------------------------------------------------------------
+
+template<typename T>
+static int binarySearch(T const sortedArray[], int first, int last, EGLint key)
+{
+   while (first <= last) {
+       int mid = (first + last) / 2;
+       if (key > sortedArray[mid].key) { 
+           first = mid + 1;
+       } else if (key < sortedArray[mid].key) { 
+           last = mid - 1;
+       } else {
+           return mid;
+       }
+   }
+   return -1;
+}
+
+static int isAttributeMatching(int i, EGLint attr, EGLint val)
+{
+    // look for the attribute in all of our configs
+    config_pair_t const* configFound = gConfigs[i].array; 
+    int index = binarySearch<config_pair_t>(
+            gConfigs[i].array,
+            0, gConfigs[i].size-1,
+            attr);
+    if (index < 0) {
+        configFound = config_base_attribute_list; 
+        index = binarySearch<config_pair_t>(
+                config_base_attribute_list,
+                0, NELEM(config_base_attribute_list)-1,
+                attr);
+    }
+    if (index >= 0) {
+        // attribute found, check if this config could match
+        int cfgMgtIndex = binarySearch<config_management_t>(
+                gConfigManagement,
+                0, NELEM(gConfigManagement)-1,
+                attr);
+        if (index >= 0) {
+            bool match = gConfigManagement[cfgMgtIndex].match(
+                    val, configFound[index].value);
+            if (match) {
+                // this config matches
+                return 1;
+            }
+        } else {
+            // attribute nont found. this should NEVER happen.
+        }
+    } else {
+        // error, this attribute doesn't exist
+    }
+    return 0;
+}
+
+static int makeCurrent(ogles_context_t* gl)
+{
+    ogles_context_t* current = (ogles_context_t*)getGlThreadSpecific();
+    if (gl) {
+        egl_context_t* c = egl_context_t::context(gl);
+        if (c->flags & egl_context_t::IS_CURRENT) {
+            if (current != gl) {
+                // it is an error to set a context current, if it's already
+                // current to another thread
+                return -1;
+            }
+        } else {
+            if (current) {
+                // mark the current context as not current, and flush
+                glFlush();
+                egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT;
+            }
+        }
+        if (!(c->flags & egl_context_t::IS_CURRENT)) {
+            // The context is not current, make it current!
+            setGlThreadSpecific(gl);
+            c->flags |= egl_context_t::IS_CURRENT;
+        }
+    } else {
+        if (current) {
+            // mark the current context as not current, and flush
+            glFlush();
+            egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT;
+        }
+        // this thread has no context attached to it
+        setGlThreadSpecific(0);
+    }
+    return 0;
+}
+
+static EGLBoolean getConfigAttrib(EGLDisplay dpy, EGLConfig config,
+        EGLint attribute, EGLint *value)
+{
+    size_t numConfigs =  NELEM(gConfigs);
+    int index = (int)config;
+    if (uint32_t(index) >= numConfigs)
+        return setError(EGL_BAD_CONFIG, EGL_FALSE);
+
+    int attrIndex;
+    attrIndex = binarySearch<config_pair_t>(
+            gConfigs[index].array,
+            0, gConfigs[index].size-1,
+            attribute);
+    if (attrIndex>=0) {
+        *value = gConfigs[index].array[attrIndex].value;
+        return EGL_TRUE;
+    }
+
+    attrIndex = binarySearch<config_pair_t>(
+            config_base_attribute_list,
+            0, NELEM(config_base_attribute_list)-1,
+            attribute);
+    if (attrIndex>=0) {
+        *value = config_base_attribute_list[attrIndex].value;
+        return EGL_TRUE;
+    }
+    return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+}
+
+static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config,
+        NativeWindowType window, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+    if (window == 0)
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    EGLint surfaceType;
+    if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
+        return EGL_FALSE;
+
+    if (!(surfaceType & EGL_WINDOW_BIT))
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    EGLint configID;
+    if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
+        return EGL_FALSE;
+
+    int32_t depthFormat;
+    int32_t pixelFormat;
+    switch(configID) {
+    case 0: 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = 0;
+        break;
+    case 1:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    case 2:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = 0;
+        break;
+    case 3:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    default:
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    // XXX: we don't have access to the pixelFormat here just yet.
+    // (it's possible that the surface is not fully initialized)
+    // maybe this should be done after the page-flip
+    //if (EGLint(info.format) != pixelFormat)
+    //    return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    egl_surface_t* surface =
+        new egl_window_surface_t(dpy, config, depthFormat,
+                static_cast<egl_native_window_t*>(window));
+
+    if (!surface->isValid()) {
+        // there was a problem in the ctor, the error
+        // flag has been set.
+        delete surface;
+        surface = 0;
+    }
+    return surface;
+}
+
+static EGLSurface createPixmapSurface(EGLDisplay dpy, EGLConfig config,
+        NativePixmapType pixmap, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+    if (pixmap == 0)
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    EGLint surfaceType;
+    if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
+        return EGL_FALSE;
+
+    if (!(surfaceType & EGL_PIXMAP_BIT))
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    EGLint configID;
+    if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
+        return EGL_FALSE;
+
+    int32_t depthFormat;
+    int32_t pixelFormat;
+    switch(configID) {
+    case 0: 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = 0;
+        break;
+    case 1:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    case 2:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = 0;
+        break;
+    case 3:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    default:
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if (pixmap->format != pixelFormat)
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    egl_surface_t* surface =
+        new egl_pixmap_surface_t(dpy, config, depthFormat,
+                static_cast<egl_native_pixmap_t*>(pixmap));
+
+    if (!surface->isValid()) {
+        // there was a problem in the ctor, the error
+        // flag has been set.
+        delete surface;
+        surface = 0;
+    }
+    return surface;
+}
+
+static EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config,
+        const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+
+    EGLint surfaceType;
+    if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
+        return EGL_FALSE;
+    
+    if (!(surfaceType & EGL_PBUFFER_BIT))
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+        
+    EGLint configID;
+    if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
+        return EGL_FALSE;
+
+    int32_t depthFormat;
+    int32_t pixelFormat;
+    switch(configID) {
+    case 0: 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = 0;
+        break;
+    case 1:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    case 2:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = 0;
+        break;
+    case 3:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    default:
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    int32_t w = 0;
+    int32_t h = 0;
+    while (attrib_list[0]) {
+        if (attrib_list[0] == EGL_WIDTH)  w = attrib_list[1];
+        if (attrib_list[0] == EGL_HEIGHT) h = attrib_list[1];
+        attrib_list+=2;
+    }
+
+    egl_surface_t* surface =
+        new egl_pbuffer_surface_t(dpy, config, depthFormat, w, h, pixelFormat);
+
+    if (!surface->isValid()) {
+        // there was a problem in the ctor, the error
+        // flag has been set.
+        delete surface;
+        surface = 0;
+    }
+    return surface;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+// Initialization
+// ----------------------------------------------------------------------------
+
+EGLDisplay eglGetDisplay(NativeDisplayType display)
+{
+#ifndef HAVE_ANDROID_OS
+    // this just needs to be done once
+    if (gGLKey == -1) {
+        pthread_mutex_lock(&gInitMutex);
+        if (gGLKey == -1)
+            pthread_key_create(&gGLKey, NULL);
+        pthread_mutex_unlock(&gInitMutex);
+    }
+#endif
+    if (display == EGL_DEFAULT_DISPLAY) {
+        EGLDisplay dpy = (EGLDisplay)1;
+        egl_display_t& d = egl_display_t::get_display(dpy);
+        d.type = display;
+        return dpy;
+    }    
+    return EGL_NO_DISPLAY;
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    
+    EGLBoolean res = EGL_TRUE;
+    egl_display_t& d = egl_display_t::get_display(dpy);
+    
+    if (android_atomic_inc(&d.initialized) == 0) {
+        // initialize stuff here if needed
+        //pthread_mutex_lock(&gInitMutex);
+        //pthread_mutex_unlock(&gInitMutex);
+    }
+
+    if (res == EGL_TRUE) {
+        if (major != NULL) *major = 1;
+        if (minor != NULL) *minor = 2;
+    }
+    return res;
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    EGLBoolean res = EGL_TRUE;
+    egl_display_t& d = egl_display_t::get_display(dpy);
+    if (android_atomic_dec(&d.initialized) == 1) {
+        // TODO: destroy all resources (surfaces, contextes, etc...)
+        //pthread_mutex_lock(&gInitMutex);
+        //pthread_mutex_unlock(&gInitMutex);
+    }
+    return res;
+}
+
+// ----------------------------------------------------------------------------
+// configuration
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglGetConfigs(   EGLDisplay dpy,
+                            EGLConfig *configs,
+                            EGLint config_size, EGLint *num_config)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    GLint numConfigs = NELEM(gConfigs);
+    if (!configs) {
+        *num_config = numConfigs;
+        return EGL_TRUE;
+    }
+    GLint i;
+    for (i=0 ; i<numConfigs && i<config_size ; i++) {
+        *configs++ = (EGLConfig)i;
+    }
+    *num_config = i;
+    return EGL_TRUE;
+}
+
+EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
+                            EGLConfig *configs, EGLint config_size,
+                            EGLint *num_config)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    if (ggl_unlikely(configs==0 || attrib_list==0)) {
+        *num_config = 0;
+        return EGL_TRUE;
+    }
+    
+    int numAttributes = 0;
+    int numConfigs =  NELEM(gConfigs);
+    uint32_t possibleMatch = (1<<numConfigs)-1;
+    while(possibleMatch && *attrib_list != EGL_NONE) {
+        numAttributes++;
+        EGLint attr = *attrib_list++;
+        EGLint val  = *attrib_list++;
+        for (int i=0 ; i<numConfigs ; i++) {
+            if (!(possibleMatch & (1<<i)))
+                continue;
+            if (isAttributeMatching(i, attr, val) == 0) {
+                possibleMatch &= ~(1<<i);
+            }
+        }
+    }
+
+    // now, handle the attributes which have a useful default value
+    for (size_t j=0 ; j<NELEM(config_defaults) ; j++) {
+        // see if this attribute was specified, if not apply its
+        // default value
+        if (binarySearch<config_pair_t>(
+                (config_pair_t const*)attrib_list,
+                0, numAttributes,
+                config_defaults[j].key) < 0)
+        {
+            for (int i=0 ; i<numConfigs ; i++) {
+                if (!(possibleMatch & (1<<i)))
+                    continue;
+                if (isAttributeMatching(i,
+                        config_defaults[j].key,
+                        config_defaults[j].value) == 0)
+                {
+                    possibleMatch &= ~(1<<i);
+                }
+            }
+        }
+    }
+
+    // return the configurations found
+    int n=0;
+    if (possibleMatch) {
+        for (int i=0 ; config_size && i<numConfigs ; i++) {
+            if (possibleMatch & (1<<i)) {
+               *configs++ = (EGLConfig)i;
+                config_size--;
+                n++;
+            }
+        }
+    }
+    *num_config = n;
+     return EGL_TRUE;
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+        EGLint attribute, EGLint *value)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    return getConfigAttrib(dpy, config, attribute, value);
+}
+
+// ----------------------------------------------------------------------------
+// surfaces
+// ----------------------------------------------------------------------------
+
+EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
+                                    NativeWindowType window,
+                                    const EGLint *attrib_list)
+{
+    return createWindowSurface(dpy, config, window, attrib_list);
+}
+    
+EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
+                                    NativePixmapType pixmap,
+                                    const EGLint *attrib_list)
+{
+    return createPixmapSurface(dpy, config, pixmap, attrib_list);
+}
+
+EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
+                                    const EGLint *attrib_list)
+{
+    // none of our configs support pbuffers
+    // (in fact it's working but since we can't use them as 
+    // textures yet, it's not useful at all)
+    //createPbufferSurface(dpy, config, attrib_list);
+    return EGL_NO_SURFACE;
+}
+                                    
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    if (eglSurface != EGL_NO_SURFACE) {
+        egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
+        if (surface->magic != egl_surface_t::MAGIC)
+            return setError(EGL_BAD_SURFACE, EGL_FALSE);
+        if (surface->dpy != dpy)
+            return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+        delete surface;
+    }
+    return EGL_TRUE;
+}
+
+EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface eglSurface,
+                            EGLint attribute, EGLint *value)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_surface_t* surface = static_cast<egl_surface_t*>(eglSurface);
+    if (surface->dpy != dpy)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    EGLBoolean ret = EGL_TRUE;
+    switch (attribute) {
+        case EGL_CONFIG_ID:
+            ret = getConfigAttrib(dpy, surface->config, EGL_CONFIG_ID, value);
+            break;
+        case EGL_WIDTH:
+            *value = surface->getWidth();
+            break;
+        case EGL_HEIGHT:
+            *value = surface->getHeight();
+            break;
+        case EGL_LARGEST_PBUFFER:
+            // not modified for a window or pixmap surface
+            break;
+        case EGL_TEXTURE_FORMAT:
+            *value = EGL_NO_TEXTURE;
+            break;
+        case EGL_TEXTURE_TARGET:
+            *value = EGL_NO_TEXTURE;
+            break;
+        case EGL_MIPMAP_TEXTURE:
+            *value = EGL_FALSE;
+            break;
+        case EGL_MIPMAP_LEVEL:
+            *value = 0;
+            break;
+        case EGL_RENDER_BUFFER:
+            // TODO: return the real RENDER_BUFFER here
+            *value = EGL_BACK_BUFFER;
+            break;
+        case EGL_HORIZONTAL_RESOLUTION:
+            // pixel/mm * EGL_DISPLAY_SCALING
+            *value = surface->getHorizontalResolution();
+            break;
+        case EGL_VERTICAL_RESOLUTION:
+            // pixel/mm * EGL_DISPLAY_SCALING
+            *value = surface->getVerticalResolution();
+            break;
+        case EGL_PIXEL_ASPECT_RATIO: {
+            // w/h * EGL_DISPLAY_SCALING
+            int wr = surface->getHorizontalResolution();
+            int hr = surface->getVerticalResolution();
+            *value = (wr * EGL_DISPLAY_SCALING) / hr;
+        } break;
+        case EGL_SWAP_BEHAVIOR:
+            *value = surface->getSwapBehavior(); 
+            break;
+        default:
+            ret = setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+    }
+    return ret;
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
+                            EGLContext share_list, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+
+    ogles_context_t* gl = ogles_init(sizeof(egl_context_t));
+    if (!gl) return setError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+
+    egl_context_t* c = static_cast<egl_context_t*>(gl->rasterizer.base);
+    c->flags = egl_context_t::NEVER_CURRENT;
+    c->dpy = dpy;
+    c->config = config;
+    c->read = 0;
+    c->draw = 0;
+    return (EGLContext)gl;
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_context_t* c = egl_context_t::context(ctx);
+    if (c->flags & egl_context_t::IS_CURRENT)
+        setGlThreadSpecific(0);
+    ogles_uninit((ogles_context_t*)ctx);
+    return EGL_TRUE;
+}
+
+EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
+                            EGLSurface read, EGLContext ctx)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    if (draw) {
+        egl_surface_t* s = (egl_surface_t*)draw;
+        if (s->dpy != dpy)
+            return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+        // TODO: check that draw and read are compatible with the context
+    }
+
+    EGLContext current_ctx = EGL_NO_CONTEXT;
+    if (ctx == EGL_NO_CONTEXT) {
+        // if we're detaching, we need the current context
+        current_ctx = (EGLContext)getGlThreadSpecific();
+    } else {
+        egl_context_t* c = egl_context_t::context(ctx);
+        egl_surface_t* d = (egl_surface_t*)draw;
+        egl_surface_t* r = (egl_surface_t*)read;
+        if ((d && d->ctx && d->ctx != ctx) ||
+            (r && r->ctx && r->ctx != ctx)) {
+            // once of the surface is bound to a context in another thread
+            return setError(EGL_BAD_ACCESS, EGL_FALSE);
+        }
+    }
+
+    ogles_context_t* gl = (ogles_context_t*)ctx;
+    if (makeCurrent(gl) == 0) {
+        if (ctx) {
+            egl_context_t* c = egl_context_t::context(ctx);
+            egl_surface_t* d = (egl_surface_t*)draw;
+            egl_surface_t* r = (egl_surface_t*)read;
+            c->read = read;
+            c->draw = draw;
+            if (c->flags & egl_context_t::NEVER_CURRENT) {
+                c->flags &= ~egl_context_t::NEVER_CURRENT;
+                GLint w = 0;
+                GLint h = 0;
+                if (draw) {
+                    w = d->getWidth();
+                    h = d->getHeight();
+                }
+                ogles_surfaceport(gl, 0, 0);
+                ogles_viewport(gl, 0, 0, w, h);
+                ogles_scissor(gl, 0, 0, w, h);
+            }
+            if (d) {
+                d->ctx = ctx;
+                d->bindDrawSurface(gl);
+            }
+            if (r) {
+                r->ctx = ctx;
+                r->bindReadSurface(gl);
+            }
+        } else {
+            // if surfaces were bound to the context bound to this thread
+            // mark then as unbound.
+            if (current_ctx) {
+                egl_context_t* c = egl_context_t::context(current_ctx);
+                egl_surface_t* d = (egl_surface_t*)c->draw;
+                egl_surface_t* r = (egl_surface_t*)c->read;
+                if (d) d->ctx = EGL_NO_CONTEXT;
+                if (r) r->ctx = EGL_NO_CONTEXT;
+            }
+        }
+        return EGL_TRUE;
+    }
+    return setError(EGL_BAD_ACCESS, EGL_FALSE);
+}
+
+EGLContext eglGetCurrentContext(void)
+{
+    // eglGetCurrentContext returns the current EGL rendering context,
+    // as specified by eglMakeCurrent. If no context is current,
+    // EGL_NO_CONTEXT is returned.
+    return (EGLContext)getGlThreadSpecific();
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+    // eglGetCurrentSurface returns the read or draw surface attached
+    // to the current EGL rendering context, as specified by eglMakeCurrent.
+    // If no context is current, EGL_NO_SURFACE is returned.
+    EGLContext ctx = (EGLContext)getGlThreadSpecific();
+    if (ctx == EGL_NO_CONTEXT) return EGL_NO_SURFACE;
+    egl_context_t* c = egl_context_t::context(ctx);
+    if (readdraw == EGL_READ) {
+        return c->read;
+    } else if (readdraw == EGL_DRAW) {
+        return c->draw;
+    }
+    return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+}
+
+EGLDisplay eglGetCurrentDisplay(void)
+{
+    // eglGetCurrentDisplay returns the current EGL display connection
+    // for the current EGL rendering context, as specified by eglMakeCurrent.
+    // If no context is current, EGL_NO_DISPLAY is returned.
+    EGLContext ctx = (EGLContext)getGlThreadSpecific();
+    if (ctx == EGL_NO_CONTEXT) return EGL_NO_DISPLAY;
+    egl_context_t* c = egl_context_t::context(ctx);
+    return c->dpy;
+}
+
+EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
+                            EGLint attribute, EGLint *value)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_context_t* c = egl_context_t::context(ctx);
+    switch (attribute) {
+        case EGL_CONFIG_ID:
+            // Returns the ID of the EGL frame buffer configuration with
+            // respect to which the context was created
+            return getConfigAttrib(dpy, c->config, EGL_CONFIG_ID, value);
+    }
+    return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+}
+
+EGLBoolean eglWaitGL(void)
+{
+    return EGL_TRUE;
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+    return EGL_TRUE;
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    
+    egl_surface_t* d = static_cast<egl_surface_t*>(draw);
+    if (d->dpy != dpy)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    // post the surface
+    d->swapBuffers();
+
+    // if it's bound to a context, update the buffer
+    if (d->ctx != EGL_NO_CONTEXT) {
+        d->bindDrawSurface((ogles_context_t*)d->ctx);
+        // if this surface is also the read surface of the context
+        // it is bound to, make sure to update the read buffer as well.
+        // The EGL spec is a little unclear about this.
+        egl_context_t* c = egl_context_t::context(d->ctx);
+        if (c->read == draw) {
+            d->bindReadSurface((ogles_context_t*)d->ctx);
+        }
+    }
+
+    return EGL_TRUE;
+}
+
+EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
+                            NativePixmapType target)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglCopyBuffers()
+    return EGL_FALSE;
+}
+
+EGLint eglGetError(void)
+{
+    return getError();
+}
+
+const char* eglQueryString(EGLDisplay dpy, EGLint name)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, (const char*)0);
+
+    switch (name) {
+        case EGL_VENDOR:
+            return gVendorString;
+        case EGL_VERSION:
+            return gVersionString;
+        case EGL_EXTENSIONS:
+            return gExtensionsString;
+        case EGL_CLIENT_APIS:
+            return gClientApiString;
+    }
+    return setError(EGL_BAD_PARAMETER, (const char *)0);
+}
+
+// ----------------------------------------------------------------------------
+// EGL 1.1
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglSurfaceAttrib(
+        EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglSurfaceAttrib()
+    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+EGLBoolean eglBindTexImage(
+        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglBindTexImage()
+    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+EGLBoolean eglReleaseTexImage(
+        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglReleaseTexImage()
+    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglSwapInterval()
+    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+// ----------------------------------------------------------------------------
+// EGL 1.2
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+    if (api != EGL_OPENGL_ES_API)
+        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+    return EGL_TRUE;
+}
+
+EGLenum eglQueryAPI(void)
+{
+    return EGL_OPENGL_ES_API;
+}
+
+EGLBoolean eglWaitClient(void)
+{
+    glFinish();
+    return EGL_TRUE;
+}
+
+EGLBoolean eglReleaseThread(void)
+{
+    // TODO: eglReleaseThread()
+    return EGL_TRUE;
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(
+          EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
+          EGLConfig config, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+    // TODO: eglCreatePbufferFromClientBuffer()
+    return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+}
+
+// ----------------------------------------------------------------------------
+// Android extentions
+// ----------------------------------------------------------------------------
+
+void (*eglGetProcAddress (const char *procname))()
+{
+    extention_map_t const * const map = gExtentionMap;
+    for (uint32_t i=0 ; i<NELEM(gExtentionMap) ; i++) {
+        if (!strcmp(procname, map[i].name)) {
+            return map[i].address;
+        }
+    }
+    return NULL;
+}
+
+EGLBoolean eglSwapRectangleANDROID(
+        EGLDisplay dpy, EGLSurface draw,
+        EGLint l, EGLint t, EGLint w, EGLint h)
+{    
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_surface_t* surface = (egl_surface_t*)draw;
+    if (surface->dpy != dpy)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    return surface->swapRectangle(l, t, w, h);
+}
diff --git a/opengl/libagl/fixed_asm.S b/opengl/libagl/fixed_asm.S
new file mode 100644
index 0000000..6cbc56f
--- /dev/null
+++ b/opengl/libagl/fixed_asm.S
@@ -0,0 +1,65 @@
+/* libs/opengles/fixed_asm.S
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+
+    .text
+    .align
+    
+    .global gglFloatToFixed
+    .global gglFloatToFixedFast
+
+
+/*
+ * Converts a float to a s15.16 fixed-point number.
+ * this doesn't handle floats out of the [-32768, +32768[ range
+ * and doesn't performs round-to-nearest.
+ * however, it's very fast :-)
+ */
+
+gglFloatToFixedFast:
+        movs    r1, r0, lsl #1          /* remove bit sign */
+        mov     r2, #0x8E               /* 127 + 15 */
+        sub     r1, r2, r1, lsr #24     /* compute shift */
+        mov     r2, r0, lsl #8          /* mantissa<<8 */
+        orr     r2, r2, #0x80000000     /* add the missing 1 */
+        mov     r0, r2, lsr r1          /* scale to 16.16 */
+        rsbcs   r0, r0, #0              /* negate if needed */
+        bx      lr
+
+/*
+ * this version rounds-to-nearest and saturates numbers
+ * outside the range (but not NaNs).
+ */
+
+gglFloatToFixed:
+        mov     r1, r0, lsl #1          /* remove bit sign */
+        mov     r2, #0x8E               /* 127 + 15 */
+        subs    r1, r2, r1, lsr #24     /* compute shift */
+        bls     0f                      /* too big */
+        mov     r2, r0, lsl #8          /* mantissa<<8 */
+        orr     r2, r2, #0x80000000     /* add the missing 1 */
+        mov     r3, r0
+        movs    r0, r2, lsr r1          /* scale to 16.16 */
+        addcs   r0, r0, #1              /* round-to-nearest */
+        tst     r3, #0x80000000         /* negative? */
+        rsbne   r0, r0, #0              /* negate if needed */
+        bx      lr 
+ 
+0:      ands    r0, r0, #0x80000000     /* keep only the sign bit */
+        moveq   r0, #0x7fffffff         /* positive, maximum value */
+        bx      lr
+
diff --git a/opengl/libagl/fp.cpp b/opengl/libagl/fp.cpp
new file mode 100644
index 0000000..ae5f1fe
--- /dev/null
+++ b/opengl/libagl/fp.cpp
@@ -0,0 +1,87 @@
+/* libs/opengles/fp.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 "fp.h"
+
+// ----------------------------------------------------------------------------
+
+#if !defined(__arm__)
+GGLfixed gglFloatToFixed(float v) {   
+    return GGLfixed(floorf(v * 65536.0f + 0.5f));
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+namespace gl {
+
+GLfloat fixedToFloat(GLfixed x)
+{
+#if DEBUG_USE_FLOATS
+    return x / 65536.0f;
+#else
+    if (!x) return 0;
+    const uint32_t s = x & 0x80000000;
+    union {
+        uint32_t i;
+        float f;
+    };
+    i = s ? -x : x;
+    const int c = gglClz(i) - 8;
+    i = (c>=0) ? (i<<c) : (i>>-c);
+    const uint32_t e = 134 - c;
+    i &= ~0x800000;
+    i |= e<<23;
+    i |= s;
+    return f;
+#endif
+}
+
+float sinef(float x)
+{
+    const float A =   1.0f / (2.0f*M_PI);
+    const float B = -16.0f;
+    const float C =   8.0f;
+
+    // scale angle for easy argument reduction
+    x *= A;
+    
+    if (fabsf(x) >= 0.5f) {
+        // Argument reduction
+        x = x - ceilf(x + 0.5f) + 1.0f; 
+    }
+
+    const float y = B*x*fabsf(x) + C*x;
+    return 0.2215f * (y*fabsf(y) - y) + y;
+}
+
+float cosinef(float x)
+{
+    return sinef(x + float(M_PI/2));
+}
+
+void sincosf(GLfloat angle, GLfloat* s, GLfloat* c) {
+    *s = sinef(angle);
+    *c = cosinef(angle);
+}
+
+}; // namespace fp_utils
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/opengl/libagl/fp.h b/opengl/libagl/fp.h
new file mode 100644
index 0000000..6d0c183
--- /dev/null
+++ b/opengl/libagl/fp.h
@@ -0,0 +1,243 @@
+/* libs/opengles/fp.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_FP_H
+#define ANDROID_OPENGLES_FP_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <math.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+#define DEBUG_USE_FLOATS      0
+
+// ----------------------------------------------------------------------------
+
+extern "C" GLfixed gglFloatToFixed(float f) __attribute__((const));
+
+// ----------------------------------------------------------------------------
+namespace android {
+
+namespace gl {
+
+        GLfloat fixedToFloat(GLfixed) CONST;
+
+        void    sincosf(GLfloat angle, GLfloat* s, GLfloat* c);
+        float   sinef(GLfloat x) CONST;
+        float   cosinef(GLfloat x) CONST;
+
+inline bool     cmpf(GLfloat a, GLfloat b) CONST;
+inline bool     isZerof(GLfloat) CONST;
+inline bool     isOnef(GLfloat) CONST;
+
+inline int      isZeroOrNegativef(GLfloat) CONST;
+
+inline int      exponent(GLfloat) CONST;
+inline int32_t  mantissa(GLfloat) CONST;
+inline GLfloat  clampToZerof(GLfloat) CONST;
+inline GLfloat  reciprocalf(GLfloat) CONST;
+inline GLfloat  rsqrtf(GLfloat) CONST;
+inline GLfloat  sqrf(GLfloat) CONST;
+inline GLfloat  addExpf(GLfloat v, int e) CONST;
+inline GLfloat  mul2f(GLfloat v) CONST;
+inline GLfloat  div2f(GLfloat v) CONST;
+inline GLfloat  absf(GLfloat v) CONST;
+
+
+/* 
+ * float fastexpf(float) : a fast approximation of expf(x)
+ *		give somewhat accurate results for -88 <= x <= 88
+ *
+ * exp(x) = 2^(x/ln(2))
+ * we use the properties of float encoding
+ * to get a fast 2^ and linear interpolation
+ *
+ */
+
+inline float fastexpf(float y) __attribute__((const));
+
+inline float fastexpf(float y)
+{
+	union {
+		float	r;
+		int32_t	i;
+	} u;	
+
+	// 127*ln(2) = 88
+	if (y < -88.0f) {
+		u.r = 0.0f;
+	} else if (y > 88.0f) {
+		u.r = INFINITY;
+	} else {
+		const float kOneOverLogTwo = (1L<<23) / M_LN2;
+		const int32_t kExponentBias = 127L<<23;
+		const int32_t e = int32_t(y*kOneOverLogTwo);
+		u.i = e + kExponentBias;
+	}
+	
+	return u.r;
+}
+
+
+bool cmpf(GLfloat a, GLfloat b) {
+#if DEBUG_USE_FLOATS
+    return a == b;
+#else
+    union {
+        float       f;
+        uint32_t    i;
+    } ua, ub;
+    ua.f = a;
+    ub.f = b;
+    return ua.i == ub.i;
+#endif
+} 
+
+bool isZerof(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v == 0;
+#else
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    return (i<<1) == 0;
+#endif
+}
+
+bool isOnef(GLfloat v) {
+    return cmpf(v, 1.0f);
+}
+
+int isZeroOrNegativef(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v <= 0;
+#else
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    return isZerof(v) | (i>>31);
+#endif
+}
+
+int exponent(GLfloat v) {
+    union {
+        float    f;
+        uint32_t i;
+    };
+    f = v;
+    return ((i << 1) >> 24) - 127;
+}
+
+int32_t mantissa(GLfloat v) {
+    union {
+        float    f;
+        uint32_t i;
+    };
+    f = v;
+    if (!(i&0x7F800000)) return 0;
+    const int s = i >> 31;
+    i |= (1L<<23);
+    i &= ~0xFF000000;
+    return s ? -i : i;
+}
+
+GLfloat clampToZerof(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v<0 ? 0 : (v>1 ? 1 : v);
+#else
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    i &= ~(i>>31);
+    return f;
+#endif
+}
+
+GLfloat reciprocalf(GLfloat v) {
+    // XXX: do better
+    return 1.0f / v;
+}
+
+GLfloat rsqrtf(GLfloat v) {
+    // XXX: do better
+    return 1.0f / sqrtf(v);
+}
+
+GLfloat sqrf(GLfloat v) {
+    // XXX: do better
+    return v*v;
+}
+
+GLfloat addExpf(GLfloat v, int e) {
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    if (i<<1) { // XXX: deal with over/underflow	
+        i += int32_t(e)<<23;
+    }
+    return f;
+}
+
+GLfloat mul2f(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v*2;
+#else
+    return addExpf(v, 1);
+#endif
+}
+
+GLfloat div2f(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v*0.5f;
+#else
+    return addExpf(v, -1);
+#endif
+}
+
+GLfloat  absf(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v<0 ? -v : v;
+#else
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    i &= ~0x80000000;
+    return f;
+#endif
+}
+
+};  // namespace gl
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_FP_H
+
diff --git a/opengl/libagl/iterators.S b/opengl/libagl/iterators.S
new file mode 100644
index 0000000..daf2937
--- /dev/null
+++ b/opengl/libagl/iterators.S
@@ -0,0 +1,88 @@
+/* libs/opengles/iterators.S
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+
+    .text
+    .align
+    .arm
+    
+    .global iterators0032
+
+/*
+ * iterators0032
+ *
+ * MUST BE CALLED FROM ARM CODE
+ *
+ * r0: const compute_iterators_t* (this)
+ *      r0 + 0: m_dx01 
+ *      r0 + 4: m_dy10
+ *      r0 + 8: m_dx20
+ *      r0 +12: m_dy02
+ *      r0 +16: m_x0
+ *      r0 +20: m_y0
+ *      r0 +24: m_area
+ *		r0 +28: m_scale
+ *		r0 +29: m_area_scale;
+ * r1: int32_t* (out)
+ *      r1 + 0: c
+ *      r1 + 4: dcdx
+ *      r1 + 8: dcdy
+ *   r2: c0
+ *   r3: c1
+ * [sp]: c2
+ */
+ 
+iterators0032:
+        stmfd	sp!, {r4, r5, r6, r7, r8, lr}
+        ldr     r4, [sp, #4*6]
+
+        ldrb    r12, [r0, #29]
+        sub     r3, r3, r2
+        sub     r4, r4, r2
+        sub     r12, r12, #16
+        mov     r3, r3, asr r12
+        mov     r4, r4, asr r12
+        
+        ldr     r5, [r0, #0]
+        ldr     r12, [r0, #4]
+        smull   r8, lr, r4, r5
+        ldr     r5, [r0, #8]
+        smull   r6, r7, r4, r12
+        ldr     r12, [r0, #12]
+        smlal   r8, lr, r3, r5
+        smlal   r6, r7, r3, r12
+
+        ldr     r3, [r0, #16]        // m_x0
+        ldr     r4, [r0, #20]        // m_x1
+        
+        str     r6, [r1, #4]
+        str     r8, [r1, #8]
+
+        umull   r6, r5, r3, r6
+        umull   r8, r0, r4, r8
+        mla     r7, r3, r7, r5
+        mla     lr, r4, lr, r0
+        adds    r6, r6, r8
+        adc     r7, r7, lr
+
+        movs    r6, r6, lsr #4
+        adc     r6, r6, r7, lsl #28
+        rsb     r6, r6, r2, lsl #16
+        str     r6, [r1, #0]
+
+        ldmfd	sp!, {r4, r5, r6, r7, r8, pc}
+
diff --git a/opengl/libagl/light.cpp b/opengl/libagl/light.cpp
new file mode 100644
index 0000000..87725cb
--- /dev/null
+++ b/opengl/libagl/light.cpp
@@ -0,0 +1,852 @@
+/* libs/opengles/light.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 "context.h"
+#include "fp.h"
+#include "light.h"
+#include "state.h"
+#include "matrix.h"
+
+
+#if defined(__arm__) && defined(__thumb__)
+#warning "light.cpp should not be compiled in thumb on ARM."
+#endif
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static void invalidate_lighting(ogles_context_t* c);
+static void lightVertexValidate(ogles_context_t* c, vertex_t* v);
+static void lightVertexNop(ogles_context_t* c, vertex_t* v);
+static void lightVertex(ogles_context_t* c, vertex_t* v);
+static void lightVertexMaterial(ogles_context_t* c, vertex_t* v);
+
+static inline void vscale3(GLfixed* d, const GLfixed* m, GLfixed s);
+static inline void vsub3w(GLfixed* d, const GLfixed* a, const GLfixed* b);
+
+static __attribute__((noinline))
+void vnorm3(GLfixed* d, const GLfixed* a);
+
+static inline void vsa3(GLfixed* d,
+    const GLfixed* m, GLfixed s, const GLfixed* a);
+static inline void vmla3(GLfixed* d,
+    const GLfixed* m0, const GLfixed* m1, const GLfixed* a);
+static inline void vmul3(GLfixed* d,
+    const GLfixed* m0, const GLfixed* m1);
+
+static GLfixed fog_linear(ogles_context_t* c, GLfixed z);
+static GLfixed fog_exp(ogles_context_t* c, GLfixed z);
+static GLfixed fog_exp2(ogles_context_t* c, GLfixed z);
+
+
+// ----------------------------------------------------------------------------
+
+static void init_white(vec4_t& c) {
+    c.r = c.g = c.b = c.a = 0x10000;
+}
+
+void ogles_init_light(ogles_context_t* c)
+{
+    for (unsigned int i=0 ; i<OGLES_MAX_LIGHTS ; i++) {
+        c->lighting.lights[i].ambient.a = 0x10000;
+        c->lighting.lights[i].position.z = 0x10000;
+        c->lighting.lights[i].spotDir.z = -0x10000;
+        c->lighting.lights[i].spotCutoff = gglIntToFixed(180);
+        c->lighting.lights[i].attenuation[0] = 0x10000;
+    }
+    init_white(c->lighting.lights[0].diffuse);
+    init_white(c->lighting.lights[0].specular);
+
+    c->lighting.front.ambient.r =
+    c->lighting.front.ambient.g =
+    c->lighting.front.ambient.b = gglFloatToFixed(0.2f);
+    c->lighting.front.ambient.a = 0x10000;
+    c->lighting.front.diffuse.r =
+    c->lighting.front.diffuse.g =
+    c->lighting.front.diffuse.b = gglFloatToFixed(0.8f);
+    c->lighting.front.diffuse.a = 0x10000;
+    c->lighting.front.specular.a = 0x10000;
+    c->lighting.front.emission.a = 0x10000;
+
+    c->lighting.lightModel.ambient.r =
+    c->lighting.lightModel.ambient.g =
+    c->lighting.lightModel.ambient.b = gglFloatToFixed(0.2f);
+    c->lighting.lightModel.ambient.a = 0x10000;
+
+    c->lighting.colorMaterial.face = GL_FRONT_AND_BACK;
+    c->lighting.colorMaterial.mode = GL_AMBIENT_AND_DIFFUSE;
+
+    c->fog.mode = GL_EXP;
+    c->fog.fog = fog_exp;
+    c->fog.density = 0x10000;
+    c->fog.end = 0x10000;
+    c->fog.invEndMinusStart = 0x10000;
+
+    invalidate_lighting(c);
+       
+    c->rasterizer.procs.shadeModel(c, GL_SMOOTH);
+    c->lighting.shadeModel = GL_SMOOTH;
+}
+
+void ogles_uninit_light(ogles_context_t* c)
+{
+}
+
+static inline int32_t clampF(GLfixed f) CONST;
+int32_t clampF(GLfixed f) {
+    f = (f & ~(f>>31));
+    if (f >= 0x10000)
+        f = 0x10000;
+    return f;
+}
+
+static GLfixed fog_linear(ogles_context_t* c, GLfixed z) {
+    return clampF(gglMulx((c->fog.end - z), c->fog.invEndMinusStart));
+}
+
+static GLfixed fog_exp(ogles_context_t* c, GLfixed z) {
+    const float e = fixedToFloat(gglMulx(c->fog.density, z));
+    return clampF(gglFloatToFixed(fastexpf(-e)));
+}
+
+static GLfixed fog_exp2(ogles_context_t* c, GLfixed z) {
+    const float e = fixedToFloat(gglMulx(c->fog.density, z));
+    return clampF(gglFloatToFixed(fastexpf(-e*e)));
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark math helpers
+#endif
+
+static inline
+void vscale3(GLfixed* d, const GLfixed* m, GLfixed s) {
+    d[0] = gglMulx(m[0], s);
+    d[1] = gglMulx(m[1], s);
+    d[2] = gglMulx(m[2], s);
+}
+
+static inline
+void vsa3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) {
+    d[0] = gglMulAddx(m[0], s, a[0]);
+    d[1] = gglMulAddx(m[1], s, a[1]);
+    d[2] = gglMulAddx(m[2], s, a[2]);
+}
+
+static inline
+void vsub3w(GLfixed* d, const GLfixed* a, const GLfixed* b) {
+    const GLfixed wa = a[3];
+    const GLfixed wb = b[3];
+    if (ggl_likely(wa == wb)) {
+        d[0] = a[0] - b[0];
+        d[1] = a[1] - b[1];
+        d[2] = a[2] - b[2];
+    } else {
+        d[0] = gglMulSubx(a[0], wb, gglMulx(b[0], wa));
+        d[1] = gglMulSubx(a[1], wb, gglMulx(b[1], wa));
+        d[2] = gglMulSubx(a[2], wb, gglMulx(b[2], wa));
+    }
+}
+
+static inline
+void vmla3(GLfixed* d,
+        const GLfixed* m0, const GLfixed* m1, const GLfixed* a)
+{
+    d[0] = gglMulAddx(m0[0], m1[0], a[0]);
+    d[1] = gglMulAddx(m0[1], m1[1], a[1]);
+    d[2] = gglMulAddx(m0[2], m1[2], a[2]);
+}
+
+static inline
+void vmul3(GLfixed* d, const GLfixed* m0, const GLfixed* m1) {
+    d[0] = gglMulx(m0[0], m1[0]);
+    d[1] = gglMulx(m0[1], m1[1]);
+    d[2] = gglMulx(m0[2], m1[2]);
+}
+
+void vnorm3(GLfixed* d, const GLfixed* a)
+{
+    // we must take care of overflows when normalizing a vector
+    GLfixed n;
+    int32_t x = a[0];   x = x>=0 ? x : -x;
+    int32_t y = a[1];   y = y>=0 ? y : -y;
+    int32_t z = a[2];   z = z>=0 ? z : -z;
+    if (ggl_likely(x<=0x6800 && y<=0x6800 && z<= 0x6800)) {
+        // in this case this will all fit on 32 bits
+        n = x*x + y*y + z*z;
+        n = gglSqrtRecipx(n);
+        n <<= 8;
+    } else {
+        // here norm^2 is at least 0x7EC00000 (>>32 == 0.495117)
+        n = vsquare3(x, y, z);
+        n = gglSqrtRecipx(n);
+    }
+    vscale3(d, a, n);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark lighting equations
+#endif
+
+static inline void light_picker(ogles_context_t* c)
+{
+    if (ggl_likely(!c->lighting.enable)) {
+        c->lighting.lightVertex = lightVertexNop;
+        return;
+    }
+    if (c->lighting.colorMaterial.enable) {
+        c->lighting.lightVertex = lightVertexMaterial;
+    } else {
+        c->lighting.lightVertex = lightVertex;
+    }
+}
+
+static inline void validate_light_mvi(ogles_context_t* c)
+{
+    uint32_t en = c->lighting.enabledLights;
+    while (en) {
+        const int i = 31 - gglClz(en);
+        en &= ~(1<<i);
+        light_t& l = c->lighting.lights[i];
+        c->transforms.mvui.point3(&c->transforms.mvui,
+                &l.objPosition, &l.position);
+        vnorm3(l.normalizedObjPosition.v, l.objPosition.v);
+    }
+}
+
+static inline void validate_light(ogles_context_t* c)
+{
+    // if colorMaterial is enabled, we get the color from the vertex
+    if (!c->lighting.colorMaterial.enable) {
+        material_t& material = c->lighting.front;
+        uint32_t en = c->lighting.enabledLights;
+        while (en) {
+            const int i = 31 - gglClz(en);
+            en &= ~(1<<i);
+            light_t& l = c->lighting.lights[i];
+            vmul3(l.implicitAmbient.v,  material.ambient.v,  l.ambient.v);
+            vmul3(l.implicitDiffuse.v,  material.diffuse.v,  l.diffuse.v);
+            vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v);
+            
+            // this is just a flag to tell if we have a specular component
+            l.implicitSpecular.v[3] =
+                    l.implicitSpecular.r |
+                    l.implicitSpecular.g |
+                    l.implicitSpecular.b;
+            
+            l.rConstAttenuation = (l.attenuation[1] | l.attenuation[2])==0;
+            if (l.rConstAttenuation)
+                l.rConstAttenuation = gglRecipFast(l.attenuation[0]);
+        }
+        // emission and ambient for the whole scene
+        vmla3(  c->lighting.implicitSceneEmissionAndAmbient.v,
+                c->lighting.lightModel.ambient.v,
+                material.ambient.v, 
+                material.emission.v);
+        c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a;
+    }
+    validate_light_mvi(c);
+}
+
+void invalidate_lighting(ogles_context_t* c)
+{
+    // TODO: pick lightVertexValidate or lightVertexValidateMVI
+    // instead of systematically the heavier lightVertexValidate()
+    c->lighting.lightVertex = lightVertexValidate;
+}
+
+void ogles_invalidate_lighting_mvui(ogles_context_t* c)
+{
+    invalidate_lighting(c);
+}
+
+void lightVertexNop(ogles_context_t*, vertex_t* v)
+{
+    // we should never end-up here
+}
+
+void lightVertexValidateMVI(ogles_context_t* c, vertex_t* v)
+{
+    validate_light_mvi(c);
+    light_picker(c);
+    c->lighting.lightVertex(c, v);
+}
+
+void lightVertexValidate(ogles_context_t* c, vertex_t* v)
+{
+    validate_light(c);
+    light_picker(c);
+    c->lighting.lightVertex(c, v);
+}
+
+void lightVertexMaterial(ogles_context_t* c, vertex_t* v)
+{
+    // fetch the material color
+    const GLvoid* cp = c->arrays.color.element(
+            v->index & vertex_cache_t::INDEX_MASK);
+    c->arrays.color.fetch(c, v->color.v, cp);
+
+    // acquire the color-material from the vertex
+    material_t& material = c->lighting.front;
+    material.ambient =
+    material.diffuse = v->color;
+    // implicit arguments need to be computed per/vertex
+    uint32_t en = c->lighting.enabledLights;
+    while (en) {
+        const int i = 31 - gglClz(en);
+        en &= ~(1<<i);
+        light_t& l = c->lighting.lights[i];
+        vmul3(l.implicitAmbient.v,  material.ambient.v,  l.ambient.v);
+        vmul3(l.implicitDiffuse.v,  material.diffuse.v,  l.diffuse.v);
+        vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v);
+    }
+    // emission and ambient for the whole scene
+    vmla3(  c->lighting.implicitSceneEmissionAndAmbient.v,
+            c->lighting.lightModel.ambient.v,
+            material.ambient.v, 
+            material.emission.v);
+    c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a;
+
+    // now we can light our vertex as usual
+    lightVertex(c, v);
+}
+
+void lightVertex(ogles_context_t* c, vertex_t* v)
+{
+    // emission and ambient for the whole scene
+    vec4_t r = c->lighting.implicitSceneEmissionAndAmbient;
+
+    uint32_t en = c->lighting.enabledLights;
+    if (ggl_likely(en)) {
+        // since we do the lighting in object-space, we don't need to
+        // transform each normal. However, we might still have to normalize
+        // it if GL_NORMALIZE is enabled.
+        vec4_t n;
+        c->arrays.normal.fetch(c, n.v,
+            c->arrays.normal.element(v->index & vertex_cache_t::INDEX_MASK));
+        if (c->transforms.rescaleNormals == GL_NORMALIZE)
+            vnorm3(n.v, n.v);
+
+        const material_t& material = c->lighting.front;
+        const int twoSide = c->lighting.lightModel.twoSide;
+
+        while (en) {
+            const int i = 31 - gglClz(en);
+            en &= ~(1<<i);
+            const light_t& l = c->lighting.lights[i];
+            
+            vec4_t d, t;
+            GLfixed s;
+            GLfixed sqDist = 0x10000;
+
+            // compute vertex-to-light vector
+            if (ggl_unlikely(l.position.w)) {
+                vsub3w(d.v, l.objPosition.v, v->obj.v);
+                sqDist = dot3(d.v, d.v);
+                vscale3(d.v, d.v, gglSqrtRecipx(sqDist));
+            } else {
+                // TODO: avoid copy here
+                d = l.normalizedObjPosition;
+            }
+
+            // ambient & diffuse
+            s = dot3(n.v, d.v);
+            s = (s<0) ? (twoSide?(-s):0) : s;
+            vsa3(t.v, l.implicitDiffuse.v, s, l.implicitAmbient.v);
+            
+            // specular
+            if (ggl_unlikely(s && l.implicitSpecular.v[3])) {
+                vec4_t h;
+                h.x = d.x;
+                h.y = d.y;
+                h.z = d.z + 0x10000;
+                vnorm3(h.v, h.v);
+                s = dot3(n.v, h.v);
+                s = (s<0) ? (twoSide?(-s):0) : s;
+                if (s > 0) {
+                    s = gglPowx(s, material.shininess);
+                    vsa3(t.v, l.implicitSpecular.v, s, t.v);
+                }
+            }
+
+            // spot
+            if (ggl_unlikely(l.spotCutoff != gglIntToFixed(180))) {
+                GLfixed spotAtt = -dot3(l.normalizedSpotDir.v, d.v);
+                if (spotAtt >= l.spotCutoffCosine) {
+                    vscale3(t.v, t.v, gglPowx(spotAtt, l.spotExp));
+                }
+            }
+
+            // attenuation
+            if (ggl_unlikely(l.position.w)) {
+                if (l.rConstAttenuation) {
+                    s = l.rConstAttenuation;
+                } else {
+                    s = gglMulAddx(sqDist, l.attenuation[2], l.attenuation[0]);
+                    if (l.attenuation[1])
+                        s = gglMulAddx(gglSqrtx(sqDist), l.attenuation[1], s);
+                    s = gglRecipFast(s);
+                }
+                vscale3(t.v, t.v, s);
+            }
+
+            r.r += t.r;
+            r.g += t.g;
+            r.b += t.b;
+        }
+    }
+    v->color.r = gglClampx(r.r);
+    v->color.g = gglClampx(r.g);
+    v->color.b = gglClampx(r.b);
+    v->color.a = gglClampx(r.a);
+    v->flags |= vertex_t::LIT;
+}
+
+static void lightModelx(GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    if (ggl_unlikely(pname != GL_LIGHT_MODEL_TWO_SIDE)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->lighting.lightModel.twoSide = param ? GL_TRUE : GL_FALSE;
+    invalidate_lighting(c);
+}
+
+static void lightx(GLenum i, GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    light_t& light = c->lighting.lights[i-GL_LIGHT0];
+    const GLfixed kDegToRad = GLfixed((M_PI * gglIntToFixed(1)) / 180.0f);
+    switch (pname) {
+    case GL_SPOT_EXPONENT:
+        if (GGLfixed(param) >= gglIntToFixed(128)) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.spotExp = param;
+        break;
+    case GL_SPOT_CUTOFF:
+        if (param!=gglIntToFixed(180) && GGLfixed(param)>=gglIntToFixed(90)) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.spotCutoff = param;
+        light.spotCutoffCosine = 
+                gglFloatToFixed(cosinef((M_PI/(180.0f*65536.0f))*param));
+        break;
+    case GL_CONSTANT_ATTENUATION:
+        if (param < 0) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.attenuation[0] = param;
+        break;
+    case GL_LINEAR_ATTENUATION:
+        if (param < 0) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.attenuation[1] = param;
+        break;
+    case GL_QUADRATIC_ATTENUATION:
+        if (param < 0) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.attenuation[2] = param;
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    invalidate_lighting(c);
+}
+
+static void lightxv(GLenum i, GLenum pname, const GLfixed *params, ogles_context_t* c)
+{
+    if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    GLfixed* what;
+    light_t& light = c->lighting.lights[i-GL_LIGHT0];
+    switch (pname) {
+    case GL_AMBIENT:
+        what = light.ambient.v;
+        break;
+    case GL_DIFFUSE:
+        what = light.diffuse.v;
+        break;
+    case GL_SPECULAR:
+        what = light.specular.v;
+        break;
+    case GL_POSITION: {
+        ogles_validate_transform(c, transform_state_t::MODELVIEW);
+        transform_t& mv = c->transforms.modelview.transform;
+        memcpy(light.position.v, params, sizeof(light.position.v));
+        mv.point4(&mv, &light.position, &light.position);
+        invalidate_lighting(c);
+        return;
+    }
+    case GL_SPOT_DIRECTION: {
+        ogles_validate_transform(c, transform_state_t::MVUI);
+        transform_t& mvui = c->transforms.mvui;
+        mvui.point3(&mvui, &light.spotDir, (vec4_t*)params);
+        vnorm3(light.normalizedSpotDir.v, light.spotDir.v);
+        invalidate_lighting(c);
+        return;
+    }
+    default:
+        lightx(i, pname, params[0], c);
+        return;
+    }
+    what[0] = params[0];
+    what[1] = params[1];
+    what[2] = params[2];
+    what[3] = params[3];
+    invalidate_lighting(c);
+}
+
+static void materialx(GLenum face, GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    if (ggl_unlikely(face != GL_FRONT_AND_BACK)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (ggl_unlikely(pname != GL_SHININESS)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->lighting.front.shininess = param;
+    invalidate_lighting(c);
+}
+
+static void fogx(GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    switch (pname) {
+    case GL_FOG_DENSITY:
+        if (param >= 0) {
+            c->fog.density = param;
+            break;
+        }
+        ogles_error(c, GL_INVALID_VALUE);
+        break;
+    case GL_FOG_START:
+        c->fog.start = gglClampx(param);
+        c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start);
+        break;
+    case GL_FOG_END:
+        c->fog.end = gglClampx(param);
+        c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start);
+        break;
+    case GL_FOG_MODE:
+        switch (param) {
+        case GL_LINEAR:
+            c->fog.mode = param;
+            c->fog.fog = fog_linear;
+            break;
+        case GL_EXP:
+            c->fog.mode = param;
+            c->fog.fog = fog_exp;
+            break;
+        case GL_EXP2:
+            c->fog.mode = param;
+            c->fog.fog = fog_exp2;
+            break;
+        default:
+            ogles_error(c, GL_INVALID_ENUM);
+            break;
+        }
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        break;
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+#if 0
+#pragma mark -
+#pragma mark lighting APIs
+#endif
+
+void glShadeModel(GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (ggl_unlikely(mode != GL_SMOOTH && mode != GL_FLAT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->lighting.shadeModel = mode;
+}
+
+void glLightModelf(GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightModelx(pname, gglFloatToFixed(param), c);
+}
+
+void glLightModelx(GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightModelx(pname, param, c);
+}
+
+void glLightModelfv(GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname == GL_LIGHT_MODEL_TWO_SIDE) {
+        lightModelx(pname, gglFloatToFixed(params[0]), c);
+        return;
+    }
+
+    if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    c->lighting.lightModel.ambient.r = gglFloatToFixed(params[0]);
+    c->lighting.lightModel.ambient.g = gglFloatToFixed(params[1]);
+    c->lighting.lightModel.ambient.b = gglFloatToFixed(params[2]);
+    c->lighting.lightModel.ambient.a = gglFloatToFixed(params[3]);
+    invalidate_lighting(c);
+}
+
+void glLightModelxv(GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname == GL_LIGHT_MODEL_TWO_SIDE) {
+        lightModelx(pname, params[0], c);
+        return;
+    }
+
+    if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    c->lighting.lightModel.ambient.r = params[0];
+    c->lighting.lightModel.ambient.g = params[1];
+    c->lighting.lightModel.ambient.b = params[2];
+    c->lighting.lightModel.ambient.a = params[3];
+    invalidate_lighting(c);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void glLightf(GLenum i, GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightx(i, pname, gglFloatToFixed(param), c);
+}
+
+void glLightx(GLenum i, GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightx(i, pname, param, c);
+}
+
+void glLightfv(GLenum i, GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (pname) {
+    case GL_SPOT_EXPONENT:
+    case GL_SPOT_CUTOFF:
+    case GL_CONSTANT_ATTENUATION:
+    case GL_LINEAR_ATTENUATION:
+    case GL_QUADRATIC_ATTENUATION:
+        lightx(i, pname, gglFloatToFixed(params[0]), c);
+        return;
+    }
+
+    GLfixed paramsx[4];
+    paramsx[0] = gglFloatToFixed(params[0]);
+    paramsx[1] = gglFloatToFixed(params[1]);
+    paramsx[2] = gglFloatToFixed(params[2]);
+    if (pname != GL_SPOT_DIRECTION)
+        paramsx[3] = gglFloatToFixed(params[3]);
+
+    lightxv(i, pname, paramsx, c);
+}
+
+void glLightxv(GLenum i, GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightxv(i, pname, params, c);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    materialx(face, pname, gglFloatToFixed(param), c);
+}
+
+void glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    materialx(face, pname, param, c);
+}
+
+void glMaterialfv(
+    GLenum face, GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (ggl_unlikely(face != GL_FRONT_AND_BACK)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    GLfixed* what=0;
+    GLfixed* other=0;
+    switch (pname) {
+    case GL_AMBIENT:    what = c->lighting.front.ambient.v; break;
+    case GL_DIFFUSE:    what = c->lighting.front.diffuse.v; break;
+    case GL_SPECULAR:   what = c->lighting.front.specular.v; break;
+    case GL_EMISSION:   what = c->lighting.front.emission.v; break;
+    case GL_AMBIENT_AND_DIFFUSE:
+        what  = c->lighting.front.ambient.v; break;
+        other = c->lighting.front.diffuse.v; break;
+        break;
+    case GL_SHININESS:
+        c->lighting.front.shininess = gglFloatToFixed(params[0]);
+        invalidate_lighting(c);
+        return;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    what[0] = gglFloatToFixed(params[0]);
+    what[1] = gglFloatToFixed(params[1]);
+    what[2] = gglFloatToFixed(params[2]);
+    what[3] = gglFloatToFixed(params[3]);
+    if (other) {
+        other[0] = what[0];
+        other[1] = what[1];
+        other[2] = what[2];
+        other[3] = what[3];
+    }
+    invalidate_lighting(c);
+}
+
+void glMaterialxv(
+    GLenum face, GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (ggl_unlikely(face != GL_FRONT_AND_BACK)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    GLfixed* what=0;
+    GLfixed* other=0;
+    switch (pname) {
+    case GL_AMBIENT:    what = c->lighting.front.ambient.v; break;
+    case GL_DIFFUSE:    what = c->lighting.front.diffuse.v; break;
+    case GL_SPECULAR:   what = c->lighting.front.specular.v; break;
+    case GL_EMISSION:   what = c->lighting.front.emission.v; break;
+    case GL_AMBIENT_AND_DIFFUSE:
+        what = c->lighting.front.ambient.v; break;
+        other= c->lighting.front.diffuse.v; break;
+        break;
+    case GL_SHININESS:
+        c->lighting.front.shininess = gglFloatToFixed(params[0]);
+        invalidate_lighting(c);
+        return;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    what[0] = params[0];
+    what[1] = params[1];
+    what[2] = params[2];
+    what[3] = params[3];
+    if (other) {
+        other[0] = what[0];
+        other[1] = what[1];
+        other[2] = what[2];
+        other[3] = what[3];
+    }
+    invalidate_lighting(c);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark fog
+#endif
+
+void glFogf(GLenum pname, GLfloat param) {
+    ogles_context_t* c = ogles_context_t::get();
+    GLfixed paramx = (GLfixed)param;
+    if (pname != GL_FOG_MODE)
+        paramx = gglFloatToFixed(param);
+    fogx(pname, paramx, c);
+}
+
+void glFogx(GLenum pname, GLfixed param) {
+    ogles_context_t* c = ogles_context_t::get();
+    fogx(pname, param, c);
+}
+
+void glFogfv(GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname != GL_FOG_COLOR) {
+        GLfixed paramx = (GLfixed)params[0];
+        if (pname != GL_FOG_MODE)
+            paramx = gglFloatToFixed(params[0]);
+        fogx(pname, paramx, c);
+        return;
+    }
+    GLfixed paramsx[4];
+    paramsx[0] = gglFloatToFixed(params[0]);
+    paramsx[1] = gglFloatToFixed(params[1]);
+    paramsx[2] = gglFloatToFixed(params[2]);
+    paramsx[3] = gglFloatToFixed(params[3]);
+    c->rasterizer.procs.fogColor3xv(c, paramsx);
+}
+
+void glFogxv(GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname != GL_FOG_COLOR) {
+        fogx(pname, params[0], c);
+        return;
+    }
+    c->rasterizer.procs.fogColor3xv(c, params);
+}
diff --git a/opengl/libagl/light.h b/opengl/libagl/light.h
new file mode 100644
index 0000000..6dae25f
--- /dev/null
+++ b/opengl/libagl/light.h
@@ -0,0 +1,38 @@
+/* libs/opengles/light.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_LIGHT_H
+#define ANDROID_OPENGLES_LIGHT_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+namespace android {
+
+namespace gl {
+struct ogles_context_t;
+};
+
+void ogles_init_light(ogles_context_t* c);
+void ogles_uninit_light(ogles_context_t* c);
+void ogles_invalidate_lighting_mvui(ogles_context_t* c);
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_LIGHT_H
+
diff --git a/opengl/libagl/matrix.cpp b/opengl/libagl/matrix.cpp
new file mode 100644
index 0000000..441da38
--- /dev/null
+++ b/opengl/libagl/matrix.cpp
@@ -0,0 +1,1144 @@
+/* libs/opengles/matrix.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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"
+
+#if defined(__arm__) && defined(__thumb__)
+#warning "matrix.cpp should not be compiled in thumb on ARM."
+#endif
+
+#define I(_i, _j) ((_j)+ 4*(_i))
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static const GLfloat gIdentityf[16] = { 1,0,0,0,
+                                        0,1,0,0,
+                                        0,0,1,0,
+                                        0,0,0,1 };
+
+static const matrixx_t gIdentityx = { 
+            {   0x10000,0,0,0,
+                0,0x10000,0,0,
+                0,0,0x10000,0,
+                0,0,0,0x10000
+            }
+        };
+
+static void point2__nop(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point3__nop(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point4__nop(transform_t const*, vec4_t* c, vec4_t const* o);
+static void normal__nop(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point2__generic(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point3__generic(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point4__generic(transform_t const*, vec4_t* c, vec4_t const* o);
+static void normal__generic(transform_t const*, vec4_t* c, vec4_t const* o);
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void ogles_init_matrix(ogles_context_t* c)
+{
+    c->transforms.modelview.init(OGLES_MODELVIEW_STACK_DEPTH);
+    c->transforms.projection.init(OGLES_PROJECTION_STACK_DEPTH);
+    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++)
+        c->transforms.texture[i].init(OGLES_TEXTURE_STACK_DEPTH);
+
+    c->transforms.current = &c->transforms.modelview;
+    c->transforms.matrixMode = GL_MODELVIEW;
+    c->transforms.dirty =   transform_state_t::VIEWPORT | 
+                            transform_state_t::MVUI |
+                            transform_state_t::MVIT |
+                            transform_state_t::MVP;
+    c->transforms.mvp.loadIdentity();
+    c->transforms.mvp4.loadIdentity();
+    c->transforms.mvit4.loadIdentity();
+    c->transforms.mvui.loadIdentity();
+    c->transforms.vpt.loadIdentity();
+    c->transforms.vpt.zNear = 0.0f;
+    c->transforms.vpt.zFar  = 1.0f;
+}
+
+void ogles_uninit_matrix(ogles_context_t* c)
+{
+    c->transforms.modelview.uninit();
+    c->transforms.projection.uninit();
+    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++)
+        c->transforms.texture[i].uninit();
+}
+
+static void validate_perspective(ogles_context_t* c, vertex_t* v)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+    c->arrays.perspective = (c->clipPlanes.enable) ?
+        ogles_vertex_clipAllPerspective3D : ogles_vertex_perspective3D;
+    if (enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) {
+        c->arrays.perspective = (c->clipPlanes.enable) ?
+            ogles_vertex_clipAllPerspective3DZ : ogles_vertex_perspective3DZ;
+    }
+    if ((c->arrays.vertex.size != 4) &&
+        (c->transforms.mvp4.flags & transform_t::FLAGS_2D_PROJECTION)) {
+        c->arrays.perspective = ogles_vertex_perspective2D;
+    }
+    c->arrays.perspective(c, v);
+}
+
+void ogles_invalidate_perspective(ogles_context_t* c)
+{
+    c->arrays.perspective = validate_perspective;
+}
+
+void ogles_validate_transform_impl(ogles_context_t* c, uint32_t want)
+{
+    int dirty = c->transforms.dirty & want;
+
+    // Validate the modelview
+    if (dirty & transform_state_t::MODELVIEW) {
+        c->transforms.modelview.validate();
+    }
+
+    // Validate the projection stack (in fact, it's never needed)
+    if (dirty & transform_state_t::PROJECTION) {
+        c->transforms.projection.validate();
+    }
+
+    // Validate the viewport transformation
+    if (dirty & transform_state_t::VIEWPORT) {
+        vp_transform_t& vpt = c->transforms.vpt;
+        vpt.transform.matrix.load(vpt.matrix);
+        vpt.transform.picker();
+    }
+
+    // We need to update the mvp (used to transform each vertex)
+    if (dirty & transform_state_t::MVP) {
+        c->transforms.update_mvp();
+        // invalidate perspective (divide by W) and view volume clipping
+        ogles_invalidate_perspective(c);
+    }
+
+    // Validate the mvui (for normal transformation)
+    if (dirty & transform_state_t::MVUI) {
+        c->transforms.update_mvui();
+        ogles_invalidate_lighting_mvui(c);
+    }
+
+    // Validate the texture stack
+    if (dirty & transform_state_t::TEXTURE) {
+        for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++)
+            c->transforms.texture[i].validate();
+    }
+
+    // Validate the mvit4 (user-clip planes)
+    if (dirty & transform_state_t::MVIT) {
+        c->transforms.update_mvit();
+    }
+
+    c->transforms.dirty &= ~want;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark transform_t
+#endif
+
+void transform_t::loadIdentity() {
+    matrix = gIdentityx;
+    flags = 0;
+    ops = OP_IDENTITY;
+    point2 = point2__nop;
+    point3 = point3__nop;
+    point4 = point4__nop;
+}
+
+
+static inline
+int notZero(GLfixed v) {
+    return abs(v) & ~0x3;
+}
+
+static inline
+int notOne(GLfixed v) {
+    return notZero(v - 0x10000);
+}
+
+void transform_t::picker()
+{
+    const GLfixed* const m = matrix.m;
+
+    // XXX: picker needs to be smarter
+    flags = 0;
+    ops = OP_ALL;
+    point2 = point2__generic;
+    point3 = point3__generic;
+    point4 = point4__generic;
+    
+    // find out if this is a 2D projection
+    if (!(notZero(m[3]) | notZero(m[7]) | notZero(m[11]) | notOne(m[15]))) {
+        flags |= FLAGS_2D_PROJECTION;
+    }
+}
+
+void mvui_transform_t::picker()
+{
+    flags = 0;
+    ops = OP_ALL;
+    point3 = normal__generic;
+}
+
+void transform_t::dump(const char* what)
+{
+    GLfixed const * const m = matrix.m;
+    LOGD("%s:", what);
+    for (int i=0 ; i<4 ; i++)
+        LOGD("[%08x %08x %08x %08x] [%f %f %f %f]\n",
+            m[I(0,i)], m[I(1,i)], m[I(2,i)], m[I(3,i)],
+            fixedToFloat(m[I(0,i)]),
+            fixedToFloat(m[I(1,i)]), 
+            fixedToFloat(m[I(2,i)]),
+            fixedToFloat(m[I(3,i)]));
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark matrixx_t
+#endif
+
+void matrixx_t::load(const matrixf_t& rhs) {
+    GLfixed* xp = m;
+    GLfloat const* fp = rhs.elements();
+    unsigned int i = 16;
+    do {
+        const GLfloat f = *fp++;
+        *xp++ = isZerof(f) ? 0 : gglFloatToFixed(f);
+    } while (--i);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark matrixf_t
+#endif
+
+void matrixf_t::multiply(matrixf_t& r, const matrixf_t& lhs, const matrixf_t& rhs)
+{
+    GLfloat const* const m = lhs.m;
+    for (int i=0 ; i<4 ; i++) {
+        register const float rhs_i0 = rhs.m[ I(i,0) ];
+        register float ri0 = m[ I(0,0) ] * rhs_i0;
+        register float ri1 = m[ I(0,1) ] * rhs_i0;
+        register float ri2 = m[ I(0,2) ] * rhs_i0;
+        register float ri3 = m[ I(0,3) ] * rhs_i0;
+        for (int j=1 ; j<4 ; j++) {
+            register const float rhs_ij = rhs.m[ I(i,j) ];
+            ri0 += m[ I(j,0) ] * rhs_ij;
+            ri1 += m[ I(j,1) ] * rhs_ij;
+            ri2 += m[ I(j,2) ] * rhs_ij;
+            ri3 += m[ I(j,3) ] * rhs_ij;
+        }
+        r.m[ I(i,0) ] = ri0;
+        r.m[ I(i,1) ] = ri1;
+        r.m[ I(i,2) ] = ri2;
+        r.m[ I(i,3) ] = ri3;
+    }
+}
+
+void matrixf_t::dump(const char* what) {
+    LOGD("%s", what);
+    LOGD("[ %9f %9f %9f %9f ]", m[I(0,0)], m[I(1,0)], m[I(2,0)], m[I(3,0)]);
+    LOGD("[ %9f %9f %9f %9f ]", m[I(0,1)], m[I(1,1)], m[I(2,1)], m[I(3,1)]);
+    LOGD("[ %9f %9f %9f %9f ]", m[I(0,2)], m[I(1,2)], m[I(2,2)], m[I(3,2)]);
+    LOGD("[ %9f %9f %9f %9f ]", m[I(0,3)], m[I(1,3)], m[I(2,3)], m[I(3,3)]);
+}
+
+void matrixf_t::loadIdentity() {
+    memcpy(m, gIdentityf, sizeof(m));
+}
+
+void matrixf_t::set(const GLfixed* rhs) {
+    load(rhs);
+}
+
+void matrixf_t::set(const GLfloat* rhs) {
+    load(rhs);
+}
+
+void matrixf_t::load(const GLfixed* rhs) {
+    GLfloat* fp = m;
+    unsigned int i = 16;
+    do {
+        *fp++ = fixedToFloat(*rhs++);
+    } while (--i);
+}
+
+void matrixf_t::load(const GLfloat* rhs) {
+    memcpy(m, rhs, sizeof(m));
+}
+
+void matrixf_t::load(const matrixf_t& rhs) {
+    operator = (rhs);
+}
+
+void matrixf_t::multiply(const matrixf_t& rhs) {
+    matrixf_t r;
+    multiply(r, *this, rhs);
+    operator = (r);
+}
+
+void matrixf_t::translate(GLfloat x, GLfloat y, GLfloat z) {
+    for (int i=0 ; i<4 ; i++) {
+        m[12+i] += m[i]*x + m[4+i]*y + m[8+i]*z;
+    }
+}
+
+void matrixf_t::scale(GLfloat x, GLfloat y, GLfloat z) {
+    for (int i=0 ; i<4 ; i++) {
+        m[  i] *= x;
+        m[4+i] *= y;
+        m[8+i] *= z;
+    }
+}
+
+void matrixf_t::rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z)
+{
+    matrixf_t rotation;
+    GLfloat* r = rotation.m;
+    GLfloat c, s;
+    r[3] = 0;   r[7] = 0;   r[11]= 0;
+    r[12]= 0;   r[13]= 0;   r[14]= 0;   r[15]= 1;
+    a *= GLfloat(M_PI / 180.0f);
+    sincosf(a, &s, &c);
+    if (isOnef(x) && isZerof(y) && isZerof(z)) {
+        r[5] = c;   r[10]= c;
+        r[6] = s;   r[9] = -s;
+        r[1] = 0;   r[2] = 0;
+        r[4] = 0;   r[8] = 0;
+        r[0] = 1;
+    } else if (isZerof(x) && isOnef(y) && isZerof(z)) {
+        r[0] = c;   r[10]= c;
+        r[8] = s;   r[2] = -s;
+        r[1] = 0;   r[4] = 0;
+        r[6] = 0;   r[9] = 0;
+        r[5] = 1;
+    } else if (isZerof(x) && isZerof(y) && isOnef(z)) {
+        r[0] = c;   r[5] = c;
+        r[1] = s;   r[4] = -s;
+        r[2] = 0;   r[6] = 0;
+        r[8] = 0;   r[9] = 0;
+        r[10]= 1;
+    } else {
+        const GLfloat len = sqrtf(x*x + y*y + z*z);
+        if (!isOnef(len)) {
+            const GLfloat recipLen = reciprocalf(len);
+            x *= recipLen;
+            y *= recipLen;
+            z *= recipLen;
+        }
+        const GLfloat nc = 1.0f - c;
+        const GLfloat xy = x * y;
+        const GLfloat yz = y * z;
+        const GLfloat zx = z * x;
+        const GLfloat xs = x * s;
+        const GLfloat ys = y * s;
+        const GLfloat zs = z * s;		
+        r[ 0] = x*x*nc +  c;    r[ 4] =  xy*nc - zs;    r[ 8] =  zx*nc + ys;
+        r[ 1] =  xy*nc + zs;    r[ 5] = y*y*nc +  c;    r[ 9] =  yz*nc - xs;
+        r[ 2] =  zx*nc - ys;    r[ 6] =  yz*nc + xs;    r[10] = z*z*nc +  c;
+    }
+    multiply(rotation);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark matrix_stack_t
+#endif
+
+void matrix_stack_t::init(int depth) {
+    stack = new matrixf_t[depth];
+    ops = new uint8_t[depth];
+    maxDepth = depth;
+    depth = 0;
+    dirty = 0;
+    loadIdentity();
+}
+
+void matrix_stack_t::uninit() {
+    delete [] stack;
+    delete [] ops;
+}
+
+void matrix_stack_t::loadIdentity() {
+    transform.loadIdentity();
+    stack[depth].loadIdentity();
+    ops[depth] = OP_IDENTITY;
+}
+
+void matrix_stack_t::load(const GLfixed* rhs)
+{   
+    memcpy(transform.matrix.m, rhs, sizeof(transform.matrix.m));
+    stack[depth].load(rhs);
+    ops[depth] = OP_ALL;    // TODO: we should look at the matrix
+}
+
+void matrix_stack_t::load(const GLfloat* rhs)
+{
+    stack[depth].load(rhs);
+    ops[depth] = OP_ALL;    // TODO: we should look at the matrix
+}
+
+void matrix_stack_t::multiply(const matrixf_t& rhs)
+{    
+    stack[depth].multiply(rhs);
+    ops[depth] = OP_ALL;    // TODO: we should look at the matrix
+}
+
+void matrix_stack_t::translate(GLfloat x, GLfloat y, GLfloat z)
+{
+    stack[depth].translate(x,y,z);
+    ops[depth] |= OP_TRANSLATE;
+}
+
+void matrix_stack_t::scale(GLfloat x, GLfloat y, GLfloat z)
+{
+    stack[depth].scale(x,y,z);
+    if (x==y && y==z) {
+        ops[depth] |= OP_UNIFORM_SCALE;
+    } else {
+        ops[depth] |= OP_SCALE;
+    }
+}
+
+void matrix_stack_t::rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z)
+{
+    stack[depth].rotate(a,x,y,z);
+    ops[depth] |= OP_ROTATE;
+}
+
+void matrix_stack_t::validate()
+{
+    if (dirty & DO_FLOAT_TO_FIXED) {
+        transform.matrix.load(top());
+    }
+    if (dirty & DO_PICKER) {
+        transform.picker();
+    }
+    dirty = 0;
+}
+
+GLint matrix_stack_t::push()
+{
+    if (depth >= (maxDepth-1)) {
+        return GL_STACK_OVERFLOW;
+    }
+    stack[depth+1] = stack[depth];
+    ops[depth+1] = ops[depth];
+    depth++;
+    return 0;
+}
+
+GLint matrix_stack_t::pop()
+{
+    if (depth == 0) {
+        return GL_STACK_UNDERFLOW;
+    }
+    depth--;
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark vp_transform_t
+#endif
+
+void vp_transform_t::loadIdentity() {
+    transform.loadIdentity();
+    matrix.loadIdentity();
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark transform_state_t
+#endif
+
+void transform_state_t::invalidate()
+{
+    switch (matrixMode) {
+    case GL_MODELVIEW:  dirty |= MODELVIEW  | MVP | MVUI | MVIT;    break;
+    case GL_PROJECTION: dirty |= PROJECTION | MVP;                  break;
+    case GL_TEXTURE:    dirty |= TEXTURE    | MVP;                  break;
+    }
+    current->dirty =    matrix_stack_t::DO_PICKER |
+                        matrix_stack_t::DO_FLOAT_TO_FIXED;
+}
+
+void transform_state_t::update_mvp()
+{
+    matrixf_t temp_mvp;
+    matrixf_t::multiply(temp_mvp, projection.top(), modelview.top());
+    mvp4.matrix.load(temp_mvp);
+    mvp4.picker();
+
+    if (mvp4.flags & transform_t::FLAGS_2D_PROJECTION) {
+        // the mvp matrix doesn't transform W, in this case we can
+        // premultiply it with the viewport transformation. In addition to
+        // being more efficient, this is also much more accurate and in fact
+        // is needed for 2D drawing with a resulting 1:1 mapping.
+        matrixf_t mvpv;
+        matrixf_t::multiply(mvpv, vpt.matrix, temp_mvp);
+        mvp.matrix.load(mvpv);
+        mvp.picker();
+    } else {
+        mvp = mvp4;
+    }
+}
+
+static inline 
+GLfloat det22(GLfloat a, GLfloat b, GLfloat c, GLfloat d) {
+    return a*d - b*c;
+}
+
+static inline
+GLfloat ndet22(GLfloat a, GLfloat b, GLfloat c, GLfloat d) {
+    return b*c - a*d;
+}
+
+static __attribute__((noinline))
+void invert(GLfloat* inverse, const GLfloat* src)
+{
+    double t;
+    int i, j, k, swap;
+    GLfloat tmp[4][4];
+    
+    memcpy(inverse, gIdentityf, sizeof(gIdentityf));
+    memcpy(tmp, src, sizeof(GLfloat)*16);
+    
+    for (i = 0; i < 4; i++) {
+        // look for largest element in column
+        swap = i;
+        for (j = i + 1; j < 4; j++) {
+            if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {
+                swap = j;
+            }
+        }
+        
+        if (swap != i) {
+            /* swap rows. */
+            for (k = 0; k < 4; k++) {
+                t = tmp[i][k];
+                tmp[i][k] = tmp[swap][k];
+                tmp[swap][k] = t;
+                
+                t = inverse[i*4+k];
+                inverse[i*4+k] = inverse[swap*4+k];
+                inverse[swap*4+k] = t;
+            }
+        }
+        
+        t = 1.0f / tmp[i][i];
+        for (k = 0; k < 4; k++) {
+            tmp[i][k] *= t;
+            inverse[i*4+k] *= t;
+        }
+        for (j = 0; j < 4; j++) {
+            if (j != i) {
+                t = tmp[j][i];
+                for (k = 0; k < 4; k++) {
+                    tmp[j][k] -= tmp[i][k]*t;
+                    inverse[j*4+k] -= inverse[i*4+k]*t;
+                }
+            }
+        }
+    }
+}
+
+void transform_state_t::update_mvit()
+{
+    GLfloat r[16];
+    const GLfloat* const mv = modelview.top().elements();
+    invert(r, mv);
+    // convert to fixed-point and transpose
+    GLfixed* const x = mvit4.matrix.m;
+    for (int i=0 ; i<4 ; i++)
+        for (int j=0 ; j<4 ; j++)
+            x[I(i,j)] = gglFloatToFixed(r[I(j,i)]);
+    mvit4.picker();
+}
+
+void transform_state_t::update_mvui()
+{
+    const GLfloat* const mv = modelview.top().elements();
+
+    /*
+    When transforming normals, we can use the upper 3x3 matrix, see:
+    http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node26.html
+    */
+    
+    // Also note that:
+    //      l(obj) =  tr(M).l(eye) for infinite light
+    //      l(obj) = inv(M).l(eye) for local light
+
+    const uint32_t ops = modelview.top_ops() & ~OP_TRANSLATE;
+    if (ggl_likely((!(ops & ~OP_ROTATE)) ||
+        (rescaleNormals && modelview.isRigidBody()))) {
+        // if the modelview matrix is a rigid body transformation
+        // (translation, rotation, uniform scaling), then we can bypass
+        // the inverse by transposing the matrix.
+        GLfloat rescale = 1.0f;
+        if (rescaleNormals == GL_RESCALE_NORMAL) {
+            if (!(ops & ~OP_UNIFORM_SCALE)) {
+                rescale = reciprocalf(mv[I(0,0)]);
+            } else {
+                rescale = rsqrtf(
+                        sqrf(mv[I(2,0)]) + sqrf(mv[I(2,1)]) + sqrf(mv[I(2,2)]));
+            }
+        }
+        GLfixed* const x = mvui.matrix.m;
+        for (int i=0 ; i<3 ; i++) {
+            x[I(i,0)] = gglFloatToFixed(mv[I(0,i)] * rescale);
+            x[I(i,1)] = gglFloatToFixed(mv[I(1,i)] * rescale);
+            x[I(i,2)] = gglFloatToFixed(mv[I(2,i)] * rescale);
+        }
+        mvui.picker();
+        return;
+    }
+
+    GLfloat r[3][3];
+    r[0][0] = det22(mv[I(1,1)], mv[I(2,1)], mv[I(1,2)], mv[I(2,2)]);
+    r[0][1] =ndet22(mv[I(0,1)], mv[I(2,1)], mv[I(0,2)], mv[I(2,2)]);
+    r[0][2] = det22(mv[I(0,1)], mv[I(1,1)], mv[I(0,2)], mv[I(1,2)]);
+    r[1][0] =ndet22(mv[I(1,0)], mv[I(2,0)], mv[I(1,2)], mv[I(2,2)]);
+    r[1][1] = det22(mv[I(0,0)], mv[I(2,0)], mv[I(0,2)], mv[I(2,2)]);
+    r[1][2] =ndet22(mv[I(0,0)], mv[I(1,0)], mv[I(0,2)], mv[I(1,2)]);
+    r[2][0] = det22(mv[I(1,0)], mv[I(2,0)], mv[I(1,1)], mv[I(2,1)]);
+    r[2][1] =ndet22(mv[I(0,0)], mv[I(2,0)], mv[I(0,1)], mv[I(2,1)]);
+    r[2][2] = det22(mv[I(0,0)], mv[I(1,0)], mv[I(0,1)], mv[I(1,1)]);        
+
+    GLfloat rdet;
+    if (rescaleNormals == GL_RESCALE_NORMAL) {
+        rdet = rsqrtf(sqrf(r[0][2]) + sqrf(r[1][2]) + sqrf(r[2][2]));
+    } else {
+        rdet = reciprocalf( 
+            r[0][0]*mv[I(0,0)] + r[0][1]*mv[I(1,0)] + r[0][2]*mv[I(2,0)]);
+    }
+
+    GLfixed* const x = mvui.matrix.m;
+    for (int i=0 ; i<3 ; i++) {
+        x[I(i,0)] = gglFloatToFixed(r[i][0] * rdet);
+        x[I(i,1)] = gglFloatToFixed(r[i][1] * rdet);
+        x[I(i,2)] = gglFloatToFixed(r[i][2] * rdet);
+    }
+    mvui.picker();
+}
+
+
+// ----------------------------------------------------------------------------
+// transformation and matrices API
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark transformation and matrices API
+#endif
+
+int ogles_surfaceport(ogles_context_t* c, GLint x, GLint y)
+{
+    c->viewport.surfaceport.x = x;
+    c->viewport.surfaceport.y = y;
+
+    ogles_viewport(c, 
+            c->viewport.x,
+            c->viewport.y,
+            c->viewport.w,
+            c->viewport.h);
+
+    ogles_scissor(c,
+            c->viewport.scissor.x,
+            c->viewport.scissor.y,
+            c->viewport.scissor.w,
+            c->viewport.scissor.h);
+
+    return 0;
+}
+
+void ogles_scissor(ogles_context_t* c, 
+        GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    if ((w|h) < 0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    c->viewport.scissor.x = x;
+    c->viewport.scissor.y = y;
+    c->viewport.scissor.w = w;
+    c->viewport.scissor.h = h;
+    
+    x += c->viewport.surfaceport.x;
+    y += c->viewport.surfaceport.y;
+
+    y = c->rasterizer.state.buffers.color.height - (y + h);
+    c->rasterizer.procs.scissor(c, x, y, w, h);
+}
+
+void ogles_viewport(ogles_context_t* c,
+        GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    if ((w|h)<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    c->viewport.x = x;
+    c->viewport.y = y;
+    c->viewport.w = w;
+    c->viewport.h = h;
+
+    x += c->viewport.surfaceport.x;
+    y += c->viewport.surfaceport.y;
+
+    GLint H = c->rasterizer.state.buffers.color.height;
+    GLfloat sx = div2f(w);
+    GLfloat ox = sx + x;
+    GLfloat sy = div2f(h);
+    GLfloat oy = sy - y + (H - h);
+
+    GLfloat near = c->transforms.vpt.zNear;
+    GLfloat far  = c->transforms.vpt.zFar;
+    GLfloat A = div2f(far - near);
+    GLfloat B = div2f(far + near);
+
+    // compute viewport matrix
+    GLfloat* const f = c->transforms.vpt.matrix.editElements();
+    f[0] = sx;  f[4] = 0;   f[ 8] = 0;  f[12] = ox;
+    f[1] = 0;   f[5] =-sy;  f[ 9] = 0;  f[13] = oy;
+    f[2] = 0;   f[6] = 0;   f[10] = A;  f[14] = B;
+    f[3] = 0;   f[7] = 0;   f[11] = 0;  f[15] = 1;
+    c->transforms.dirty |= transform_state_t::VIEWPORT;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark matrix * vertex
+#endif
+
+void point2__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
+    const GLfixed* const m = mx->matrix.m;
+    const GLfixed rx = rhs->x;
+    const GLfixed ry = rhs->y;
+    lhs->x = mla2a(rx, m[ 0], ry, m[ 4], m[12]); 
+    lhs->y = mla2a(rx, m[ 1], ry, m[ 5], m[13]);
+    lhs->z = mla2a(rx, m[ 2], ry, m[ 6], m[14]);
+    lhs->w = mla2a(rx, m[ 3], ry, m[ 7], m[15]);
+}
+
+void point3__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
+    const GLfixed* const m = mx->matrix.m;
+    const GLfixed rx = rhs->x;
+    const GLfixed ry = rhs->y;
+    const GLfixed rz = rhs->z;
+    lhs->x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); 
+    lhs->y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]);
+    lhs->z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]);
+    lhs->w = mla3a(rx, m[ 3], ry, m[ 7], rz, m[11], m[15]);
+}
+
+void point4__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
+    const GLfixed* const m = mx->matrix.m;
+    const GLfixed rx = rhs->x;
+    const GLfixed ry = rhs->y;
+    const GLfixed rz = rhs->z;
+    const GLfixed rw = rhs->w;
+    lhs->x = mla4(rx, m[ 0], ry, m[ 4], rz, m[ 8], rw, m[12]); 
+    lhs->y = mla4(rx, m[ 1], ry, m[ 5], rz, m[ 9], rw, m[13]);
+    lhs->z = mla4(rx, m[ 2], ry, m[ 6], rz, m[10], rw, m[14]);
+    lhs->w = mla4(rx, m[ 3], ry, m[ 7], rz, m[11], rw, m[15]);
+}
+
+void normal__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
+    const GLfixed* const m = mx->matrix.m;
+    const GLfixed rx = rhs->x;
+    const GLfixed ry = rhs->y;
+    const GLfixed rz = rhs->z;
+    lhs->x = mla3(rx, m[ 0], ry, m[ 4], rz, m[ 8]); 
+    lhs->y = mla3(rx, m[ 1], ry, m[ 5], rz, m[ 9]);
+    lhs->z = mla3(rx, m[ 2], ry, m[ 6], rz, m[10]);
+}
+
+
+void point2__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
+    lhs->z = 0;
+    lhs->w = 0x10000;
+    if (lhs != rhs) {
+        lhs->x = rhs->x;
+        lhs->y = rhs->y;
+    }
+}
+
+void point3__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
+    lhs->w = 0x10000;
+    if (lhs != rhs) {
+        lhs->x = rhs->x;
+        lhs->y = rhs->y;
+        lhs->z = rhs->z;
+    }
+}
+
+void point4__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
+    if (lhs != rhs)
+        *lhs = *rhs;
+}
+
+
+static void frustumf(
+            GLfloat left, GLfloat right, 
+            GLfloat bottom, GLfloat top,
+            GLfloat zNear, GLfloat zFar,
+            ogles_context_t* c)
+    {
+    if (cmpf(left,right) ||
+        cmpf(top, bottom) ||
+        cmpf(zNear, zFar) ||
+        isZeroOrNegativef(zNear) ||
+        isZeroOrNegativef(zFar))
+    {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    const GLfloat r_width  = reciprocalf(right - left);
+    const GLfloat r_height = reciprocalf(top - bottom);
+    const GLfloat r_depth  = reciprocalf(zNear - zFar);
+    const GLfloat x = mul2f(zNear * r_width);
+    const GLfloat y = mul2f(zNear * r_height);
+    const GLfloat A = mul2f((right + left) * r_width);
+    const GLfloat B = (top + bottom) * r_height;
+    const GLfloat C = (zFar + zNear) * r_depth;
+    const GLfloat D = mul2f(zFar * zNear * r_depth);
+    GLfloat f[16];
+    f[ 0] = x;
+    f[ 5] = y;
+    f[ 8] = A;
+    f[ 9] = B;
+    f[10] = C;
+    f[14] = D;
+    f[11] = -1.0f;
+    f[ 1] = f[ 2] = f[ 3] =
+    f[ 4] = f[ 6] = f[ 7] =
+    f[12] = f[13] = f[15] = 0.0f;
+
+    matrixf_t rhs;
+    rhs.set(f);
+    c->transforms.current->multiply(rhs);
+    c->transforms.invalidate();
+}
+
+static void orthof( 
+        GLfloat left, GLfloat right, 
+        GLfloat bottom, GLfloat top,
+        GLfloat zNear, GLfloat zFar,
+        ogles_context_t* c)
+{
+    if (cmpf(left,right) ||
+        cmpf(top, bottom) ||
+        cmpf(zNear, zFar))
+    {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    const GLfloat r_width  = reciprocalf(right - left);
+    const GLfloat r_height = reciprocalf(top - bottom);
+    const GLfloat r_depth  = reciprocalf(zFar - zNear);
+    const GLfloat x =  mul2f(r_width);
+    const GLfloat y =  mul2f(r_height);
+    const GLfloat z = -mul2f(r_depth);
+    const GLfloat tx = -(right + left) * r_width;
+    const GLfloat ty = -(top + bottom) * r_height;
+    const GLfloat tz = -(zFar + zNear) * r_depth;
+    GLfloat f[16];
+    f[ 0] = x;
+    f[ 5] = y;
+    f[10] = z;
+    f[12] = tx;
+    f[13] = ty;
+    f[14] = tz;
+    f[15] = 1.0f;
+    f[ 1] = f[ 2] = f[ 3] =
+    f[ 4] = f[ 6] = f[ 7] =
+    f[ 8] = f[ 9] = f[11] = 0.0f;
+    matrixf_t rhs;
+    rhs.set(f);
+    c->transforms.current->multiply(rhs);
+    c->transforms.invalidate();
+}
+
+static void depthRangef(GLclampf zNear, GLclampf zFar, ogles_context_t* c)
+{
+    zNear = clampToZerof(zNear > 1 ? 1 : zNear);
+    zFar  = clampToZerof(zFar  > 1 ? 1 : zFar);
+    GLfloat* const f = c->transforms.vpt.matrix.editElements();
+    f[10] = div2f(zFar - zNear);
+    f[14] = div2f(zFar + zNear);
+    c->transforms.dirty |= transform_state_t::VIEWPORT;
+    c->transforms.vpt.zNear = zNear;
+    c->transforms.vpt.zFar  = zFar;
+}
+
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+using namespace android;
+
+void glMatrixMode(GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    matrix_stack_t* stack = 0;
+    switch (mode) {
+    case GL_MODELVIEW:
+        stack = &c->transforms.modelview;
+        break;
+    case GL_PROJECTION:
+        stack = &c->transforms.projection;
+        break;
+    case GL_TEXTURE:
+        stack = &c->transforms.texture[c->textures.active];
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->transforms.matrixMode = mode;
+    c->transforms.current = stack;
+}
+
+void glLoadIdentity()
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->loadIdentity(); // also loads the GLfixed transform
+    c->transforms.invalidate();
+    c->transforms.current->dirty = 0;
+}
+
+void glLoadMatrixf(const GLfloat* m)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->load(m);
+    c->transforms.invalidate();
+}
+
+void glLoadMatrixx(const GLfixed* m)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->load(m); // also loads the GLfixed transform
+    c->transforms.invalidate();
+    c->transforms.current->dirty &= ~matrix_stack_t::DO_FLOAT_TO_FIXED;
+}
+
+void glMultMatrixf(const GLfloat* m)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    matrixf_t rhs;
+    rhs.set(m);
+    c->transforms.current->multiply(rhs);
+    c->transforms.invalidate();
+}
+
+void glMultMatrixx(const GLfixed* m)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    matrixf_t rhs;
+    rhs.set(m);
+    c->transforms.current->multiply(rhs);
+    c->transforms.invalidate();
+}
+
+void glPopMatrix()
+{
+    ogles_context_t* c = ogles_context_t::get();
+    GLint err = c->transforms.current->pop();
+    if (ggl_unlikely(err)) {
+        ogles_error(c, err);
+        return;
+    }
+    c->transforms.invalidate();
+}
+
+void glPushMatrix()
+{
+    ogles_context_t* c = ogles_context_t::get();
+    GLint err = c->transforms.current->push();
+    if (ggl_unlikely(err)) {
+        ogles_error(c, err);
+        return;
+    }
+    c->transforms.invalidate();
+}
+
+void glFrustumf(
+        GLfloat left, GLfloat right, 
+        GLfloat bottom, GLfloat top,
+        GLfloat zNear, GLfloat zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    frustumf(left, right, bottom, top, zNear, zFar, c);
+}
+
+void glFrustumx( 
+        GLfixed left, GLfixed right,
+        GLfixed bottom, GLfixed top,
+        GLfixed zNear, GLfixed zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    frustumf( fixedToFloat(left), fixedToFloat(right),
+              fixedToFloat(bottom), fixedToFloat(top),
+              fixedToFloat(zNear), fixedToFloat(zFar),
+              c);
+}
+
+void glOrthof( 
+        GLfloat left, GLfloat right, 
+        GLfloat bottom, GLfloat top,
+        GLfloat zNear, GLfloat zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    orthof(left, right, bottom, top, zNear, zFar, c);
+}
+
+void glOrthox(
+        GLfixed left, GLfixed right,
+        GLfixed bottom, GLfixed top,
+        GLfixed zNear, GLfixed zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    orthof( fixedToFloat(left), fixedToFloat(right),
+            fixedToFloat(bottom), fixedToFloat(top),
+            fixedToFloat(zNear), fixedToFloat(zFar),
+            c);
+}
+
+void glRotatef(GLfloat a, GLfloat x, GLfloat y, GLfloat z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->rotate(a, x, y, z);
+    c->transforms.invalidate();
+}
+
+void glRotatex(GLfixed a, GLfixed x, GLfixed y, GLfixed z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->rotate( 
+            fixedToFloat(a), fixedToFloat(x),
+            fixedToFloat(y), fixedToFloat(z));
+    c->transforms.invalidate();
+}
+
+void glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->scale(x, y, z);
+    c->transforms.invalidate();
+}
+
+void glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->scale(
+            fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
+    c->transforms.invalidate();
+}
+
+void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->translate(x, y, z);
+    c->transforms.invalidate();
+}
+
+void glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->translate(
+            fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
+    c->transforms.invalidate();
+}
+
+void glScissor(GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    ogles_scissor(c, x, y, w, h);
+}
+
+void glViewport(GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    ogles_viewport(c, x, y, w, h);
+}
+
+void glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    depthRangef(zNear, zFar, c);
+}
+
+void glDepthRangex(GLclampx zNear, GLclampx zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    depthRangef(fixedToFloat(zNear), fixedToFloat(zFar), c);
+}
+
+void glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->polygonOffset.factor = factor;
+    c->polygonOffset.units = units;
+}
+
+void glPolygonOffset(GLfloat factor, GLfloat units)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->polygonOffset.factor = gglFloatToFixed(factor);
+    c->polygonOffset.units = gglFloatToFixed(units);
+}
+
+GLbitfield glQueryMatrixxOES(GLfixed* m, GLint* e)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    GLbitfield status = 0;
+    GLfloat const* f = c->transforms.current->top().elements();
+    for  (int i=0 ; i<16 ; i++) {
+        if (isnan(f[i]) || isinf(f[i])) {
+            status |= 1<<i;
+            continue;
+        }
+        e[i] = exponent(f[i]) - 7;
+        m[i] = mantissa(f[i]);
+    }
+    return status;
+}
diff --git a/opengl/libagl/matrix.h b/opengl/libagl/matrix.h
new file mode 100644
index 0000000..c9a38a9
--- /dev/null
+++ b/opengl/libagl/matrix.h
@@ -0,0 +1,355 @@
+/* libs/opengles/matrix.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_MATRIX_H
+#define ANDROID_OPENGLES_MATRIX_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+namespace android {
+
+const int OGLES_MODELVIEW_STACK_DEPTH   = 16;
+const int OGLES_PROJECTION_STACK_DEPTH  =  2;
+const int OGLES_TEXTURE_STACK_DEPTH     =  2;
+
+void ogles_init_matrix(ogles_context_t*);
+void ogles_uninit_matrix(ogles_context_t*);
+void ogles_invalidate_perspective(ogles_context_t* c);
+void ogles_validate_transform_impl(ogles_context_t* c, uint32_t want);
+
+int ogles_surfaceport(ogles_context_t* c, GLint x, GLint y);
+
+void ogles_scissor(ogles_context_t* c, 
+        GLint x, GLint y, GLsizei w, GLsizei h);
+
+void ogles_viewport(ogles_context_t* c,
+        GLint x, GLint y, GLsizei w, GLsizei h);
+
+inline void ogles_validate_transform(
+        ogles_context_t* c, uint32_t want)
+{
+    if (c->transforms.dirty & want)
+        ogles_validate_transform_impl(c, want);
+}
+
+// ----------------------------------------------------------------------------
+
+inline
+GLfixed vsquare3(GLfixed a, GLfixed b, GLfixed c) 
+{
+#if defined(__arm__) && !defined(__thumb__)
+
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %2       \n"
+        "smlal %0, %1, %3, %3       \n"
+        "smlal %0, %1, %4, %4       \n"
+        "movs  %0, %0, lsr #16      \n"
+        "adc   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a), "r"(b), "r"(c)
+        :   "cc"
+        ); 
+    return r;
+
+#else
+
+    return ((   int64_t(a)*a +
+                int64_t(b)*b +
+                int64_t(c)*c + 0x8000)>>16);
+
+#endif
+}
+
+static inline GLfixed mla2a( GLfixed a0, GLfixed b0,
+                            GLfixed a1, GLfixed b1,
+                            GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %3       \n"
+        "smlal %0, %1, %4, %5       \n"
+        "add   %0, %6, %0, lsr #16  \n"
+        "add   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a0), "r"(b0), 
+            "%r"(a1), "r"(b1),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    return ((   int64_t(a0)*b0 +
+                int64_t(a1)*b1)>>16) + c;
+
+#endif
+}
+
+static inline GLfixed mla3a( GLfixed a0, GLfixed b0,
+                             GLfixed a1, GLfixed b1,
+                             GLfixed a2, GLfixed b2,
+                             GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %3       \n"
+        "smlal %0, %1, %4, %5       \n"
+        "smlal %0, %1, %6, %7       \n"
+        "add   %0, %8, %0, lsr #16  \n"
+        "add   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a0), "r"(b0),
+            "%r"(a1), "r"(b1),
+            "%r"(a2), "r"(b2),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    return ((   int64_t(a0)*b0 +
+                int64_t(a1)*b1 +
+                int64_t(a2)*b2)>>16) + c;
+
+#endif
+}
+
+// b0, b1, b2 are signed 16-bit quanities
+// that have been shifted right by 'shift' bits relative to normal
+// S16.16 fixed point
+static inline GLfixed mla3a16( GLfixed a0, int32_t b1b0,
+                               GLfixed a1,
+                               GLfixed a2, int32_t b2,
+                               GLint shift,
+                               GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    asm(
+        "smulwb %0, %1, %2          \n"
+        "smlawt %0, %3, %2, %0      \n" 
+        "smlawb %0, %4, %5, %0      \n"
+        "add    %0, %7, %0, lsl %6  \n"
+        :   "=&r"(r)
+        :   "r"(a0), "r"(b1b0),
+            "r"(a1),
+            "r"(a2), "r"(b2),
+            "r"(shift),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    int32_t accum;
+    int16_t b0 = b1b0 & 0xffff;
+    int16_t b1 = (b1b0 >> 16) & 0xffff;
+    accum  = int64_t(a0)*int16_t(b0) >> 16;
+    accum += int64_t(a1)*int16_t(b1) >> 16;
+    accum += int64_t(a2)*int16_t(b2) >> 16;
+    accum = (accum << shift) + c;
+    return accum;
+
+#endif
+}
+
+
+static inline GLfixed mla3a16_btb( GLfixed a0,
+                                   GLfixed a1,
+                                   GLfixed a2,
+                                   int32_t b1b0, int32_t xxb2,
+                                   GLint shift,
+                                   GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    asm(
+        "smulwb %0, %1, %4          \n"
+        "smlawt %0, %2, %4, %0      \n" 
+        "smlawb %0, %3, %5, %0      \n"
+        "add    %0, %7, %0, lsl %6  \n"
+        :   "=&r"(r)
+        :   "r"(a0),
+            "r"(a1),
+            "r"(a2),
+            "r"(b1b0), "r"(xxb2),
+            "r"(shift),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    int32_t accum;
+    int16_t b0 =  b1b0        & 0xffff;
+    int16_t b1 = (b1b0 >> 16) & 0xffff;
+    int16_t b2 =  xxb2        & 0xffff;
+    accum  = int64_t(a0)*int16_t(b0) >> 16;
+    accum += int64_t(a1)*int16_t(b1) >> 16;
+    accum += int64_t(a2)*int16_t(b2) >> 16;
+    accum = (accum << shift) + c;
+    return accum;
+
+#endif
+}
+
+static inline GLfixed mla3a16_btt( GLfixed a0,
+                                   GLfixed a1,
+                                   GLfixed a2,
+                                   int32_t b1b0, int32_t b2xx,
+                                   GLint shift,
+                                   GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    asm(
+        "smulwb %0, %1, %4          \n"
+        "smlawt %0, %2, %4, %0      \n" 
+        "smlawt %0, %3, %5, %0      \n"
+        "add    %0, %7, %0, lsl %6  \n"
+        :   "=&r"(r)
+        :   "r"(a0),
+            "r"(a1),
+            "r"(a2),
+            "r"(b1b0), "r"(b2xx),
+            "r"(shift),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    int32_t accum;
+    int16_t b0 =  b1b0        & 0xffff;
+    int16_t b1 = (b1b0 >> 16) & 0xffff;
+    int16_t b2 = (b2xx >> 16) & 0xffff;
+    accum  = int64_t(a0)*int16_t(b0) >> 16;
+    accum += int64_t(a1)*int16_t(b1) >> 16;
+    accum += int64_t(a2)*int16_t(b2) >> 16;
+    accum = (accum << shift) + c;
+    return accum;
+
+#endif
+}
+
+static inline GLfixed mla3( GLfixed a0, GLfixed b0,
+                            GLfixed a1, GLfixed b1,
+                            GLfixed a2, GLfixed b2)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %3       \n"
+        "smlal %0, %1, %4, %5       \n"
+        "smlal %0, %1, %6, %7       \n"
+        "movs  %0, %0, lsr #16      \n"
+        "adc   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a0), "r"(b0),
+            "%r"(a1), "r"(b1),
+            "%r"(a2), "r"(b2)
+        :   "cc"
+        ); 
+    return r;
+    
+#else
+
+    return ((   int64_t(a0)*b0 +
+                int64_t(a1)*b1 +
+                int64_t(a2)*b2 + 0x8000)>>16);
+
+#endif
+}
+
+static inline GLfixed mla4( GLfixed a0, GLfixed b0,
+                            GLfixed a1, GLfixed b1,
+                            GLfixed a2, GLfixed b2,
+                            GLfixed a3, GLfixed b3)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %3       \n"
+        "smlal %0, %1, %4, %5       \n"
+        "smlal %0, %1, %6, %7       \n"
+        "smlal %0, %1, %8, %9       \n"
+        "movs  %0, %0, lsr #16      \n"
+        "adc   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a0), "r"(b0),
+            "%r"(a1), "r"(b1),
+            "%r"(a2), "r"(b2),
+            "%r"(a3), "r"(b3)
+        :   "cc"
+        ); 
+    return r;
+    
+#else
+
+    return ((   int64_t(a0)*b0 +
+                int64_t(a1)*b1 +
+                int64_t(a2)*b2 +
+                int64_t(a3)*b3 + 0x8000)>>16);
+
+#endif
+}
+
+inline
+GLfixed dot4(const GLfixed* a, const GLfixed* b) 
+{
+    return mla4(a[0], b[0], a[1], b[1], a[2], b[2], a[3], b[3]);
+}
+
+
+inline
+GLfixed dot3(const GLfixed* a, const GLfixed* b) 
+{
+    return mla3(a[0], b[0], a[1], b[1], a[2], b[2]);
+}
+
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_MATRIX_H
+
diff --git a/opengl/libagl/mipmap.cpp b/opengl/libagl/mipmap.cpp
new file mode 100644
index 0000000..ccd77b7
--- /dev/null
+++ b/opengl/libagl/mipmap.cpp
@@ -0,0 +1,192 @@
+/* libs/opengles/mipmap.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 <stdlib.h>
+
+#include "context.h"
+#include "state.h"
+#include "texture.h"
+#include "TextureObjectManager.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+status_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex)
+{
+    int level = 0;
+    const GGLSurface* base = &tex->surface;    
+    const GGLFormat& pixelFormat(c->rasterizer.formats[base->format]);
+
+    int w = base->width;
+    int h = base->height;
+    if ((w&h) == 1)
+        return NO_ERROR;
+
+    w = (w>>1) ? : 1;
+    h = (h>>1) ? : 1;
+
+    while(true) {
+        ++level;
+        const int bpr = w * pixelFormat.size;
+        if (tex->reallocate(level, w, h, w,
+                base->format, base->compressedFormat, bpr) != NO_ERROR) {
+            return NO_MEMORY;
+        }
+    
+        int stride = w;
+        int bs = base->stride;
+        GGLSurface& cur = tex->editMip(level);
+
+        if (base->format == GGL_PIXEL_FORMAT_RGB_565)
+        {
+            uint16_t const * src = (uint16_t const *)base->data;
+            uint16_t* dst = (uint16_t*)cur.data;
+            const uint32_t mask = 0x07E0F81F;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    uint32_t p00 = src[offset];
+                    uint32_t p10 = src[offset+1];
+                    uint32_t p01 = src[offset+bs];
+                    uint32_t p11 = src[offset+bs+1];
+                    p00 = (p00 | (p00 << 16)) & mask;
+                    p01 = (p01 | (p01 << 16)) & mask;
+                    p10 = (p10 | (p10 << 16)) & mask;
+                    p11 = (p11 | (p11 << 16)) & mask;
+                    uint32_t grb = ((p00 + p10 + p01 + p11) >> 2) & mask;
+                    uint32_t rgb = (grb & 0xFFFF) | (grb >> 16);
+                    dst[x + y*stride] = rgb;
+                    offset += 2;
+                }
+            }
+        }
+        else if (base->format == GGL_PIXEL_FORMAT_RGBA_5551)
+        {
+            uint16_t const * src = (uint16_t const *)base->data;
+            uint16_t* dst = (uint16_t*)cur.data;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    uint32_t p00 = src[offset];
+                    uint32_t p10 = src[offset+1];
+                    uint32_t p01 = src[offset+bs];
+                    uint32_t p11 = src[offset+bs+1];
+                    uint32_t r = ((p00>>11)+(p10>>11)+(p01>>11)+(p11>>11)+2)>>2;
+                    uint32_t g = (((p00>>6)+(p10>>6)+(p01>>6)+(p11>>6)+2)>>2)&0x3F;
+                    uint32_t b = ((p00&0x3E)+(p10&0x3E)+(p01&0x3E)+(p11&0x3E)+4)>>3;
+                    uint32_t a = ((p00&1)+(p10&1)+(p01&1)+(p11&1)+2)>>2;
+                    dst[x + y*stride] = (r<<11)|(g<<6)|(b<<1)|a;
+                    offset += 2;
+                }
+            }
+        }
+        else if (base->format == GGL_PIXEL_FORMAT_RGBA_8888)
+        {
+            uint32_t const * src = (uint32_t const *)base->data;
+            uint32_t* dst = (uint32_t*)cur.data;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    uint32_t p00 = src[offset];
+                    uint32_t p10 = src[offset+1];
+                    uint32_t p01 = src[offset+bs];
+                    uint32_t p11 = src[offset+bs+1];
+                    uint32_t rb00 = p00 & 0x00FF00FF;
+                    uint32_t rb01 = p01 & 0x00FF00FF;
+                    uint32_t rb10 = p10 & 0x00FF00FF;
+                    uint32_t rb11 = p11 & 0x00FF00FF;
+                    uint32_t ga00 = (p00 >> 8) & 0x00FF00FF;
+                    uint32_t ga01 = (p01 >> 8) & 0x00FF00FF;
+                    uint32_t ga10 = (p10 >> 8) & 0x00FF00FF;
+                    uint32_t ga11 = (p11 >> 8) & 0x00FF00FF;
+                    uint32_t rb = (rb00 + rb01 + rb10 + rb11)>>2;
+                    uint32_t ga = (ga00 + ga01 + ga10 + ga11)>>2;
+                    uint32_t rgba = (rb & 0x00FF00FF) | ((ga & 0x00FF00FF)<<8);
+                    dst[x + y*stride] = rgba;
+                    offset += 2;
+                }
+            }
+        }
+        else if ((base->format == GGL_PIXEL_FORMAT_RGB_888) ||
+                 (base->format == GGL_PIXEL_FORMAT_LA_88) ||
+                 (base->format == GGL_PIXEL_FORMAT_A_8) ||
+                 (base->format == GGL_PIXEL_FORMAT_L_8))
+        {
+            int skip;
+            switch (base->format) {
+            case GGL_PIXEL_FORMAT_RGB_888:  skip = 3;   break;
+            case GGL_PIXEL_FORMAT_LA_88:    skip = 2;   break;
+            default:                        skip = 1;   break;
+            }
+            uint8_t const * src = (uint8_t const *)base->data;
+            uint8_t* dst = (uint8_t*)cur.data;            
+            bs *= skip;
+            stride *= skip;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    for (int c=0 ; c<skip ; c++) {
+                        uint32_t p00 = src[c+offset];
+                        uint32_t p10 = src[c+offset+skip];
+                        uint32_t p01 = src[c+offset+bs];
+                        uint32_t p11 = src[c+offset+bs+skip];
+                        dst[x + y*stride + c] = (p00 + p10 + p01 + p11) >> 2;
+                    }
+                    offset += 2*skip;
+                }
+            }
+        }
+        else if (base->format == GGL_PIXEL_FORMAT_RGBA_4444)
+        {
+            uint16_t const * src = (uint16_t const *)base->data;
+            uint16_t* dst = (uint16_t*)cur.data;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    uint32_t p00 = src[offset];
+                    uint32_t p10 = src[offset+1];
+                    uint32_t p01 = src[offset+bs];
+                    uint32_t p11 = src[offset+bs+1];
+                    p00 = ((p00 << 12) & 0x0F0F0000) | (p00 & 0x0F0F);
+                    p10 = ((p10 << 12) & 0x0F0F0000) | (p10 & 0x0F0F);
+                    p01 = ((p01 << 12) & 0x0F0F0000) | (p01 & 0x0F0F);
+                    p11 = ((p11 << 12) & 0x0F0F0000) | (p11 & 0x0F0F);
+                    uint32_t rbga = (p00 + p10 + p01 + p11) >> 2;
+                    uint32_t rgba = (rbga & 0x0F0F) | ((rbga>>12) & 0xF0F0);
+                    dst[x + y*stride] = rgba;
+                    offset += 2;
+                }
+            }
+        } else {
+            LOGE("Unsupported format (%d)", base->format);
+            return BAD_TYPE;
+        }
+
+        // exit condition: we just processed the 1x1 LODs
+        if ((w&h) == 1)
+            break;
+
+        base = &cur;
+        w = (w>>1) ? : 1;
+        h = (h>>1) ? : 1;
+    }
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/opengl/libagl/primitives.cpp b/opengl/libagl/primitives.cpp
new file mode 100644
index 0000000..20e8d37
--- /dev/null
+++ b/opengl/libagl/primitives.cpp
@@ -0,0 +1,1095 @@
+/* libs/opengles/primitives.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 <stdlib.h>
+#include <math.h>
+
+#include "context.h"
+#include "primitives.h"
+#include "light.h"
+#include "matrix.h"
+#include "vertex.h"
+#include "fp.h"
+#include "TextureObjectManager.h"
+
+extern "C" void iterators0032(const void* that,
+        int32_t* it, int32_t c0, int32_t c1, int32_t c2);
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static void primitive_point(ogles_context_t* c, vertex_t* v);
+static void primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
+static void primitive_clip_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void primitive_nop_point(ogles_context_t* c, vertex_t* v);
+static void primitive_nop_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
+static void primitive_nop_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static inline bool cull_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void lerp_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void lerp_texcoords(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void lerp_texcoords_w(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void clip_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static unsigned int clip_line(ogles_context_t* c,
+        vertex_t* s, vertex_t* p);
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+static void lightTriangleDarkSmooth(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (!(v0->flags & vertex_t::LIT)) {
+        v0->flags |= vertex_t::LIT;
+        const GLvoid* cp = c->arrays.color.element(
+                v0->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v0->color.v, cp);
+    }
+    if (!(v1->flags & vertex_t::LIT)) {
+        v1->flags |= vertex_t::LIT;
+        const GLvoid* cp = c->arrays.color.element(
+                v1->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v1->color.v, cp);
+    }
+    if(!(v2->flags & vertex_t::LIT)) {
+        v2->flags |= vertex_t::LIT;
+        const GLvoid* cp = c->arrays.color.element(
+                v2->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v2->color.v, cp);
+    }
+}
+
+static void lightTriangleDarkFlat(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (!(v2->flags & vertex_t::LIT)) {
+        v2->flags |= vertex_t::LIT;
+        const GLvoid* cp = c->arrays.color.element(
+                v2->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v2->color.v, cp);
+    }
+    // configure the rasterizer here, before we clip
+    c->rasterizer.procs.color4xv(c, v2->color.v);
+}
+
+static void lightTriangleSmooth(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (!(v0->flags & vertex_t::LIT))
+        c->lighting.lightVertex(c, v0);
+    if (!(v1->flags & vertex_t::LIT))
+        c->lighting.lightVertex(c, v1);
+    if(!(v2->flags & vertex_t::LIT))
+        c->lighting.lightVertex(c, v2);
+}
+
+static void lightTriangleFlat(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (!(v2->flags & vertex_t::LIT))
+        c->lighting.lightVertex(c, v2);
+    // configure the rasterizer here, before we clip
+    c->rasterizer.procs.color4xv(c, v2->color.v);
+}
+
+// The fog versions...
+
+static inline
+void lightVertexDarkSmoothFog(ogles_context_t* c, vertex_t* v)
+{
+    if (!(v->flags & vertex_t::LIT)) {
+        v->flags |= vertex_t::LIT;
+        v->fog = c->fog.fog(c, v->window.z);
+        const GLvoid* cp = c->arrays.color.element(
+                v->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v->color.v, cp);
+    }
+}
+static inline
+void lightVertexDarkFlatFog(ogles_context_t* c, vertex_t* v)
+{
+    if (!(v->flags & vertex_t::LIT)) {
+        v->flags |= vertex_t::LIT;
+        v->fog = c->fog.fog(c, v->window.z);
+    }
+}
+static inline
+void lightVertexSmoothFog(ogles_context_t* c, vertex_t* v)
+{
+    if (!(v->flags & vertex_t::LIT)) {
+        v->fog = c->fog.fog(c, v->window.z);
+        c->lighting.lightVertex(c, v);
+    }
+}
+
+static void lightTriangleDarkSmoothFog(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    lightVertexDarkSmoothFog(c, v0);
+    lightVertexDarkSmoothFog(c, v1);
+    lightVertexDarkSmoothFog(c, v2);
+}
+
+static void lightTriangleDarkFlatFog(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    lightVertexDarkFlatFog(c, v0);
+    lightVertexDarkFlatFog(c, v1);
+    lightVertexDarkSmoothFog(c, v2);
+    // configure the rasterizer here, before we clip
+    c->rasterizer.procs.color4xv(c, v2->color.v);
+}
+
+static void lightTriangleSmoothFog(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    lightVertexSmoothFog(c, v0);
+    lightVertexSmoothFog(c, v1);
+    lightVertexSmoothFog(c, v2);
+}
+
+static void lightTriangleFlatFog(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    lightVertexDarkFlatFog(c, v0);
+    lightVertexDarkFlatFog(c, v1);
+    lightVertexSmoothFog(c, v2);
+    // configure the rasterizer here, before we clip
+    c->rasterizer.procs.color4xv(c, v2->color.v);
+}
+
+
+
+typedef void (*light_primitive_t)(ogles_context_t*,
+        vertex_t*, vertex_t*, vertex_t*);
+
+// fog 0x4, light 0x2, smooth 0x1
+static const light_primitive_t lightPrimitive[8] = {
+    lightTriangleDarkFlat,          // no fog | dark  | flat
+    lightTriangleDarkSmooth,        // no fog | dark  | smooth
+    lightTriangleFlat,              // no fog | light | flat
+    lightTriangleSmooth,            // no fog | light | smooth
+    lightTriangleDarkFlatFog,       // fog    | dark  | flat
+    lightTriangleDarkSmoothFog,     // fog    | dark  | smooth
+    lightTriangleFlatFog,           // fog    | light | flat
+    lightTriangleSmoothFog          // fog    | light | smooth
+};
+
+void ogles_validate_primitives(ogles_context_t* c)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+
+    // set up the lighting/shading/smoothing/fogging function
+    int index = enables & GGL_ENABLE_SMOOTH ? 0x1 : 0;
+    index |= c->lighting.enable ? 0x2 : 0;
+    index |= enables & GGL_ENABLE_FOG ? 0x4 : 0;
+    c->lighting.lightTriangle = lightPrimitive[index];
+    
+    // set up the primitive renderers
+    if (ggl_likely(c->arrays.vertex.enable)) {
+        c->prims.renderPoint    = primitive_point;
+        c->prims.renderLine     = primitive_line;
+        c->prims.renderTriangle = primitive_clip_triangle;
+    } else {
+        c->prims.renderPoint    = primitive_nop_point;
+        c->prims.renderLine     = primitive_nop_line;
+        c->prims.renderTriangle = primitive_nop_triangle;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+void compute_iterators_t::initTriangle(
+        vertex_t const* v0, vertex_t const* v1, vertex_t const* v2)
+{
+    m_dx01 = v1->window.x - v0->window.x;
+    m_dy10 = v0->window.y - v1->window.y;
+    m_dx20 = v0->window.x - v2->window.x;
+    m_dy02 = v2->window.y - v0->window.y;
+    m_area = m_dx01*m_dy02 + (-m_dy10)*m_dx20;
+}
+
+void compute_iterators_t::initLerp(vertex_t const* v0, uint32_t enables)
+{
+    m_x0 = v0->window.x;
+    m_y0 = v0->window.y;
+    const GGLcoord area = (m_area + TRI_HALF) >> TRI_FRACTION_BITS;
+    const GGLcoord minArea = 2; // cannot be inversed
+    // triangles with an area smaller than 1.0 are not smooth-shaded
+
+    int q=0, s=0, d=0;
+    if (abs(area) >= minArea) {
+        // Here we do some voodoo magic, to compute a suitable scale
+        // factor for deltas/area:
+
+        // First compute the 1/area with full 32-bits precision,
+        // gglRecipQNormalized returns a number [-0.5, 0.5[ and an exponent.
+        d = gglRecipQNormalized(area, &q);
+
+        // Then compute the minimum left-shift to not overflow the muls
+        // below. 
+        s = 32 - gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));
+
+        // We'll keep 16-bits of precision for deltas/area. So we need
+        // to shift everything left an extra 15 bits.
+        s += 15;
+        
+        // make sure all final shifts are not > 32, because gglMulx
+        // can't handle it.
+        if (s < q) s = q;
+        if (s > 32) {
+            d >>= 32-s;
+            s = 32;
+        }
+    }
+
+    m_dx01 = gglMulx(m_dx01, d, s);
+    m_dy10 = gglMulx(m_dy10, d, s);
+    m_dx20 = gglMulx(m_dx20, d, s);
+    m_dy02 = gglMulx(m_dy02, d, s);
+    m_area_scale = 32 + q - s;
+    m_scale = 0;
+
+    if (enables & GGL_ENABLE_TMUS) {
+        const int A = gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));
+        const int B = gglClz(abs(m_x0)|abs(m_y0));
+        m_scale = max(0, 32 - (A + 16)) +
+                  max(0, 32 - (B + TRI_FRACTION_BITS)) + 1;
+    }
+}
+
+int compute_iterators_t::iteratorsScale(GGLfixed* it,
+        int32_t c0, int32_t c1, int32_t c2) const
+{
+    int32_t dc01 = c1 - c0;
+    int32_t dc02 = c2 - c0;
+    const int A = gglClz(abs(c0));
+    const int B = gglClz(abs(dc01)|abs(dc02));
+    const int scale = min(A, B - m_scale) - 2;
+    if (scale >= 0) {
+        c0   <<= scale;
+        dc01 <<= scale;
+        dc02 <<= scale;
+    } else {
+        c0   >>= -scale;
+        dc01 >>= -scale;
+        dc02 >>= -scale;
+    }
+    const int s = m_area_scale;
+    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
+    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
+    int32_t c = c0 - (gglMulAddx(dcdx, m_x0, 
+            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
+    it[0] = c;
+    it[1] = dcdx;
+    it[2] = dcdy;
+    return scale;
+}
+
+void compute_iterators_t::iterators1616(GGLfixed* it,
+        GGLfixed c0, GGLfixed c1, GGLfixed c2) const
+{
+    const GGLfixed dc01 = c1 - c0;
+    const GGLfixed dc02 = c2 - c0;
+    // 16.16 x 16.16 == 32.32 --> 16.16
+    const int s = m_area_scale;
+    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
+    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
+    int32_t c = c0 - (gglMulAddx(dcdx, m_x0,
+            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
+    it[0] = c;
+    it[1] = dcdx;
+    it[2] = dcdy;
+}
+
+#if defined(__arm__) && !defined(__thumb__)
+inline void compute_iterators_t::iterators0032(int32_t* it,
+        int32_t c0, int32_t c1, int32_t c2) const
+{
+    ::iterators0032(this, it, c0, c1, c2);
+}
+#else
+void compute_iterators_t::iterators0032(int32_t* it,
+        int32_t c0, int32_t c1, int32_t c2) const
+{
+    const int s = m_area_scale - 16;
+    int32_t dc01 = (c1 - c0)>>s;
+    int32_t dc02 = (c2 - c0)>>s;
+    // 16.16 x 16.16 == 32.32
+    int64_t dcdx = gglMulii(dc01, m_dy02) + gglMulii(dc02, m_dy10);
+    int64_t dcdy = gglMulii(dc02, m_dx01) + gglMulii(dc01, m_dx20);
+    int32_t c = (c0<<16) - ((dcdx*m_x0 + dcdy*m_y0)>>4);
+    it[ 0] = c;
+    it[ 1] = dcdx;
+    it[ 2] = dcdy;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+static inline int32_t clampZ(GLfixed z) CONST;
+int32_t clampZ(GLfixed z) {
+    z = (z & ~(z>>31));
+    if (z >= 0x10000)
+        z = 0xFFFF;
+    return z;
+}
+
+static __attribute__((noinline))
+void fetch_texcoord_impl(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    vertex_t* const vtx[3] = { v0, v1, v2 };
+    array_t const * const texcoordArray = c->arrays.texture;
+    
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (!(c->rasterizer.state.texture[i].enable))
+            continue;
+        
+        for (int j=0 ; j<3 ; j++) {
+            vertex_t* const v = vtx[j];
+            if (v->flags & vertex_t::TT)
+                continue;
+
+            // NOTE: here we could compute automatic texgen
+            // such as sphere/cube maps, instead of fetching them
+            // from the textcoord array.
+
+            vec4_t& coords = v->texture[i];
+            const GLubyte* tp = texcoordArray[i].element(
+                    v->index & vertex_cache_t::INDEX_MASK);
+            texcoordArray[i].fetch(c, coords.v, tp);
+
+            // transform texture coordinates...
+            coords.Q = 0x10000;
+            const transform_t& tr = c->transforms.texture[i].transform; 
+            if (ggl_unlikely(tr.ops)) {
+                c->arrays.tex_transform[i](&tr, &coords, &coords);
+            }
+
+            // divide by Q
+            const GGLfixed q = coords.Q;
+            if (ggl_unlikely(q != 0x10000)) {
+                const int32_t qinv = gglRecip28(q);
+                coords.S = gglMulx(coords.S, qinv, 28);
+                coords.T = gglMulx(coords.T, qinv, 28);
+            }
+        }
+    }
+    v0->flags |= vertex_t::TT;
+    v1->flags |= vertex_t::TT;
+    v2->flags |= vertex_t::TT;
+}
+
+inline void fetch_texcoord(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+    if (!(enables & GGL_ENABLE_TMUS))
+        return;
+
+    // Fetch & transform texture coordinates...
+    if (ggl_likely(v0->flags & v1->flags & v2->flags & vertex_t::TT)) {
+        // already done for all three vertices, bail...
+        return;
+    }
+    fetch_texcoord_impl(c, v0, v1, v2);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Point
+#endif
+
+void primitive_nop_point(ogles_context_t*, vertex_t*) {
+}
+
+void primitive_point(ogles_context_t* c, vertex_t* v)
+{
+    // lighting & clamping...
+    const uint32_t enables = c->rasterizer.state.enables;
+
+    if (ggl_unlikely(!(v->flags & vertex_t::LIT))) {
+        if (c->lighting.enable) {
+            c->lighting.lightVertex(c, v);
+        } else {
+            v->flags |= vertex_t::LIT;
+            const GLvoid* cp = c->arrays.color.element(
+                    v->index & vertex_cache_t::INDEX_MASK);
+            c->arrays.color.fetch(c, v->color.v, cp);
+        }
+        if (enables & GGL_ENABLE_FOG) {
+            v->fog = c->fog.fog(c, v->window.z);
+        }
+    }
+
+    // XXX: we don't need to do that each-time
+    // if color array and lighting not enabled 
+    c->rasterizer.procs.color4xv(c, v->color.v);
+
+    // XXX: look into ES point-sprite extension
+    if (enables & GGL_ENABLE_TMUS) {
+        fetch_texcoord(c, v,v,v);
+        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+            if (!c->rasterizer.state.texture[i].enable) 
+                continue;
+            int32_t itt[8];
+            itt[1] = itt[2] = itt[4] = itt[5] = 0;
+            itt[6] = itt[7] = 16; // XXX: check that
+            if (c->rasterizer.state.texture[i].s_wrap == GGL_CLAMP) {
+                int width = c->textures.tmu[i].texture->surface.width;
+                itt[0] = v->texture[i].S * width;
+                itt[6] = 0;
+            }
+            if (c->rasterizer.state.texture[i].t_wrap == GGL_CLAMP) {
+                int height = c->textures.tmu[i].texture->surface.height;
+                itt[3] = v->texture[i].T * height;
+                itt[7] = 0;
+            }
+            c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
+        }
+    }
+    
+    if (enables & GGL_ENABLE_DEPTH_TEST) {
+        int32_t itz[3];
+        itz[0] = clampZ(v->window.z) * 0x00010001;
+        itz[1] = itz[2] = 0;
+        c->rasterizer.procs.zGrad3xv(c, itz);
+    }
+
+    if (enables & GGL_ENABLE_FOG) {
+        GLfixed itf[3];
+        itf[0] = v->fog;
+        itf[1] = itf[2] = 0;
+        c->rasterizer.procs.fogGrad3xv(c, itf);
+    }
+
+    // Render our point...
+    c->rasterizer.procs.pointx(c, v->window.v, c->point.size);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Line
+#endif
+
+void primitive_nop_line(ogles_context_t*, vertex_t*, vertex_t*) {
+}
+
+void primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1)
+{
+    // This is a cheezy implementation of line drawing that
+    // uses 2 triangles per line. 
+    // That said, how often line drawing is used?
+
+    // get texture coordinates
+    fetch_texcoord(c, v0, v1, v1);
+
+    // light/shade the vertices first (they're copied below)
+    c->lighting.lightTriangle(c, v0, v1, v1);
+
+    vertex_t v[4];
+    v[0] = *v0;
+    v[1] = *v1;
+    v0 = &v[0];
+    v1 = &v[1];
+
+    // clip the line if needed
+    if (ggl_unlikely((v0->flags | v1->flags) & vertex_t::CLIP_ALL)) {
+        unsigned int count = clip_line(c, v0, v1);
+        if (ggl_unlikely(count == 0))
+            return;
+    }
+
+    // compute iterators...
+    const uint32_t enables = c->rasterizer.state.enables;
+    const uint32_t mask =   GGL_ENABLE_TMUS |
+                            GGL_ENABLE_SMOOTH |
+                            GGL_ENABLE_W | 
+                            GGL_ENABLE_FOG |
+                            GGL_ENABLE_DEPTH_TEST;
+
+    if (ggl_unlikely(enables & mask)) {
+        c->lerp.initTriangle(v0, v1, v1);
+        lerp_triangle(c, v0, v1, v1);
+    }
+
+    // render our line
+    c->rasterizer.procs.linex(c, v0->window.v, v1->window.v, c->line.width);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Triangle
+#endif
+
+void primitive_nop_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2) {
+}
+
+void primitive_clip_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    uint32_t cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;
+    if (ggl_likely(!cc)) {
+        // code below must be as optimized as possible, this is the
+        // common code path.
+
+        // This triangle is not clipped, test if it's culled
+        // unclipped triangle...
+        c->lerp.initTriangle(v0, v1, v2);
+        if (cull_triangle(c, v0, v1, v2))
+            return; // culled!
+
+        // Fetch all texture coordinates if needed
+        fetch_texcoord(c, v0, v1, v2);
+
+        // light (or shade) our triangle!
+        c->lighting.lightTriangle(c, v0, v1, v2);
+
+        triangle(c, v0, v1, v2);
+        return;
+    }
+
+    // The assumption here is that we're not going to clip very often,
+    // and even more rarely will we clip a triangle that ends up
+    // being culled out. So it's okay to light the vertices here, even though
+    // in a few cases we won't render the triangle (if culled).
+
+    // Fetch texture coordinates...
+    fetch_texcoord(c, v0, v1, v2);
+
+    // light (or shade) our triangle!
+    c->lighting.lightTriangle(c, v0, v1, v2);
+
+    clip_triangle(c, v0, v1, v2);
+}
+
+// -----------------------------------------------------------------------
+
+void triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    // compute iterators...
+    const uint32_t enables = c->rasterizer.state.enables;
+    const uint32_t mask =   GGL_ENABLE_TMUS |
+                            GGL_ENABLE_SMOOTH |
+                            GGL_ENABLE_W | 
+                            GGL_ENABLE_FOG |
+                            GGL_ENABLE_DEPTH_TEST;
+
+    if (ggl_likely(enables & mask))
+        lerp_triangle(c, v0, v1, v2);
+
+    c->rasterizer.procs.trianglex(c, v0->window.v, v1->window.v, v2->window.v);
+}
+
+void lerp_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+    c->lerp.initLerp(v0, enables);
+
+    // set up texture iterators
+    if (enables & GGL_ENABLE_TMUS) {
+        if (enables & GGL_ENABLE_W) {
+            lerp_texcoords_w(c, v0, v1, v2);
+        } else {
+            lerp_texcoords(c, v0, v1, v2);
+        }
+    }
+
+    // set up the color iterators
+    const compute_iterators_t& lerp = c->lerp;
+    if (enables & GGL_ENABLE_SMOOTH) {
+        GLfixed itc[12];
+        for (int i=0 ; i<4 ; i++) {
+            const GGLcolor c0 = v0->color.v[i] * 255;
+            const GGLcolor c1 = v1->color.v[i] * 255;
+            const GGLcolor c2 = v2->color.v[i] * 255;
+            lerp.iterators1616(&itc[i*3], c0, c1, c2);
+        }
+        c->rasterizer.procs.colorGrad12xv(c, itc);
+    }
+
+    if (enables & GGL_ENABLE_DEPTH_TEST) {
+        int32_t itz[3];
+        const int32_t v0z = clampZ(v0->window.z);
+        const int32_t v1z = clampZ(v1->window.z);
+        const int32_t v2z = clampZ(v2->window.z);
+        lerp.iterators0032(itz, v0z, v1z, v2z);
+        if (ggl_unlikely(c->polygonOffset.enable)) {
+            const GLfixed factor = c->polygonOffset.factor;
+            const GLfixed units = c->polygonOffset.units;
+            int32_t maxDepthSlope = max(abs(itz[1]), abs(itz[2]));
+            int32_t offset = (int64_t(maxDepthSlope)*factor +
+                    (int64_t(units) << 16)) >> 16;
+            itz[0] += offset; // XXX: this can cause overflows
+        }
+        c->rasterizer.procs.zGrad3xv(c, itz);
+    }
+
+    if (ggl_unlikely(enables & GGL_ENABLE_FOG)) {
+        GLfixed itf[3];
+        lerp.iterators1616(itf, v0->fog, v1->fog, v2->fog);
+        c->rasterizer.procs.fogGrad3xv(c, itf);
+    }
+}
+
+
+static inline
+int compute_lod(ogles_context_t* c, int i,
+        int32_t s0, int32_t t0, int32_t s1, int32_t t1, int32_t s2, int32_t t2)
+{
+    // Compute mipmap level / primitive
+    // rho = sqrt( texelArea / area )
+    // lod = log2( rho )
+    // lod = log2( texelArea / area ) / 2
+    // lod = (log2( texelArea ) - log2( area )) / 2
+    const compute_iterators_t& lerp = c->lerp;
+    const GGLcoord area = abs(lerp.area());
+    const int w = c->textures.tmu[i].texture->surface.width;
+    const int h = c->textures.tmu[i].texture->surface.height;
+    const int shift = 16 + (16 - TRI_FRACTION_BITS);
+    int32_t texelArea = abs( gglMulx(s1-s0, t2-t0, shift) -
+            gglMulx(s2-s0, t1-t0, shift) )*w*h;
+    int log2TArea = (32-TRI_FRACTION_BITS  -1) - gglClz(texelArea);
+    int log2Area  = (32-TRI_FRACTION_BITS*2-1) - gglClz(area);
+    int lod = (log2TArea - log2Area + 1) >> 1;
+    return lod;
+}
+
+void lerp_texcoords(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    const compute_iterators_t& lerp = c->lerp;
+    int32_t itt[8] __attribute__((aligned(16)));
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        const texture_t& tmu = c->rasterizer.state.texture[i];
+        if (!tmu.enable) 
+            continue;
+
+        // compute the jacobians using block floating-point
+        int32_t s0 = v0->texture[i].S;
+        int32_t t0 = v0->texture[i].T;
+        int32_t s1 = v1->texture[i].S;
+        int32_t t1 = v1->texture[i].T;
+        int32_t s2 = v2->texture[i].S;
+        int32_t t2 = v2->texture[i].T;
+
+        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
+        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
+            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
+            c->rasterizer.procs.bindTextureLod(c, i,
+                    &c->textures.tmu[i].texture->mip(lod));
+        }
+
+        // premultiply (s,t) when clampling
+        if (tmu.s_wrap == GGL_CLAMP) {
+            const int width = tmu.surface.width;
+            s0 *= width;
+            s1 *= width;
+            s2 *= width;
+        }
+        if (tmu.t_wrap == GGL_CLAMP) {
+            const int height = tmu.surface.height;
+            t0 *= height;
+            t1 *= height;
+            t2 *= height;
+        }
+        itt[6] = -lerp.iteratorsScale(itt+0, s0, s1, s2);
+        itt[7] = -lerp.iteratorsScale(itt+3, t0, t1, t2);
+        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
+    }
+}
+
+void lerp_texcoords_w(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    const compute_iterators_t& lerp = c->lerp;
+    int32_t itt[8] __attribute__((aligned(16)));
+    int32_t itw[3];
+
+    // compute W's scale to 2.30
+    int32_t w0 = v0->window.w;
+    int32_t w1 = v1->window.w;
+    int32_t w2 = v2->window.w;
+    int wscale = 32 - gglClz(w0|w1|w2);
+
+    // compute the jacobian using block floating-point    
+    int sc = lerp.iteratorsScale(itw, w0, w1, w2);
+    sc +=  wscale - 16;
+    c->rasterizer.procs.wGrad3xv(c, itw);
+
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        const texture_t& tmu = c->rasterizer.state.texture[i];
+        if (!tmu.enable) 
+            continue;
+
+        // compute the jacobians using block floating-point
+        int32_t s0 = v0->texture[i].S;
+        int32_t t0 = v0->texture[i].T;
+        int32_t s1 = v1->texture[i].S;
+        int32_t t1 = v1->texture[i].T;
+        int32_t s2 = v2->texture[i].S;
+        int32_t t2 = v2->texture[i].T;
+
+        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
+        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
+            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
+            c->rasterizer.procs.bindTextureLod(c, i,
+                    &c->textures.tmu[i].texture->mip(lod));
+        }
+
+        // premultiply (s,t) when clampling
+        if (tmu.s_wrap == GGL_CLAMP) {
+            const int width = tmu.surface.width;
+            s0 *= width;
+            s1 *= width;
+            s2 *= width;
+        }
+        if (tmu.t_wrap == GGL_CLAMP) {
+            const int height = tmu.surface.height;
+            t0 *= height;
+            t1 *= height;
+            t2 *= height;
+        }
+
+        s0 = gglMulx(s0, w0, wscale);
+        t0 = gglMulx(t0, w0, wscale);
+        s1 = gglMulx(s1, w1, wscale);
+        t1 = gglMulx(t1, w1, wscale);
+        s2 = gglMulx(s2, w2, wscale);
+        t2 = gglMulx(t2, w2, wscale);
+
+        itt[6] = sc - lerp.iteratorsScale(itt+0, s0, s1, s2);
+        itt[7] = sc - lerp.iteratorsScale(itt+3, t0, t1, t2);
+        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
+    }
+}
+
+
+static inline
+bool cull_triangle(ogles_context_t* c, vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (ggl_likely(c->cull.enable)) {
+        const GLenum winding = (c->lerp.area() > 0) ? GL_CW : GL_CCW;
+        const GLenum face = (winding == c->cull.frontFace) ? GL_FRONT : GL_BACK;
+        if (face == c->cull.cullFace)
+            return true; // culled!
+    }
+    return false;
+}
+
+static inline
+GLfixed frustumPlaneDist(int plane, const vec4_t& s)
+{
+    const GLfixed d = s.v[ plane >> 1 ];
+    return  ((plane & 1) ? (s.w - d) : (s.w + d)); 
+}
+
+static inline
+int32_t clipDivide(GLfixed a, GLfixed b) {
+    // returns a 4.28 fixed-point
+    return gglMulDivi(1LU<<28, a, b);
+} 
+
+void clip_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    uint32_t all_cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;
+
+    vertex_t *p0, *p1, *p2;
+    const int MAX_CLIPPING_PLANES = 6 + OGLES_MAX_CLIP_PLANES;
+    const int MAX_VERTICES = 3;
+
+    // Temporary buffer to hold the new vertices. Each plane can add up to 
+    // two new vertices (because the polygon is convex).
+    // We need one extra element, to handle an overflow case when
+    // the polygon degenerates into something non convex.
+    vertex_t buffer[MAX_CLIPPING_PLANES * 2 + 1];   // ~3KB
+    vertex_t* buf = buffer;
+
+    // original list of vertices (polygon to clip, in fact this
+    // function works with an arbitrary polygon).
+    vertex_t* in[3] = { v0, v1, v2 };
+    
+    // output lists (we need 2, which we use back and forth)
+    // (maximum outpout list's size is MAX_CLIPPING_PLANES + MAX_VERTICES)
+    // 2 more elements for overflow when non convex polygons.
+    vertex_t* out[2][MAX_CLIPPING_PLANES + MAX_VERTICES + 2];
+    unsigned int outi = 0;
+    
+    // current input list
+    vertex_t** ivl = in;
+
+    // 3 input vertices, 0 in the output list, first plane
+    unsigned int ic = 3;
+
+    // User clip-planes first, the clipping is always done in eye-coordinate
+    // this is basically the same algorithm than for the view-volume
+    // clipping, except for the computation of the distance (vertex, plane)
+    // and the fact that we need to compute the eye-coordinates of each
+    // new vertex we create.
+    
+    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
+    {
+        unsigned int plane = 0;
+        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
+        do {
+            if (cc & 1) {        
+                // pointers to our output list (head and current)
+                vertex_t** const ovl = &out[outi][0];
+                vertex_t** output = ovl;
+                unsigned int oc = 0;
+                unsigned int sentinel = 0;
+                // previous vertice, compute distance to the plane
+                vertex_t* s = ivl[ic-1];
+                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
+                GLfixed sd = dot4(equation.v, s->eye.v);
+                // clip each vertice against this plane...
+                for (unsigned int i=0 ; i<ic ; i++) {            
+                    vertex_t* p = ivl[i];
+                    const GLfixed pd = dot4(equation.v, p->eye.v);
+                    if (sd >= 0) {
+                        if (pd >= 0) {
+                            // both inside
+                            *output++ = p;
+                            oc++;
+                        } else {
+                            // s inside, p outside (exiting)
+                            const GLfixed t = clipDivide(sd, sd-pd);
+                            c->arrays.clipEye(c, buf, t, p, s);
+                            *output++ = buf++;
+                            oc++;
+                            if (++sentinel >= 3)
+                                return; // non-convex polygon!
+                        }
+                    } else {
+                        if (pd >= 0) {
+                            // s outside (entering)
+                            if (pd) {
+                                const GLfixed t = clipDivide(pd, pd-sd);
+                                c->arrays.clipEye(c, buf, t, s, p);
+                                *output++ = buf++;
+                                oc++;
+                                if (++sentinel >= 3)
+                                    return; // non-convex polygon!
+                            }
+                            *output++ = p;
+                            oc++;
+                        } else {
+                           // both outside
+                        }
+                    }
+                    s = p;
+                    sd = pd;
+                }
+                // output list become the new input list
+                if (oc<3)
+                    return; // less than 3 vertices left? we're done!
+                ivl = ovl;
+                ic = oc;
+                outi = 1-outi;
+            }
+            cc >>= 1;
+            plane++;
+        } while (cc);
+    }
+
+    // frustum clip-planes
+    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
+    {
+        unsigned int plane = 0;
+        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
+        do {
+            if (cc & 1) {        
+                // pointers to our output list (head and current)
+                vertex_t** const ovl = &out[outi][0];
+                vertex_t** output = ovl;
+                unsigned int oc = 0;
+                unsigned int sentinel = 0;
+                // previous vertice, compute distance to the plane
+                vertex_t* s = ivl[ic-1];
+                GLfixed sd = frustumPlaneDist(plane, s->clip);
+                // clip each vertice against this plane...
+                for (unsigned int i=0 ; i<ic ; i++) {            
+                    vertex_t* p = ivl[i];
+                    const GLfixed pd = frustumPlaneDist(plane, p->clip);
+                    if (sd >= 0) {
+                        if (pd >= 0) {
+                            // both inside
+                            *output++ = p;
+                            oc++;
+                        } else {
+                            // s inside, p outside (exiting)
+                            const GLfixed t = clipDivide(sd, sd-pd);
+                            c->arrays.clipVertex(c, buf, t, p, s);
+                            *output++ = buf++;
+                            oc++;
+                            if (++sentinel >= 3)
+                                return; // non-convex polygon!
+                        }
+                    } else {
+                        if (pd >= 0) {
+                            // s outside (entering)
+                            if (pd) {
+                                const GLfixed t = clipDivide(pd, pd-sd);
+                                c->arrays.clipVertex(c, buf, t, s, p);
+                                *output++ = buf++;
+                                oc++;
+                                if (++sentinel >= 3)
+                                    return; // non-convex polygon!
+                            }
+                            *output++ = p;
+                            oc++;
+                        } else {
+                           // both outside
+                        }
+                    }
+                    s = p;
+                    sd = pd;
+                }
+                // output list become the new input list
+                if (oc<3)
+                    return; // less than 3 vertices left? we're done!
+                ivl = ovl;
+                ic = oc;
+                outi = 1-outi;
+            }
+            cc >>= 1;
+            plane++;
+        } while (cc);
+    }
+    
+    // finally we can render our triangles...
+    p0 = ivl[0];
+    p1 = ivl[1];
+    for (unsigned int i=2 ; i<ic ; i++) {
+        p2 = ivl[i];
+        c->lerp.initTriangle(p0, p1, p2);
+        if (cull_triangle(c, p0, p1, p2)) {
+            p1 = p2;
+            continue; // culled!
+        }
+        triangle(c, p0, p1, p2);
+        p1 = p2;
+    }
+}
+
+unsigned int clip_line(ogles_context_t* c, vertex_t* s, vertex_t* p)
+{
+    const uint32_t all_cc = (s->flags | p->flags) & vertex_t::CLIP_ALL;
+
+    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
+    {
+        unsigned int plane = 0;
+        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
+        do {
+            if (cc & 1) {
+                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
+                const GLfixed sd = dot4(equation.v, s->eye.v);
+                const GLfixed pd = dot4(equation.v, p->eye.v);
+                if (sd >= 0) {
+                    if (pd >= 0) {
+                        // both inside
+                    } else {
+                        // s inside, p outside (exiting)
+                        const GLfixed t = clipDivide(sd, sd-pd);
+                        c->arrays.clipEye(c, p, t, p, s);
+                    }
+                } else {
+                    if (pd >= 0) {
+                        // s outside (entering)
+                        if (pd) {
+                            const GLfixed t = clipDivide(pd, pd-sd);
+                            c->arrays.clipEye(c, s, t, s, p);
+                        }
+                    } else {
+                       // both outside
+                       return 0;
+                    }
+                }
+            }
+            cc >>= 1;
+            plane++;
+        } while (cc);
+    }
+
+    // frustum clip-planes
+    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
+    {
+        unsigned int plane = 0;
+        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
+        do {
+            if (cc & 1) {
+                const GLfixed sd = frustumPlaneDist(plane, s->clip);
+                const GLfixed pd = frustumPlaneDist(plane, p->clip);
+                if (sd >= 0) {
+                    if (pd >= 0) {
+                        // both inside
+                    } else {
+                        // s inside, p outside (exiting)
+                        const GLfixed t = clipDivide(sd, sd-pd);
+                        c->arrays.clipVertex(c, p, t, p, s);
+                    }
+                } else {
+                    if (pd >= 0) {
+                        // s outside (entering)
+                        if (pd) {
+                            const GLfixed t = clipDivide(pd, pd-sd);
+                            c->arrays.clipVertex(c, s, t, s, p);
+                        }
+                    } else {
+                       // both outside
+                       return 0;
+                    }
+                }
+            }
+            cc >>= 1;
+            plane++;
+        } while (cc);
+    }
+
+    return 2;
+}
+
+
+}; // namespace android
diff --git a/opengl/libagl/primitives.h b/opengl/libagl/primitives.h
new file mode 100644
index 0000000..1bef604
--- /dev/null
+++ b/opengl/libagl/primitives.h
@@ -0,0 +1,37 @@
+/* libs/opengles/primitives.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_PRIMITIVES_H
+#define ANDROID_OPENGLES_PRIMITIVES_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+
+namespace android {
+
+namespace gl {
+struct ogles_context_t;
+};
+
+void ogles_validate_primitives(ogles_context_t* c);
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_PRIMITIVES_H
+
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
new file mode 100644
index 0000000..c2f9f12
--- /dev/null
+++ b/opengl/libagl/state.cpp
@@ -0,0 +1,592 @@
+/* libs/opengles/state.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 "context.h"
+#include "fp.h"
+#include "state.h"
+#include "array.h"
+#include "matrix.h"
+#include "vertex.h"
+#include "light.h"
+#include "texture.h"
+#include "BufferObjectManager.h"
+#include "TextureObjectManager.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static char const * const gVendorString     = "Android";
+static char const * const gRendererString   = "Android PixelFlinger 1.0";
+static char const * const gVersionString    = "OpenGL ES-CM 1.0";
+static char const * const gExtensionsString =
+    "GL_OES_byte_coordinates "              // OK
+    "GL_OES_fixed_point "                   // OK
+    "GL_OES_single_precision "              // OK
+    "GL_OES_read_format "                   // OK
+    "GL_OES_compressed_paletted_texture "   // OK
+    "GL_OES_draw_texture "                  // OK
+    "GL_OES_matrix_get "                    // OK
+    "GL_OES_query_matrix "                  // OK
+    //        "GL_OES_point_size_array "              // TODO
+    //        "GL_OES_point_sprite "                  // TODO
+    "GL_ARB_texture_compression "           // OK
+    "GL_ARB_texture_non_power_of_two "      // OK
+    "GL_ANDROID_direct_texture "            // OK
+    "GL_ANDROID_user_clip_plane "           // OK
+    "GL_ANDROID_vertex_buffer_object "      // OK
+    "GL_ANDROID_generate_mipmap "           // OK
+    ;
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+ogles_context_t *ogles_init(size_t extra)
+{
+    void* const base = malloc(extra + sizeof(ogles_context_t) + 32);
+	if (!base) return 0;
+
+    ogles_context_t *c =
+            (ogles_context_t *)((ptrdiff_t(base) + extra + 31) & ~0x1FL);
+    memset(c, 0, sizeof(ogles_context_t));
+    ggl_init_context(&(c->rasterizer));
+    
+    // XXX: this should be passed as an argument
+    sp<EGLSurfaceManager> smgr(new EGLSurfaceManager());
+    c->surfaceManager = smgr.get();
+    c->surfaceManager->incStrong(c);
+
+    sp<EGLBufferObjectManager> bomgr(new EGLBufferObjectManager());
+    c->bufferObjectManager = bomgr.get();
+    c->bufferObjectManager->incStrong(c);
+
+    ogles_init_array(c);
+    ogles_init_matrix(c);
+    ogles_init_vertex(c);
+    ogles_init_light(c);
+    ogles_init_texture(c);
+
+    c->rasterizer.base = base;
+    c->point.size = TRI_ONE;
+    c->line.width = TRI_ONE;
+            
+    // in OpenGL, writing to the depth buffer is enabled by default.
+    c->rasterizer.procs.depthMask(c, 1);
+    
+    // OpenGL enables dithering by default
+    c->rasterizer.procs.enable(c, GL_DITHER);
+
+    return c;
+}
+
+void ogles_uninit(ogles_context_t* c)
+{
+    ogles_uninit_array(c);
+    ogles_uninit_matrix(c);
+    ogles_uninit_vertex(c);
+    ogles_uninit_light(c);
+    ogles_uninit_texture(c);
+    c->surfaceManager->decStrong(c);
+    c->bufferObjectManager->decStrong(c);
+    ggl_uninit_context(&(c->rasterizer));
+	free(c->rasterizer.base);
+}
+
+void _ogles_error(ogles_context_t* c, GLenum error)
+{
+    if (c->error == GL_NO_ERROR)
+        c->error = error;
+}
+
+static bool stencilop_valid(GLenum op) {
+    switch (op) {
+    case GL_KEEP:
+    case GL_ZERO:
+    case GL_REPLACE:
+    case GL_INCR:
+    case GL_DECR:
+    case GL_INVERT:
+        return true;
+    }
+    return false;
+}
+
+static void enable_disable(ogles_context_t* c, GLenum cap, int enabled)
+{
+    if ((cap >= GL_LIGHT0) && (cap<GL_LIGHT0+OGLES_MAX_LIGHTS)) {
+        c->lighting.lights[cap-GL_LIGHT0].enable = enabled;
+        c->lighting.enabledLights &= ~(1<<(cap-GL_LIGHT0));
+        c->lighting.enabledLights |= (enabled<<(cap-GL_LIGHT0));
+        return;
+    }
+
+    switch (cap) {
+    case GL_POINT_SMOOTH:
+        c->point.smooth = enabled;
+        break;
+    case GL_LINE_SMOOTH:
+        c->line.smooth = enabled;
+        break;
+    case GL_POLYGON_OFFSET_FILL:
+        c->polygonOffset.enable = enabled;
+        break;
+    case GL_CULL_FACE:
+        c->cull.enable = enabled;
+        break;
+    case GL_LIGHTING:
+        c->lighting.enable = enabled;
+        break;
+    case GL_COLOR_MATERIAL:
+        c->lighting.colorMaterial.enable = enabled;
+        break;
+    case GL_NORMALIZE:
+    case GL_RESCALE_NORMAL:
+        c->transforms.rescaleNormals = enabled ? cap : 0;
+        // XXX: invalidate mvit
+        break;
+
+    case GL_CLIP_PLANE0:
+    case GL_CLIP_PLANE1:
+    case GL_CLIP_PLANE2:
+    case GL_CLIP_PLANE3:
+    case GL_CLIP_PLANE4:
+    case GL_CLIP_PLANE5:
+        c->clipPlanes.enable &= ~(1<<(cap-GL_CLIP_PLANE0));
+        c->clipPlanes.enable |= (enabled<<(cap-GL_CLIP_PLANE0));
+        ogles_invalidate_perspective(c);
+        break;
+
+    case GL_FOG:
+    case GL_DEPTH_TEST:
+        ogles_invalidate_perspective(c);
+        // fall-through...
+    case GL_BLEND:
+    case GL_SCISSOR_TEST:
+    case GL_ALPHA_TEST:
+    case GL_COLOR_LOGIC_OP:
+    case GL_DITHER:
+    case GL_STENCIL_TEST:
+    case GL_TEXTURE_2D:
+        // these need to fall through into the rasterizer
+        c->rasterizer.procs.enableDisable(c, cap, enabled);
+        break;
+        
+    case GL_MULTISAMPLE:
+    case GL_SAMPLE_ALPHA_TO_COVERAGE:
+    case GL_SAMPLE_ALPHA_TO_ONE:
+    case GL_SAMPLE_COVERAGE:
+        // not supported in this implementation
+        break;
+
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+using namespace android;
+
+#if 0
+#pragma mark -
+#endif
+
+// These ones are super-easy, we're not supporting those features!
+void glSampleCoverage(GLclampf value, GLboolean invert) {
+}
+void glSampleCoveragex(GLclampx value, GLboolean invert) {
+}
+void glStencilFunc(GLenum func, GLint ref, GLuint mask) {
+    ogles_context_t* c = ogles_context_t::get();
+    if (func < GL_NEVER || func > GL_ALWAYS) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    // from OpenGL|ES 1.0 sepcification:
+    // If there is no stencil buffer, no stencil modification can occur
+    // and it is as if the stencil test always passes.
+}
+
+void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
+    ogles_context_t* c = ogles_context_t::get();
+    if ((stencilop_valid(fail) &
+         stencilop_valid(zfail) &
+         stencilop_valid(zpass)) == 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+void glAlphaFunc(GLenum func, GLclampf ref)
+{
+    glAlphaFuncx(func, gglFloatToFixed(ref));
+}
+
+void glCullFace(GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (mode) {
+    case GL_FRONT:
+    case GL_BACK:
+    case GL_FRONT_AND_BACK:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+    }
+    c->cull.cullFace = mode;
+}
+
+void glFrontFace(GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (mode) {
+    case GL_CW:
+    case GL_CCW:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->cull.frontFace = mode;
+}
+
+void glHint(GLenum target, GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (target) {
+    case GL_FOG_HINT:
+    case GL_GENERATE_MIPMAP_HINT:
+    case GL_LINE_SMOOTH_HINT:
+        break;
+    case GL_POINT_SMOOTH_HINT:
+        c->rasterizer.procs.enableDisable(c, 
+                GGL_POINT_SMOOTH_NICE, mode==GL_NICEST);
+        break;
+    case GL_PERSPECTIVE_CORRECTION_HINT:
+        c->perspective = (mode == GL_NICEST) ? 1 : 0;
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+    }
+}
+
+void glEnable(GLenum cap) {
+    ogles_context_t* c = ogles_context_t::get();
+    enable_disable(c, cap, 1);
+}
+void glDisable(GLenum cap) {
+    ogles_context_t* c = ogles_context_t::get();
+    enable_disable(c, cap, 0);
+}
+
+void glFinish()
+{ // nothing to do for our software implementation
+}
+
+void glFlush()
+{ // nothing to do for our software implementation
+}
+
+GLenum glGetError()
+{
+    // From OpenGL|ES 1.0 specification:
+    // If more than one flag has recorded an error, glGetError returns
+    // and clears an arbitrary error flag value. Thus, glGetError should
+    // always be called in a loop, until it returns GL_NO_ERROR,
+    // if all error flags are to be reset.
+
+    ogles_context_t* c = ogles_context_t::get();
+    if (c->error) {
+        const GLenum ret(c->error);
+        c->error = 0;
+        return ret;
+    }
+    
+    if (c->rasterizer.error) {
+        const GLenum ret(c->rasterizer.error);
+        c->rasterizer.error = 0;
+        return ret;
+    }
+
+    return GL_NO_ERROR;
+}
+
+const GLubyte* glGetString(GLenum string)
+{
+    switch (string) {
+    case GL_VENDOR:     return (const GLubyte*)gVendorString;
+    case GL_RENDERER:   return (const GLubyte*)gRendererString;
+    case GL_VERSION:    return (const GLubyte*)gVersionString;
+    case GL_EXTENSIONS: return (const GLubyte*)gExtensionsString;
+    }
+    ogles_context_t* c = ogles_context_t::get();
+    ogles_error(c, GL_INVALID_ENUM);
+    return 0;
+}
+
+void glGetIntegerv(GLenum pname, GLint *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (pname) {
+    case GL_ALIASED_POINT_SIZE_RANGE:
+        params[0] = 0;
+        params[1] = GGL_MAX_ALIASED_POINT_SIZE;
+        break;
+    case GL_ALIASED_LINE_WIDTH_RANGE:
+        params[0] = 0;
+        params[1] = GGL_MAX_ALIASED_POINT_SIZE;
+        break;
+    case GL_ALPHA_BITS: {
+        int index = c->rasterizer.state.buffers.color.format;
+        GGLFormat const * formats = gglGetPixelFormatTable();
+        params[0] = formats[index].ah - formats[index].al;
+        break; 
+        }
+    case GL_RED_BITS: {
+        int index = c->rasterizer.state.buffers.color.format;
+        GGLFormat const * formats = gglGetPixelFormatTable();
+        params[0] = formats[index].rh - formats[index].rl;
+        break; 
+        }
+    case GL_GREEN_BITS: {
+        int index = c->rasterizer.state.buffers.color.format;
+        GGLFormat const * formats = gglGetPixelFormatTable();
+        params[0] = formats[index].gh - formats[index].gl;
+        break; 
+        }
+    case GL_BLUE_BITS: {
+        int index = c->rasterizer.state.buffers.color.format;
+        GGLFormat const * formats = gglGetPixelFormatTable();
+        params[0] = formats[index].bh - formats[index].bl;
+        break; 
+        }
+    case GL_COMPRESSED_TEXTURE_FORMATS:
+        params[ 0] = GL_PALETTE4_RGB8_OES;
+        params[ 1] = GL_PALETTE4_RGBA8_OES;
+        params[ 2] = GL_PALETTE4_R5_G6_B5_OES;
+        params[ 3] = GL_PALETTE4_RGBA4_OES;
+        params[ 4] = GL_PALETTE4_RGB5_A1_OES;
+        params[ 5] = GL_PALETTE8_RGB8_OES;
+        params[ 6] = GL_PALETTE8_RGBA8_OES;
+        params[ 7] = GL_PALETTE8_R5_G6_B5_OES;
+        params[ 8] = GL_PALETTE8_RGBA4_OES;
+        params[ 9] = GL_PALETTE8_RGB5_A1_OES;
+        break;
+    case GL_DEPTH_BITS:
+        params[0] = c->rasterizer.state.buffers.depth.format ? 0 : 16;
+        break;
+    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+        params[0] = GL_RGB;
+        break;
+    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+        params[0] = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case GL_MAX_ELEMENTS_INDICES:
+        params[0] = 65536;
+        break;
+    case GL_MAX_ELEMENTS_VERTICES:
+        params[0] = 0x7FFFFFFF;
+        break;
+    case GL_MAX_LIGHTS:
+        params[0] = OGLES_MAX_LIGHTS;
+        break;
+    case GL_MAX_CLIP_PLANES:
+        params[0] = OGLES_MAX_CLIP_PLANES;
+        break;
+    case GL_MAX_MODELVIEW_STACK_DEPTH:
+        params[0] = OGLES_MODELVIEW_STACK_DEPTH;
+        break;
+    case GL_MAX_PROJECTION_STACK_DEPTH:
+        params[0] = OGLES_PROJECTION_STACK_DEPTH;
+        break;
+    case GL_MAX_TEXTURE_STACK_DEPTH:
+        params[0] = OGLES_TEXTURE_STACK_DEPTH;
+        break;
+    case GL_MAX_TEXTURE_SIZE:
+        params[0] = GGL_MAX_TEXTURE_SIZE;
+        break;
+    case GL_MAX_TEXTURE_UNITS:
+        params[0] = GGL_TEXTURE_UNIT_COUNT;
+        break;
+    case GL_MAX_VIEWPORT_DIMS:
+        params[0] = GGL_MAX_VIEWPORT_DIMS;
+        params[1] = GGL_MAX_VIEWPORT_DIMS;
+        break;
+    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+        params[0] = OGLES_NUM_COMPRESSED_TEXTURE_FORMATS;
+        break;
+    case GL_SMOOTH_LINE_WIDTH_RANGE:
+        params[0] = 0;
+        params[1] = GGL_MAX_SMOOTH_LINE_WIDTH;
+        break;
+    case GL_SMOOTH_POINT_SIZE_RANGE:
+        params[0] = 0;
+        params[1] = GGL_MAX_SMOOTH_POINT_SIZE;
+        break;
+    case GL_STENCIL_BITS:
+        params[0] = 0;
+        break;
+    case GL_SUBPIXEL_BITS:
+        params[0] = GGL_SUBPIXEL_BITS;
+        break;
+
+    case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES:
+        memcpy( params,
+                c->transforms.modelview.top().elements(),
+                16*sizeof(GLint));
+        break;
+    case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES:
+        memcpy( params,
+                c->transforms.projection.top().elements(),
+                16*sizeof(GLint));
+        break;
+    case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES:
+        memcpy( params,
+                c->transforms.texture[c->textures.active].top().elements(),
+                16*sizeof(GLint));
+        break;
+
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        break;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+void glPointSize(GLfloat size)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (size <= 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->point.size = TRI_FROM_FIXED(gglFloatToFixed(size));
+}
+
+void glPointSizex(GLfixed size)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (size <= 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->point.size = TRI_FROM_FIXED(size);
+}
+
+// ----------------------------------------------------------------------------
+
+void glLineWidth(GLfloat width)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (width <= 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->line.width = TRI_FROM_FIXED(gglFloatToFixed(width));
+}
+
+void glLineWidthx(GLfixed width)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (width <= 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->line.width = TRI_FROM_FIXED(width);
+}
+
+// ----------------------------------------------------------------------------
+
+void glColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.colorMask(c, r, g, b, a);
+}
+
+void glDepthMask(GLboolean flag) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.depthMask(c, flag);
+}
+
+void glStencilMask(GLuint mask) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.stencilMask(c, mask);
+}
+
+void glDepthFunc(GLenum func) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.depthFunc(c, func);
+}
+
+void glLogicOp(GLenum opcode) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.logicOp(c, opcode);
+}
+
+void glAlphaFuncx(GLenum func, GLclampx ref) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.alphaFuncx(c, func, ref);
+}
+
+void glBlendFunc(GLenum sfactor, GLenum dfactor) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.blendFunc(c, sfactor, dfactor);
+}
+
+void glClear(GLbitfield mask) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clear(c, mask);
+}
+
+void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearColorx(c, red, green, blue, alpha);
+}
+
+void glClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearColorx(c,
+                    gglFloatToFixed(r),
+                    gglFloatToFixed(g),
+                    gglFloatToFixed(b),
+                    gglFloatToFixed(a));
+}
+
+void glClearDepthx(GLclampx depth) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearDepthx(c, depth);
+}
+
+void glClearDepthf(GLclampf depth)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearDepthx(c, gglFloatToFixed(depth));
+}
+
+void glClearStencil(GLint s) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearStencil(c, s);
+}
diff --git a/opengl/libagl/state.h b/opengl/libagl/state.h
new file mode 100644
index 0000000..55a5ccb
--- /dev/null
+++ b/opengl/libagl/state.h
@@ -0,0 +1,54 @@
+/* libs/opengles/state.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_STATE_H
+#define ANDROID_OPENGLES_STATE_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+#include <stdio.h>
+
+namespace android {
+
+ogles_context_t *ogles_init(size_t extra);
+void ogles_uninit(ogles_context_t* c);
+void _ogles_error(ogles_context_t* c, GLenum error);
+
+#ifndef TRACE_GL_ERRORS
+#define TRACE_GL_ERRORS 0
+#endif
+
+#if TRACE_GL_ERRORS
+#define ogles_error(c, error) \
+do { \
+  printf("ogles_error at file %s line %d\n", __FILE__, __LINE__); \
+  _ogles_error(c, error); \
+} while (0)
+#else /* !TRACE_GL_ERRORS */
+#define ogles_error(c, error) _ogles_error((c), (error))
+#endif
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_STATE_H
+
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
new file mode 100644
index 0000000..6b2640a
--- /dev/null
+++ b/opengl/libagl/texture.cpp
@@ -0,0 +1,1423 @@
+/* libs/opengles/texture.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 <stdlib.h>
+#include "context.h"
+#include "fp.h"
+#include "state.h"
+#include "texture.h"
+#include "TextureObjectManager.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static void bindTextureTmu(
+    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex);
+
+static __attribute__((noinline))
+void generateMipmap(ogles_context_t* c, GLint level);
+
+// ----------------------------------------------------------------------------
+
+#if 0
+#pragma mark -
+#pragma mark Init
+#endif
+
+void ogles_init_texture(ogles_context_t* c)
+{
+    c->textures.packAlignment   = 4;
+    c->textures.unpackAlignment = 4;
+
+    // each context has a default named (0) texture (not shared)
+    c->textures.defaultTexture = new EGLTextureObject();
+    c->textures.defaultTexture->incStrong(c);
+    
+    // bind the default texture to each texture unit
+    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        bindTextureTmu(c, i, 0, c->textures.defaultTexture);
+        memset(c->current.texture[i].v, 0, sizeof(vec4_t));
+        c->current.texture[i].Q = 0x10000;
+    }
+}
+
+void ogles_uninit_texture(ogles_context_t* c)
+{
+    if (c->textures.ggl)
+        gglUninit(c->textures.ggl);
+    c->textures.defaultTexture->decStrong(c);
+    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (c->textures.tmu[i].texture)
+            c->textures.tmu[i].texture->decStrong(c);
+    }
+}
+
+static __attribute__((noinline))
+void validate_tmu(ogles_context_t* c, int i)
+{
+    texture_unit_t& u(c->textures.tmu[i]);
+    if (u.dirty) {
+        u.dirty = 0;
+        c->rasterizer.procs.activeTexture(c, i);
+        c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
+        c->rasterizer.procs.texGeni(c, GGL_S,
+                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
+        c->rasterizer.procs.texGeni(c, GGL_T,
+                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
+        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                GGL_TEXTURE_WRAP_S, u.texture->wraps);
+        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                GGL_TEXTURE_WRAP_T, u.texture->wrapt);
+        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
+        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
+
+        // disable this texture unit if it's not complete
+        if (!u.texture->isComplete()) {
+            c->rasterizer.procs.disable(c, GGL_TEXTURE_2D);
+        }
+    }
+}
+
+void ogles_validate_texture_impl(ogles_context_t* c)
+{
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (c->rasterizer.state.texture[i].enable)
+            validate_tmu(c, i);
+    }
+    c->rasterizer.procs.activeTexture(c, c->textures.active);
+}
+
+static
+void invalidate_texture(ogles_context_t* c, int tmu, uint8_t flags = 0xFF) {
+    c->textures.tmu[tmu].dirty = flags;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Format conversion
+#endif
+
+static uint32_t gl2format_table[6][4] = {
+    // BYTE, 565, 4444, 5551
+    { GGL_PIXEL_FORMAT_A_8,
+      0, 0, 0 },                        // GL_ALPHA
+    { GGL_PIXEL_FORMAT_RGB_888,
+      GGL_PIXEL_FORMAT_RGB_565,
+      0, 0 },                           // GL_RGB
+    { GGL_PIXEL_FORMAT_RGBA_8888,
+      0,
+      GGL_PIXEL_FORMAT_RGBA_4444,
+      GGL_PIXEL_FORMAT_RGBA_5551 },     // GL_RGBA
+    { GGL_PIXEL_FORMAT_L_8,
+      0, 0, 0 },                        // GL_LUMINANCE
+    { GGL_PIXEL_FORMAT_LA_88,
+      0, 0, 0 },                        // GL_LUMINANCE_ALPHA
+};
+
+static int32_t convertGLPixelFormat(GLint format, GLenum type)
+{
+    int32_t fi = -1;
+    int32_t ti = -1;
+    switch (format) {
+    case GL_ALPHA:              fi = 0;     break;
+    case GL_RGB:                fi = 1;     break;
+    case GL_RGBA:               fi = 2;     break;
+    case GL_LUMINANCE:          fi = 3;     break;
+    case GL_LUMINANCE_ALPHA:    fi = 4;     break;
+    }
+    switch (type) {
+    case GL_UNSIGNED_BYTE:          ti = 0; break;
+    case GL_UNSIGNED_SHORT_5_6_5:   ti = 1; break;
+    case GL_UNSIGNED_SHORT_4_4_4_4: ti = 2; break;
+    case GL_UNSIGNED_SHORT_5_5_5_1: ti = 3; break;
+    }
+    if (fi==-1 || ti==-1)
+        return 0;
+    return gl2format_table[fi][ti];
+}
+
+// ----------------------------------------------------------------------------
+
+static GLenum validFormatType(ogles_context_t* c, GLenum format, GLenum type)
+{
+    GLenum error = 0;
+    if (format<GL_ALPHA || format>GL_LUMINANCE_ALPHA) {
+        error = GL_INVALID_ENUM;
+    }
+    if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT_4_4_4_4 &&
+        type != GL_UNSIGNED_SHORT_5_5_5_1 && type != GL_UNSIGNED_SHORT_5_6_5) {
+        error = GL_INVALID_ENUM;
+    }
+    if (type == GL_UNSIGNED_SHORT_5_6_5 && format != GL_RGB) {
+        error = GL_INVALID_OPERATION;
+    }
+    if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
+         type == GL_UNSIGNED_SHORT_5_5_5_1)  && format != GL_RGBA) {
+        error = GL_INVALID_OPERATION;
+    }
+    if (error) {
+        ogles_error(c, error);
+    }
+    return error;
+}
+
+// ----------------------------------------------------------------------------
+
+GGLContext* getRasterizer(ogles_context_t* c)
+{
+    GGLContext* ggl = c->textures.ggl;
+    if (ggl_unlikely(!ggl)) {
+        // this is quite heavy the first time...
+        gglInit(&ggl);
+        if (!ggl) {
+            return 0;
+        }
+        GGLfixed colors[4] = { 0, 0, 0, 0x10000 };
+        c->textures.ggl = ggl;
+        ggl->activeTexture(ggl, 0);
+        ggl->enable(ggl, GGL_TEXTURE_2D);
+        ggl->texEnvi(ggl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
+        ggl->disable(ggl, GGL_DITHER);
+        ggl->shadeModel(ggl, GGL_FLAT);
+        ggl->color4xv(ggl, colors);
+    }
+    return ggl;
+}
+
+static __attribute__((noinline))
+int copyPixels(
+        ogles_context_t* c,
+        const GGLSurface& dst,
+        GLint xoffset, GLint yoffset,
+        const GGLSurface& src,
+        GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    if ((dst.format == src.format) &&
+        (dst.stride == src.stride) &&
+        (dst.width == src.width) &&
+        (dst.height == src.height) &&
+        (dst.stride > 0) &&
+        ((x|y) == 0) &&
+        ((xoffset|yoffset) == 0))
+    {
+        // this is a common case...
+        const GGLFormat& pixelFormat(c->rasterizer.formats[src.format]);
+        const size_t size = src.height * src.stride * pixelFormat.size;
+        memcpy(dst.data, src.data, size);
+        return 0;
+    }
+
+    // use pixel-flinger to handle all the conversions
+    GGLContext* ggl = getRasterizer(c);
+    if (!ggl) {
+        // the only reason this would fail is because we ran out of memory
+        return GL_OUT_OF_MEMORY;
+    }
+
+    ggl->colorBuffer(ggl, &dst);
+    ggl->bindTexture(ggl, &src);
+    ggl->texCoord2i(ggl, x-xoffset, y-yoffset);
+    ggl->recti(ggl, xoffset, yoffset, xoffset+w, yoffset+h);
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+static __attribute__((noinline))
+sp<EGLTextureObject> getAndBindActiveTextureObject(ogles_context_t* c)
+{
+    sp<EGLTextureObject> tex;
+    const int active = c->textures.active;
+    const GLuint name = c->textures.tmu[active].name;
+
+    // free the reference to the previously bound object
+    texture_unit_t& u(c->textures.tmu[active]);
+    if (u.texture)
+        u.texture->decStrong(c);
+
+    if (name == 0) {
+        // 0 is our local texture object, not shared with anyone. 
+        // But it affects all bound TMUs immediately.
+        // (we need to invalidate all units bound to this texture object)
+        tex = c->textures.defaultTexture;
+        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+            if (c->textures.tmu[i].texture == tex.get())
+                invalidate_texture(c, i);
+        }
+    } else {
+        // get a new texture object for that name
+        tex = c->surfaceManager->replaceTexture(name);
+    }
+
+    // bind this texture to the current active texture unit
+    // and add a reference to this texture object
+    u.texture = tex.get();
+    u.texture->incStrong(c);
+    u.name = name;
+    invalidate_texture(c, active);    
+    return tex;
+}
+
+void bindTextureTmu(
+    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex)
+{
+    if (tex.get() == c->textures.tmu[tmu].texture)
+        return;
+    
+    // free the reference to the previously bound object
+    texture_unit_t& u(c->textures.tmu[tmu]);
+    if (u.texture)
+        u.texture->decStrong(c);
+
+    // bind this texture to the current active texture unit
+    // and add a reference to this texture object
+    u.texture = tex.get();
+    u.texture->incStrong(c);
+    u.name = texture;
+    invalidate_texture(c, tmu);
+}
+
+int createTextureSurface(ogles_context_t* c,
+        GGLSurface** outSurface, int32_t* outSize, GLint level,
+        GLenum format, GLenum type, GLsizei width, GLsizei height,
+        GLenum compressedFormat = 0)
+{
+    // find out which texture is bound to the current unit
+    const int active = c->textures.active;
+    const GLuint name = c->textures.tmu[active].name;
+
+    // convert the pixelformat to one we can handle
+    const int32_t formatIdx = convertGLPixelFormat(format, type);
+    if (formatIdx == 0) { // we don't know what to do with this
+        return GL_INVALID_OPERATION;
+    }
+    
+    // figure out the size we need as well as the stride
+    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
+    const int32_t align = c->textures.unpackAlignment-1;
+    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
+    const size_t size = bpr * height;
+    const int32_t stride = bpr / pixelFormat.size;
+
+    if (level > 0) {
+        const int active = c->textures.active;
+        EGLTextureObject* tex = c->textures.tmu[active].texture;
+        status_t err = tex->reallocate(level,
+                width, height, stride, formatIdx, compressedFormat, bpr);
+        if (err != NO_ERROR)
+            return GL_OUT_OF_MEMORY;
+        GGLSurface& surface = tex->editMip(level);
+        *outSurface = &surface;
+        *outSize = size;
+        return 0;
+    }
+
+    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
+    status_t err = tex->reallocate(level,
+            width, height, stride, formatIdx, compressedFormat, bpr);
+    if (err != NO_ERROR)
+        return GL_OUT_OF_MEMORY;
+
+    tex->internalformat = format;
+    *outSurface = &tex->surface;
+    *outSize = size;
+    return 0;
+}
+
+static void decodePalette4(const GLvoid *data, int level, int width, int height,
+                           void *surface, int stride, int format)
+
+{
+    int indexBits = 8;
+    int entrySize = 0;
+    switch (format) {
+    case GL_PALETTE4_RGB8_OES:
+        indexBits = 4;
+        /* FALLTHROUGH */
+    case GL_PALETTE8_RGB8_OES:
+        entrySize = 3;
+        break;
+
+    case GL_PALETTE4_RGBA8_OES:
+        indexBits = 4;
+        /* FALLTHROUGH */
+    case GL_PALETTE8_RGBA8_OES:
+        entrySize = 4;
+        break;
+
+    case GL_PALETTE4_R5_G6_B5_OES:
+    case GL_PALETTE4_RGBA4_OES:
+    case GL_PALETTE4_RGB5_A1_OES:
+        indexBits = 4;
+        /* FALLTHROUGH */
+    case GL_PALETTE8_R5_G6_B5_OES:
+    case GL_PALETTE8_RGBA4_OES:
+    case GL_PALETTE8_RGB5_A1_OES:
+        entrySize = 2;
+        break;
+    }
+
+    const int paletteSize = (1 << indexBits) * entrySize;
+    uint8_t const* pixels = (uint8_t *)data + paletteSize;
+    for (int i=0 ; i<level ; i++) {
+        int w = (width  >> i) ? : 1;
+        int h = (height >> i) ? : 1;
+        pixels += h * ((w * indexBits) / 8);
+    }
+    width  = (width  >> level) ? : 1;
+    height = (height >> level) ? : 1;
+
+    if (entrySize == 2) {
+        uint8_t const* const palette = (uint8_t*)data;
+        for (int y=0 ; y<height ; y++) {
+            uint8_t* p = (uint8_t*)surface + y*stride*2;
+            if (indexBits == 8) {
+                for (int x=0 ; x<width ; x++) {
+                    int index = 2 * (*pixels++);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                }
+            } else {
+                for (int x=0 ; x<width ; x+=2) {
+                    int v = *pixels++;
+                    int index = 2 * (v >> 4);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    if (x+1 < width) {
+                        index = 2 * (v & 0xF);
+                        *p++ = palette[index + 0];
+                        *p++ = palette[index + 1];
+                    }
+                }
+            }
+        }
+    } else if (entrySize == 3) {
+        uint8_t const* const palette = (uint8_t*)data;
+        for (int y=0 ; y<height ; y++) {
+            uint8_t* p = (uint8_t*)surface + y*stride*3;
+            if (indexBits == 8) {
+                for (int x=0 ; x<width ; x++) {
+                    int index = 3 * (*pixels++);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    *p++ = palette[index + 2];
+                }
+            } else {
+                for (int x=0 ; x<width ; x+=2) {
+                    int v = *pixels++;
+                    int index = 3 * (v >> 4);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    *p++ = palette[index + 2];
+                    if (x+1 < width) {
+                        index = 3 * (v & 0xF);
+                        *p++ = palette[index + 0];
+                        *p++ = palette[index + 1];
+                        *p++ = palette[index + 2];
+                    }
+                }
+            }
+        }
+    } else if (entrySize == 4) {
+        uint8_t const* const palette = (uint8_t*)data;
+        for (int y=0 ; y<height ; y++) {
+            uint8_t* p = (uint8_t*)surface + y*stride*4;
+            if (indexBits == 8) {
+                for (int x=0 ; x<width ; x++) {
+                    int index = 4 * (*pixels++);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    *p++ = palette[index + 2];
+                    *p++ = palette[index + 3];
+                }
+            } else {
+                for (int x=0 ; x<width ; x+=2) {
+                    int v = *pixels++;
+                    int index = 4 * (v >> 4);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    *p++ = palette[index + 2];
+                    *p++ = palette[index + 3];
+                    if (x+1 < width) {
+                        index = 4 * (v & 0xF);
+                        *p++ = palette[index + 0];
+                        *p++ = palette[index + 1];
+                        *p++ = palette[index + 2];
+                        *p++ = palette[index + 3];
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+
+static __attribute__((noinline))
+void set_depth_and_fog(ogles_context_t* c, GLint z)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+    // we need to compute Zw
+    int32_t iterators[3];
+    iterators[1] = iterators[2] = 0;
+    GGLfixed Zw;
+    GGLfixed n = gglFloatToFixed(c->transforms.vpt.zNear);
+    GGLfixed f = gglFloatToFixed(c->transforms.vpt.zFar);
+    if (z<=0)       Zw = n;
+    else if (z>=1)  Zw = f;
+    else            Zw = gglMulAddx(z, (f-n), n);
+    if (enables & GGL_ENABLE_FOG) {
+        // set up fog if needed...
+        iterators[0] = c->fog.fog(c, Zw);
+        c->rasterizer.procs.fogGrad3xv(c, iterators);
+    }
+    if (enables & GGL_ENABLE_DEPTH_TEST) {
+        // set up z-test if needed...
+        int32_t z = (Zw & ~(Zw>>31));
+        if (z >= 0x10000)
+            z = 0xFFFF;
+        iterators[0] = (z << 16) | z;
+        c->rasterizer.procs.zGrad3xv(c, iterators);
+    }
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Generate mimaps
+#endif
+
+extern status_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex);
+
+void generateMipmap(ogles_context_t* c, GLint level)
+{
+    if (level == 0) {
+        const int active = c->textures.active;
+        EGLTextureObject* tex = c->textures.tmu[active].texture;
+        if (tex->generate_mipmap) {
+            if (buildAPyramid(c, tex) != NO_ERROR) {
+                ogles_error(c, GL_OUT_OF_MEMORY);
+                return;
+            }
+        }
+    }
+}
+
+
+static void texParameterx(
+        GLenum target, GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    if (target != GGL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    
+    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;    
+    switch (pname) {
+    case GL_TEXTURE_WRAP_S:
+        if ((param == GL_CLAMP) ||
+            (param == GL_REPEAT) ||
+            (param == GL_CLAMP_TO_EDGE)) {
+            textureObject->wraps = param;
+        } else {
+            goto invalid_enum;
+        }
+        break;
+    case GL_TEXTURE_WRAP_T:
+        if ((param == GGL_CLAMP) ||
+            (param == GGL_REPEAT) ||
+            (param == GGL_CLAMP_TO_EDGE)) {
+            textureObject->wrapt = param;
+        } else {
+            goto invalid_enum;
+        }
+        break;
+    case GL_TEXTURE_MIN_FILTER:
+        if ((param == GL_NEAREST) ||
+            (param == GL_LINEAR) ||
+            (param == GL_NEAREST_MIPMAP_NEAREST) ||
+            (param == GL_LINEAR_MIPMAP_NEAREST) ||
+            (param == GL_NEAREST_MIPMAP_LINEAR) ||
+            (param == GL_LINEAR_MIPMAP_LINEAR)) {
+            textureObject->min_filter = param;
+        } else {
+            goto invalid_enum;
+        }
+        break;
+    case GL_TEXTURE_MAG_FILTER:
+        if ((param == GL_NEAREST) ||
+            (param == GL_LINEAR)) {
+            textureObject->mag_filter = param;
+        } else {
+            goto invalid_enum;
+        }
+        break;
+    case GL_GENERATE_MIPMAP:
+        textureObject->generate_mipmap = param;
+        break;
+    default:
+invalid_enum:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    invalidate_texture(c, c->textures.active);
+}
+
+
+static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
+        ogles_context_t* c)
+{
+    // quickly reject empty rects
+    if ((w|h) <= 0)
+        return;                
+
+    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+    y = gglIntToFixed(cbSurface.height) - (y + h);
+    w >>= FIXED_BITS;
+    h >>= FIXED_BITS;
+
+    // set up all texture units
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (!c->rasterizer.state.texture[i].enable)
+            continue;
+
+        int32_t texcoords[8];
+        texture_unit_t& u(c->textures.tmu[i]);
+
+        // validate this tmu (bind, wrap, filter)
+        validate_tmu(c, i);
+        // we CLAMP here, which works with premultiplied (s,t)
+        c->rasterizer.procs.texParameteri(c,
+                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP);
+        c->rasterizer.procs.texParameteri(c,
+                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
+        u.dirty = 0xFF; // XXX: should be more subtle
+
+        EGLTextureObject* textureObject = u.texture;  
+        const GLint Ucr = textureObject->crop_rect[0] << 16;
+        const GLint Vcr = textureObject->crop_rect[1] << 16;
+        const GLint Wcr = textureObject->crop_rect[2] << 16;
+        const GLint Hcr = textureObject->crop_rect[3] << 16;
+
+        // computes texture coordinates (pre-multiplied)
+        int32_t dsdx = Wcr / w;   // dsdx =  ((Wcr/w)/Wt)*Wt
+        int32_t dtdy =-Hcr / h;   // dtdy = -((Hcr/h)/Ht)*Ht
+        int32_t s0   = Ucr       - gglMulx(dsdx, x); // s0 = Ucr - x * dsdx
+        int32_t t0   = (Vcr+Hcr) - gglMulx(dtdy, y); // t0 = (Vcr+Hcr) - y*dtdy
+        texcoords[0] = s0;
+        texcoords[1] = dsdx;
+        texcoords[2] = 0;
+        texcoords[3] = t0;
+        texcoords[4] = 0;
+        texcoords[5] = dtdy;
+        texcoords[6] = 0;
+        texcoords[7] = 0;
+        c->rasterizer.procs.texCoordGradScale8xv(c, i, texcoords);
+    }
+
+    const uint32_t enables = c->rasterizer.state.enables;
+    if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
+        set_depth_and_fog(c, z);
+
+    c->rasterizer.procs.activeTexture(c, c->textures.active);
+    c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
+    c->rasterizer.procs.disable(c, GGL_W_LERP);
+    c->rasterizer.procs.disable(c, GGL_AA);
+    c->rasterizer.procs.shadeModel(c, GL_FLAT);
+    c->rasterizer.procs.recti(c, 
+            gglFixedToIntRound(x),
+            gglFixedToIntRound(y),
+            gglFixedToIntRound(x)+w,
+            gglFixedToIntRound(y)+h);
+}
+
+static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c)
+{
+    // All coordinates are integer, so if we have only one
+    // texture unit active and no scaling is required
+    // THEN, we can use our special 1:1 mapping
+    // which is a lot faster.
+
+    if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
+        const int tmu = 0;
+        texture_unit_t& u(c->textures.tmu[tmu]);
+        EGLTextureObject* textureObject = u.texture;  
+        const GLint Wcr = textureObject->crop_rect[2];
+        const GLint Hcr = textureObject->crop_rect[3];
+
+        if ((w == Wcr) && (h == -Hcr)) {
+            if ((w|h) <= 0) return; // quickly reject empty rects
+
+            if (u.dirty) {
+                c->rasterizer.procs.activeTexture(c, tmu);
+                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
+                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                        GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
+                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                        GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
+            }
+            c->rasterizer.procs.texGeni(c, GGL_S,
+                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
+            c->rasterizer.procs.texGeni(c, GGL_T,
+                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
+            u.dirty = 0xFF; // XXX: should be more subtle
+            c->rasterizer.procs.activeTexture(c, c->textures.active);
+            
+            const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+            y = cbSurface.height - (y + h);
+            const GLint Ucr = textureObject->crop_rect[0];
+            const GLint Vcr = textureObject->crop_rect[1];
+            const GLint s0  = Ucr - x;
+            const GLint t0  = (Vcr + Hcr) - y;
+            
+            const GLuint tw = textureObject->surface.width;
+            const GLuint th = textureObject->surface.height;
+            if ((uint32_t(s0+x+w) > tw) || (uint32_t(t0+y+h) > th)) {
+                // The GL spec is unclear about what should happen
+                // in this case, so we just use the slow case, which
+                // at least won't crash
+                goto slow_case;
+            } 
+
+            c->rasterizer.procs.texCoord2i(c, s0, t0);
+            const uint32_t enables = c->rasterizer.state.enables;
+            if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
+                set_depth_and_fog(c, z);
+
+            c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
+            c->rasterizer.procs.disable(c, GGL_W_LERP);
+            c->rasterizer.procs.disable(c, GGL_AA);
+            c->rasterizer.procs.shadeModel(c, GL_FLAT);
+            c->rasterizer.procs.recti(c, x, y, x+w, y+h);
+            return;
+        }
+    }
+
+slow_case:
+    drawTexxOES(
+            gglIntToFixed(x), gglIntToFixed(y), gglIntToFixed(z),
+            gglIntToFixed(w), gglIntToFixed(h),
+            c);
+}
+
+
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+
+#if 0
+#pragma mark -
+#pragma mark Texture API
+#endif
+
+void glActiveTexture(GLenum texture)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (uint32_t(texture-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->textures.active = texture - GL_TEXTURE0;
+    c->rasterizer.procs.activeTexture(c, c->textures.active);
+}
+
+void glBindTexture(GLenum target, GLuint texture)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    // Bind or create a texture
+    sp<EGLTextureObject> tex;    
+    if (texture == 0) {
+        // 0 is our local texture object
+        tex = c->textures.defaultTexture;
+    } else {
+        tex = c->surfaceManager->texture(texture);
+        if (ggl_unlikely(tex == 0)) {
+            tex = c->surfaceManager->createTexture(texture);
+            if (tex == 0) {
+                ogles_error(c, GL_OUT_OF_MEMORY);
+                return;
+            }
+        }
+    }
+    bindTextureTmu(c, c->textures.active, texture, tex);
+}
+
+void glGenTextures(GLsizei n, GLuint *textures)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (n<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    // generate unique (shared) texture names
+    c->surfaceManager->getToken(n, textures);
+}
+
+void glDeleteTextures(GLsizei n, const GLuint *textures)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (n<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    // If deleting a bound texture, bind this unit to 0
+    for (int t=0 ; t<GGL_TEXTURE_UNIT_COUNT ; t++) {
+        if (c->textures.tmu[t].name == 0)
+            continue;
+        for (int i=0 ; i<n ; i++) {
+            if (textures[i] && (textures[i] == c->textures.tmu[t].name)) {
+                // bind this tmu to texture 0
+                sp<EGLTextureObject> tex(c->textures.defaultTexture);
+                bindTextureTmu(c, t, 0, tex);
+            }
+        }
+    }
+    c->surfaceManager->deleteTextures(n, textures);
+    c->surfaceManager->recycleTokens(n, textures);
+}
+
+void glMultiTexCoord4f(
+        GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    const int tmu = target-GL_TEXTURE0;
+    c->current.texture[tmu].S = gglFloatToFixed(s);
+    c->current.texture[tmu].T = gglFloatToFixed(t);
+    c->current.texture[tmu].R = gglFloatToFixed(r);
+    c->current.texture[tmu].Q = gglFloatToFixed(q);
+}
+
+void glMultiTexCoord4x(
+        GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    const int tmu = target-GL_TEXTURE0;
+    c->current.texture[tmu].S = s;
+    c->current.texture[tmu].T = t;
+    c->current.texture[tmu].R = r;
+    c->current.texture[tmu].Q = q;
+}
+
+void glPixelStorei(GLenum pname, GLint param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if ((pname != GL_PACK_ALIGNMENT) && (pname != GL_UNPACK_ALIGNMENT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }    
+    if ((param<=0 || param>8) || (param & (param-1))) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (pname == GL_PACK_ALIGNMENT)
+        c->textures.packAlignment = param;
+    if (pname == GL_UNPACK_ALIGNMENT)
+        c->textures.unpackAlignment = param;
+}
+
+void glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.texEnvi(c, target, pname, GLint(param));
+}
+
+void glTexEnvfv(
+        GLenum target, GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname == GL_TEXTURE_ENV_MODE) {
+        c->rasterizer.procs.texEnvi(c, target, pname, GLint(*params));
+        return;
+    }
+    if (pname == GL_TEXTURE_ENV_COLOR) {
+        GGLfixed fixed[4];
+        for (int i=0 ; i<4 ; i++)
+            fixed[i] = gglFloatToFixed(params[i]);
+        c->rasterizer.procs.texEnvxv(c, target, pname, fixed);
+        return;
+    }
+    ogles_error(c, GL_INVALID_ENUM);
+}
+
+void glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.texEnvi(c, target, pname, param);
+}
+
+void glTexEnvxv(
+        GLenum target, GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.texEnvxv(c, target, pname, params);
+}
+
+void glTexParameteriv(
+        GLenum target, GLenum pname, const GLint* params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GGL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
+    switch (pname) {
+    case GL_TEXTURE_CROP_RECT_OES:
+        memcpy(textureObject->crop_rect, params, 4*sizeof(GLint));
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+}
+
+void glTexParameterf(
+        GLenum target, GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    texParameterx(target, pname, GLfixed(param), c);
+}
+
+void glTexParameterx(
+        GLenum target, GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    texParameterx(target, pname, param, c);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void glCompressedTexImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLsizei width, GLsizei height, GLint border,
+        GLsizei imageSize, const GLvoid *data)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if ((internalformat < GL_PALETTE4_RGB8_OES ||
+         internalformat > GL_PALETTE8_RGB5_A1_OES)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (width<0 || height<0 || border!=0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    // "uncompress" the texture since pixelflinger doesn't support
+    // any compressed texture format natively. 
+    GLenum format;
+    GLenum type;
+    switch (internalformat) {
+    case GL_PALETTE8_RGB8_OES:
+    case GL_PALETTE4_RGB8_OES:
+        format      = GL_RGB;
+        type        = GL_UNSIGNED_BYTE;
+        break;
+    case GL_PALETTE8_RGBA8_OES:
+    case GL_PALETTE4_RGBA8_OES:
+        format      = GL_RGBA;
+        type        = GL_UNSIGNED_BYTE;
+        break;
+    case GL_PALETTE8_R5_G6_B5_OES:
+    case GL_PALETTE4_R5_G6_B5_OES:
+        format      = GL_RGB;
+        type        = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case GL_PALETTE8_RGBA4_OES:
+    case GL_PALETTE4_RGBA4_OES:
+        format      = GL_RGBA;
+        type        = GL_UNSIGNED_SHORT_4_4_4_4;
+        break;
+    case GL_PALETTE8_RGB5_A1_OES:
+    case GL_PALETTE4_RGB5_A1_OES:
+        format      = GL_RGBA;
+        type        = GL_UNSIGNED_SHORT_5_5_5_1;
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    if (!data || !width || !height) {
+        // unclear if this is an error or not...
+        return;
+    }
+
+    int32_t size;
+    GGLSurface* surface;
+    // all mipmap levels are specified at once.
+    const int numLevels = level<0 ? -level : 1;
+    for (int i=0 ; i<numLevels ; i++) {
+        int lod_w = (width  >> i) ? : 1;
+        int lod_h = (height >> i) ? : 1;
+        int error = createTextureSurface(c, &surface, &size,
+                i, format, type, lod_w, lod_h);
+        if (error) {
+            ogles_error(c, error);
+            return;
+        }
+        decodePalette4(data, i, width, height,
+                surface->data, surface->stride, internalformat);
+    }
+}
+
+
+void glTexImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLsizei width, GLsizei height, GLint border,
+        GLenum format, GLenum type, const GLvoid *pixels)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D && target != GL_DIRECT_TEXTURE_2D_QUALCOMM) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (width<0 || height<0 || border!=0 || level < 0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (format != internalformat) {
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+    if (validFormatType(c, format, type)) {
+        return;
+    }
+
+    int32_t size = 0;
+    GGLSurface* surface = 0;
+    if (target != GL_DIRECT_TEXTURE_2D_QUALCOMM) {
+        int error = createTextureSurface(c, &surface, &size,
+                level, format, type, width, height);
+        if (error) {
+            ogles_error(c, error);
+            return;
+        }
+    } else if (pixels == 0 || level != 0) {
+        // pixel can't be null for direct texture
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+
+    if (pixels) {
+        const int32_t formatIdx = convertGLPixelFormat(format, type);
+        const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
+        const int32_t align = c->textures.unpackAlignment-1;
+        const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
+        const size_t size = bpr * height;
+        const int32_t stride = bpr / pixelFormat.size;
+
+        GGLSurface userSurface;
+        userSurface.version = sizeof(userSurface);
+        userSurface.width  = width;
+        userSurface.height = height;
+        userSurface.stride = stride;
+        userSurface.format = formatIdx;
+        userSurface.compressedFormat = 0;
+        userSurface.data = (GLubyte*)pixels;
+
+        if (target != GL_DIRECT_TEXTURE_2D_QUALCOMM) {
+            int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height); 
+            if (err) {
+                ogles_error(c, err);
+                return;
+            }
+            generateMipmap(c, level);
+        } else {
+            // bind it to the texture unit
+            sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
+            tex->setSurface(&userSurface);
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+void glCompressedTexSubImage2D(
+        GLenum target, GLint level, GLint xoffset,
+        GLint yoffset, GLsizei width, GLsizei height,
+        GLenum format, GLsizei imageSize,
+        const GLvoid *data)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    ogles_error(c, GL_INVALID_ENUM);
+}
+
+void glTexSubImage2D(
+        GLenum target, GLint level, GLint xoffset,
+        GLint yoffset, GLsizei width, GLsizei height,
+        GLenum format, GLenum type, const GLvoid *pixels)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (xoffset<0 || yoffset<0 || width<0 || height<0 || level<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (validFormatType(c, format, type)) {
+        return;
+    }
+
+    // find out which texture is bound to the current unit
+    const int active = c->textures.active;
+    EGLTextureObject* tex = c->textures.tmu[active].texture;
+    const GGLSurface& surface(tex->mip(level));
+
+    if (!tex->internalformat || tex->direct) {
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+    if ((xoffset + width  > GLsizei(surface.width)) ||
+        (yoffset + height > GLsizei(surface.height))) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (!width || !height) {
+        return; // okay, but no-op.
+    }
+
+    // figure out the size we need as well as the stride
+    const int32_t formatIdx = convertGLPixelFormat(format, type);
+    if (formatIdx == 0) { // we don't know what to do with this
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+
+    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
+    const int32_t align = c->textures.unpackAlignment-1;
+    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
+    const size_t size = bpr * height;
+    const int32_t stride = bpr / pixelFormat.size;
+    GGLSurface userSurface;
+    userSurface.version = sizeof(userSurface);
+    userSurface.width  = width;
+    userSurface.height = height;
+    userSurface.stride = stride;
+    userSurface.format = formatIdx;
+    userSurface.compressedFormat = 0;
+    userSurface.data = (GLubyte*)pixels;
+
+    int err = copyPixels(c,
+            surface, xoffset, yoffset,
+            userSurface, 0, 0, width, height); 
+    if (err) {
+        ogles_error(c, err);
+        return;
+    }
+
+    generateMipmap(c, level);
+
+    // since we only changed the content of the texture, we don't need
+    // to call bindTexture on the main rasterizer.
+}
+
+// ----------------------------------------------------------------------------
+
+void glCopyTexImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLint x, GLint y, GLsizei width, GLsizei height,
+        GLint border)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (internalformat<GL_ALPHA || internalformat>GL_LUMINANCE_ALPHA) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (width<0 || height<0 || border!=0 || level<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    GLenum format = 0;
+    GLenum type = GL_UNSIGNED_BYTE;
+    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+    const int cbFormatIdx = cbSurface.format;
+    switch (cbFormatIdx) {
+    case GGL_PIXEL_FORMAT_RGB_565:
+        type = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case GGL_PIXEL_FORMAT_RGBA_5551:
+        type = GL_UNSIGNED_SHORT_5_5_5_1;
+        break;
+    case GGL_PIXEL_FORMAT_RGBA_4444:
+        type = GL_UNSIGNED_SHORT_4_4_4_4;
+        break;
+    }
+    switch (internalformat) {
+    case GL_ALPHA:
+    case GL_LUMINANCE_ALPHA:
+    case GL_LUMINANCE:
+        type = GL_UNSIGNED_BYTE;
+        break;    
+    }
+
+    // figure out the format to use for the new texture
+    switch (cbFormatIdx) {
+    case GGL_PIXEL_FORMAT_RGBA_8888:
+    case GGL_PIXEL_FORMAT_A_8:
+    case GGL_PIXEL_FORMAT_RGBA_5551:
+    case GGL_PIXEL_FORMAT_RGBA_4444:
+        format = internalformat;
+        break;    
+    case GGL_PIXEL_FORMAT_RGBX_8888:
+    case GGL_PIXEL_FORMAT_RGB_888:
+    case GGL_PIXEL_FORMAT_RGB_565:
+    case GGL_PIXEL_FORMAT_L_8:
+        switch (internalformat) {
+        case GL_LUMINANCE:
+        case GL_RGB:
+            format = internalformat;
+            break;    
+        }
+        break;
+    }
+
+    if (format == 0) {
+        // invalid combination
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    // create the new texture...
+    int32_t size;
+    GGLSurface* surface;
+    int error = createTextureSurface(c, &surface, &size,
+            level, format, type, width, height);
+    if (error) {
+        ogles_error(c, error);
+        return;
+    }
+    
+    // The bottom row is stored first in textures
+    GGLSurface txSurface(*surface);
+    txSurface.stride = -txSurface.stride;
+
+    // (x,y) is the lower-left corner of colorBuffer
+    y = cbSurface.height - (y + height);
+
+    int err = copyPixels(c,
+            txSurface, 0, 0,
+            cbSurface, x, y, cbSurface.width, cbSurface.height);  
+    if (err) {
+        ogles_error(c, err);
+    }
+
+    generateMipmap(c, level);
+}
+
+void glCopyTexSubImage2D(
+        GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (xoffset<0 || yoffset<0 || width<0 || height<0 || level<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (!width || !height) {
+        return; // okay, but no-op.
+    }
+
+    // find out which texture is bound to the current unit
+    const int active = c->textures.active;
+    EGLTextureObject* tex = c->textures.tmu[active].texture;
+    const GGLSurface& surface(tex->mip(level));
+
+    if (!tex->internalformat) {
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+    if ((xoffset + width  > GLsizei(surface.width)) ||
+        (yoffset + height > GLsizei(surface.height))) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    // The bottom row is stored first in textures
+    GGLSurface txSurface(surface);
+    txSurface.stride = -txSurface.stride;
+
+    // (x,y) is the lower-left corner of colorBuffer
+    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+    y = cbSurface.height - (y + height);
+
+    int err = copyPixels(c,
+            surface, xoffset, yoffset,
+            cbSurface, x, y, width, height);  
+    if (err) {
+        ogles_error(c, err);
+        return;
+    }
+
+    generateMipmap(c, level);
+}
+
+void glReadPixels(
+        GLint x, GLint y, GLsizei width, GLsizei height,
+        GLenum format, GLenum type, GLvoid *pixels)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if ((format != GL_RGBA) && (format != GL_RGB)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if ((type != GL_UNSIGNED_BYTE) && (type != GL_UNSIGNED_SHORT_5_6_5)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (width<0 || height<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (x<0 || x<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    int32_t formatIdx = GGL_PIXEL_FORMAT_NONE;
+    if ((format == GL_RGBA) && (type == GL_UNSIGNED_BYTE)) {
+        formatIdx = GGL_PIXEL_FORMAT_RGBA_8888;
+    } else if ((format == GL_RGB) && (type == GL_UNSIGNED_SHORT_5_6_5)) {
+        formatIdx = GGL_PIXEL_FORMAT_RGB_565;
+    } else {
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+
+    const GGLSurface& readSurface = c->rasterizer.state.buffers.read.s;
+    if ((x+width > GLint(readSurface.width)) ||
+            (y+height > GLint(readSurface.height))) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
+    const int32_t align = c->textures.packAlignment-1;
+    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
+    const int32_t stride = bpr / pixelFormat.size;
+
+    GGLSurface userSurface;
+    userSurface.version = sizeof(userSurface);
+    userSurface.width  = width;
+    userSurface.height = height;
+    userSurface.stride = -stride; // bottom row is transfered first
+    userSurface.format = formatIdx;
+    userSurface.compressedFormat = 0;
+    userSurface.data = (GLubyte*)pixels;
+
+    // use pixel-flinger to handle all the conversions
+    GGLContext* ggl = getRasterizer(c);
+    if (!ggl) {
+        // the only reason this would fail is because we ran out of memory
+        ogles_error(c, GL_OUT_OF_MEMORY);
+        return;
+    }
+
+    ggl->colorBuffer(ggl, &userSurface);  // destination is user buffer 
+    ggl->bindTexture(ggl, &readSurface);  // source is read-buffer
+    ggl->texCoord2i(ggl, x, readSurface.height - (y + height));
+    ggl->recti(ggl, 0, 0, width, height);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark DrawTexture Extension
+#endif
+
+void glDrawTexsvOES(const GLshort* coords) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexiOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
+}
+void glDrawTexivOES(const GLint* coords) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexiOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
+}
+void glDrawTexsOES(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexiOES(x, y, z, w, h, c);
+}
+void glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexiOES(x, y, z, w, h, c);
+}
+
+void glDrawTexfvOES(const GLfloat* coords) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexxOES(
+            gglFloatToFixed(coords[0]),
+            gglFloatToFixed(coords[1]),
+            gglFloatToFixed(coords[2]),
+            gglFloatToFixed(coords[3]),
+            gglFloatToFixed(coords[4]),
+            c);
+}
+void glDrawTexxvOES(const GLfixed* coords) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexxOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
+}
+void glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h){
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexxOES(
+            gglFloatToFixed(x), gglFloatToFixed(y), gglFloatToFixed(z),
+            gglFloatToFixed(w), gglFloatToFixed(h),
+            c);
+}
+void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexxOES(x, y, z, w, h, c);
+}
diff --git a/opengl/libagl/texture.h b/opengl/libagl/texture.h
new file mode 100644
index 0000000..5c57948
--- /dev/null
+++ b/opengl/libagl/texture.h
@@ -0,0 +1,45 @@
+/* libs/opengles/texture.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_TEXTURE_H
+#define ANDROID_OPENGLES_TEXTURE_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+#include "context.h"
+
+namespace android {
+
+void ogles_init_texture(ogles_context_t* c);
+void ogles_uninit_texture(ogles_context_t* c);
+void ogles_validate_texture_impl(ogles_context_t* c);
+
+inline void ogles_validate_texture(ogles_context_t* c) {
+    if (c->rasterizer.state.enables & GGL_ENABLE_TMUS)
+        ogles_validate_texture_impl(c);
+}
+
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_TEXTURE_H
diff --git a/opengl/libagl/vertex.cpp b/opengl/libagl/vertex.cpp
new file mode 100644
index 0000000..5bcc9dc
--- /dev/null
+++ b/opengl/libagl/vertex.cpp
@@ -0,0 +1,247 @@
+/* libs/opengles/vertex.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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 <stdlib.h>
+#include "context.h"
+#include "fp.h"
+#include "vertex.h"
+#include "state.h"
+#include "matrix.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+void ogles_init_vertex(ogles_context_t* c)
+{
+    c->cull.enable = GL_FALSE;
+    c->cull.cullFace = GL_BACK;
+    c->cull.frontFace = GL_CCW;
+
+    c->current.color.r = 0x10000;
+    c->current.color.g = 0x10000;
+    c->current.color.b = 0x10000;
+    c->current.color.a = 0x10000;
+
+    c->currentNormal.z = 0x10000;
+}
+
+void ogles_uninit_vertex(ogles_context_t* c)
+{
+}
+
+// ----------------------------------------------------------------------------
+// vertex processing
+// ----------------------------------------------------------------------------
+
+// Divides a vertex clip coordinates by W
+static inline
+void perspective(ogles_context_t* c, vertex_t* v, uint32_t enables)
+{
+    // [x,y,z]window = vpt * ([x,y,z]clip / clip.w)
+    // [w]window = 1/w
+
+    // With a regular projection generated by glFrustum(),
+    // we have w=-z, therefore, w is in [zNear, zFar].
+    // Also, zNear and zFar are stricly positive,
+    // and 1/w (window.w) is in [1/zFar, 1/zNear], usually this
+    // means ]0, +inf[ -- however, it is always recommended
+    // to use as large values as possible for zNear.
+    // All in all, w is usually smaller than 1.0 (assuming
+    // zNear is at least 1.0); and even if zNear is smaller than 1.0
+    // values of w won't be too big.
+
+    const int32_t rw = gglRecip28(v->clip.w);
+    const GLfixed* const m = c->transforms.vpt.transform.matrix.m;
+    v->window.w = rw;
+    v->window.x = gglMulAddx(gglMulx(v->clip.x, rw, 16), m[ 0], m[12], 28); 
+    v->window.y = gglMulAddx(gglMulx(v->clip.y, rw, 16), m[ 5], m[13], 28);
+    v->window.x = TRI_FROM_FIXED(v->window.x);
+    v->window.y = TRI_FROM_FIXED(v->window.y);
+    if (enables & GGL_ENABLE_DEPTH_TEST) {
+        v->window.z = gglMulAddx(gglMulx(v->clip.z, rw, 16), m[10], m[14], 28);
+    }
+}
+
+// frustum clipping and W-divide
+static inline
+void clipFrustumPerspective(ogles_context_t* c, vertex_t* v, uint32_t enables)
+{
+    // ndc = clip / W
+    // window = ncd * viewport
+    
+    // clip to the view-volume
+    uint32_t clip = v->flags & vertex_t::CLIP_ALL;
+    const GLfixed w = v->clip.w;
+    if (v->clip.x < -w)   clip |= vertex_t::CLIP_L;
+    if (v->clip.x >  w)   clip |= vertex_t::CLIP_R;
+    if (v->clip.y < -w)   clip |= vertex_t::CLIP_B;
+    if (v->clip.y >  w)   clip |= vertex_t::CLIP_T;
+    if (v->clip.z < -w)   clip |= vertex_t::CLIP_N;
+    if (v->clip.z >  w)   clip |= vertex_t::CLIP_F;
+
+    v->flags |= clip;
+    c->arrays.cull &= clip;
+
+    if (ggl_likely(!clip)) {
+        // if the vertice is clipped, we don't do the perspective
+        // divide, since we don't need its window coordinates.
+        perspective(c, v, enables);
+    }
+}
+
+// frustum clipping, user clipping and W-divide
+static inline
+void clipAllPerspective(ogles_context_t* c, vertex_t* v, uint32_t enables)
+{
+    // compute eye coordinates
+    c->arrays.mv_transform(
+            &c->transforms.modelview.transform, &v->eye, &v->obj);
+    v->flags |= vertex_t::EYE;
+
+    // clip this vertex against each user clip plane
+    uint32_t clip = 0;
+    int planes = c->clipPlanes.enable;
+    while (planes) {
+        const int i = 31 - gglClz(planes);
+        planes &= ~(1<<i);
+        // XXX: we should have a special dot() for 2,3,4 coords vertices
+        GLfixed d = dot4(c->clipPlanes.plane[i].equation.v, v->eye.v);
+        if (d < 0) {
+            clip |= 0x100<<i;
+        }
+    }
+    v->flags |= clip;
+
+    clipFrustumPerspective(c, v, enables);
+}
+
+// ----------------------------------------------------------------------------
+
+void ogles_vertex_project(ogles_context_t* c, vertex_t* v) {
+    perspective(c, v, c->rasterizer.state.enables);
+}
+
+void ogles_vertex_perspective2D(ogles_context_t* c, vertex_t* v)
+{
+    // here we assume w=1.0 and the viewport transformation
+    // has been applied already.
+    c->arrays.cull = 0;
+    v->window.x = TRI_FROM_FIXED(v->clip.x);
+    v->window.y = TRI_FROM_FIXED(v->clip.y);
+    v->window.z = v->clip.z;
+    v->window.w = v->clip.w << 12;
+}
+
+void ogles_vertex_perspective3DZ(ogles_context_t* c, vertex_t* v) {
+    clipFrustumPerspective(c, v, GGL_ENABLE_DEPTH_TEST);
+}
+void ogles_vertex_perspective3D(ogles_context_t* c, vertex_t* v) {
+    clipFrustumPerspective(c, v, 0);
+}
+void ogles_vertex_clipAllPerspective3DZ(ogles_context_t* c, vertex_t* v) {
+    clipAllPerspective(c, v, GGL_ENABLE_DEPTH_TEST);
+}
+void ogles_vertex_clipAllPerspective3D(ogles_context_t* c, vertex_t* v) {
+    clipAllPerspective(c, v, 0);
+}
+
+static void clipPlanex(GLenum plane, const GLfixed* equ, ogles_context_t* c)
+{
+    const int p = plane - GL_CLIP_PLANE0;
+    if (ggl_unlikely(uint32_t(p) > (GL_CLIP_PLANE5 - GL_CLIP_PLANE0))) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    vec4_t& equation = c->clipPlanes.plane[p].equation;
+    memcpy(equation.v, equ, sizeof(vec4_t));
+
+    ogles_validate_transform(c, transform_state_t::MVIT);
+    transform_t& mvit = c->transforms.mvit4;
+    mvit.point4(&mvit, &equation, &equation);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+
+void glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->current.color.r       = gglFloatToFixed(r);
+    c->currentColorClamped.r = gglClampx(c->current.color.r);
+    c->current.color.g       = gglFloatToFixed(g);
+    c->currentColorClamped.g = gglClampx(c->current.color.g);
+    c->current.color.b       = gglFloatToFixed(b);
+    c->currentColorClamped.b = gglClampx(c->current.color.b);
+    c->current.color.a       = gglFloatToFixed(a);
+    c->currentColorClamped.a = gglClampx(c->current.color.a);
+}
+
+void glColor4x(GLfixed r, GLfixed g, GLfixed b, GLfixed a)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->current.color.r = r;
+    c->current.color.g = g;
+    c->current.color.b = b;
+    c->current.color.a = a;
+    c->currentColorClamped.r = gglClampx(r);
+    c->currentColorClamped.g = gglClampx(g);
+    c->currentColorClamped.b = gglClampx(b);
+    c->currentColorClamped.a = gglClampx(a);
+}
+
+void glNormal3f(GLfloat x, GLfloat y, GLfloat z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->currentNormal.x = gglFloatToFixed(x);
+    c->currentNormal.y = gglFloatToFixed(y);
+    c->currentNormal.z = gglFloatToFixed(z);
+}
+
+void glNormal3x(GLfixed x, GLfixed y, GLfixed z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->currentNormal.x = x;
+    c->currentNormal.y = y;
+    c->currentNormal.z = z;
+}
+
+// ----------------------------------------------------------------------------
+
+void glClipPlanef(GLenum plane, const GLfloat* equ)
+{
+    const GLfixed equx[4] = {
+            gglFloatToFixed(equ[0]),
+            gglFloatToFixed(equ[1]),
+            gglFloatToFixed(equ[2]),
+            gglFloatToFixed(equ[3])
+    };
+    ogles_context_t* c = ogles_context_t::get();
+    clipPlanex(plane, equx, c);
+}
+
+void glClipPlanex(GLenum plane, const GLfixed* equ)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    clipPlanex(plane, equ, c);
+}
diff --git a/opengl/libagl/vertex.h b/opengl/libagl/vertex.h
new file mode 100644
index 0000000..55e6213
--- /dev/null
+++ b/opengl/libagl/vertex.h
@@ -0,0 +1,48 @@
+/* libs/opengles/vertex.h
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT 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_VERTEX_H
+#define ANDROID_OPENGLES_VERTEX_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+namespace android {
+
+namespace gl {
+struct vertex_t;
+struct ogles_context_t;
+};
+
+void ogles_init_vertex(ogles_context_t* c);
+void ogles_uninit_vertex(ogles_context_t* c);
+
+void ogles_vertex_perspective2D(ogles_context_t*, vertex_t*);
+
+void ogles_vertex_perspective3D(ogles_context_t*, vertex_t*);
+void ogles_vertex_perspective3DZ(ogles_context_t*, vertex_t*);
+void ogles_vertex_clipAllPerspective3D(ogles_context_t*, vertex_t*);
+void ogles_vertex_clipAllPerspective3DZ(ogles_context_t*, vertex_t*);
+
+
+void ogles_vertex_project(ogles_context_t* c, vertex_t*);
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_VERTEX_H
+
diff --git a/services/Android.mk b/services/Android.mk
new file mode 100644
index 0000000..5e912d6
--- /dev/null
+++ b/services/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH:= $(call my-dir)
+
+# the library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+            $(call all-subdir-java-files)
+
+LOCAL_MODULE:= services
+
+LOCAL_JAVA_LIBRARIES := android.policy
+
+include $(BUILD_JAVA_LIBRARY)
+
+include $(BUILD_DROIDDOC)
+
